Skip to main content
The OpenAI Moderation policy sends text to OpenAI’s Moderations API and records a score for every category the model returns. It either blocks the call or lets it through: the Moderations API returns scores, not rewritten text, so there is nothing for this policy to put back. Applies to LLM traffic only. Text only.
A policy created from the console today detects and never blocks. Blocking needs Block On Flagged or at least one per-category Threshold, and the form draws neither — there is no field for either one anywhere on it. Until there is, a policy you create here is a scoring instrument: useful, and not a guardrail. See Making it block for what has to happen instead, and who has to do it.
This policy puts a synchronous call to OpenAI in front of every inspected leg. What that costs depends on your region and the size of the conversation, so measure it in your own environment rather than assuming.

Before you configure: the OpenAI key

This policy calls OpenAI with a credential of your own, so you need a key before it can do anything. That is the whole prerequisite — there is no resource to create, no template to build and no permission to grant, which is what makes this the quickest of the guardrails to stand up. Two things worth knowing before you pick a key. The Moderations API is billed separately from your model usage, and this policy calls it on every inspected leg in its scope. And the key is stored on the policy as you typed it, so give it a key scoped to moderation rather than one that can also spend on completions.

Configure the policy

Open PoliciesLibraryOpenAI Moderation. The form has two fields.
The key is stored as provided and is shown again whenever the policy is reopened. Policy settings are not encrypted at rest and are not redacted on read. Use a key scoped to moderation, and rotate it on your normal schedule.

Mode and scope

Start in Observe and read the recorded scores before you choose thresholds. That is not ceremony here — you cannot pick a sensible threshold for your traffic without seeing what your traffic actually scores. A policy created from the console inspects the request leg only. The form offers no choice about it and writes that leg for you. The gateway can also inspect the model’s answer — a second call to OpenAI on every turn — but that is another of the things this form cannot turn on.

Making it block

Four settings decide whether this policy ever refuses anything, and the form draws none of them. You will not find them under Advanced, behind a toggle, or anywhere else on the panel: there is nothing to look for. They are not out of reach altogether — they can be set on the policy outside the console, which is a job for whoever manages your gateway. Once one of them is set it stays set: the form preserves what it does not show, so your own edits here will not wipe it. The category names have to be exactly the ones OpenAI uses. The reliable way to learn them is to run in Observe and read the per-category scores off the recorded events — every category OpenAI scored is named there. A fifth setting the form does not draw chooses which legs are inspected — the request on its way to the model, the model’s answer coming back, or both. It does not affect whether a violation blocks, only where one can be found.
A threshold of 0 blocks everything in that category. The comparison is at or above, and every score is at or above zero. A category with a 0 threshold refuses every request that reaches this policy, whatever the content. It is the most common way to take an application offline with this policy.
Categories is an allow-list that also switches off thresholds. A category outside the list is not evaluated at all, so a threshold you set for it is never consulted and nothing reports that it was ignored. If you list categories, list every category you have a threshold for.

How the decision is made

1

The text is flattened and sent in one call

On the request leg, the system prompt and the content of every message are joined with newlines into a single string. On the response leg, the assistant’s content alone. One call, one string.
2

Scores are aggregated across the returned results

The highest score per category wins, and a category flagged in any result counts as flagged.
3

Each evaluated category is checked

A category with a threshold is a violation when its score is at or above it. A category without a threshold is a violation only when Block On Flagged is on and OpenAI flagged it. With neither, there are no violations and nothing is ever blocked.
4

A violation in Enforce refuses the call

The caller gets 403, and the response lists every category that crossed, with the score OpenAI returned and the threshold it crossed. The wording is the Message setting, or a default saying the request was blocked by content policy. A category blocked by Block On Flagged rather than by a threshold of yours is listed with no threshold beside it.

Modes and failures

On failure in Enforce the caller gets 502, and a response saying only that content moderation is temporarily unavailable.
In Enforce this policy fails closed, and there is no setting to change that. Every failure class collapses into that one response: a revoked key, an OpenAI rate limit, a malformed request and an outage are indistinguishable from the caller’s side and from the policy’s event. When it starts refusing everything, the gateway cannot tell you which of those it is — check the key and OpenAI’s status page yourself.

Limits

  • It cannot mask. There is no anonymise action; the call is blocked or it is not. For redaction use TrustGuard or Regex Replace.
  • Streaming responses are not inspected. They pass through untouched, and nothing is recorded. Enforce on the request leg.
  • Text only, and structure is lost. Roles, tool calls, tool definitions and attachments are not sent — the request leg becomes one newline-joined blob. A detector that would care which participant said something cannot.
  • Your own system prompt is scored. It is the first thing in that blob, and a security-related system prompt can score high enough to matter. Check it in Observe before enforcing.
  • LLM traffic only. The policy does not apply to MCP (Model Context Protocol) tool calls.
  • The console cannot select the response leg. A policy created there inspects requests, and inspecting the answer is set outside the console, like the blocking settings.
  • Settings are stored and returned in plain text, including the API key.

Verify the policy

Open the Playground, pick an application the policy applies to, and work through these in order. Steps 2 and 3 are one loop: observe, then enforce.
1

Control — the path works at all

Expect a normal reply and the decision allowed. If this fails, the problem is the application, the model or the key — not the thresholds. Fix it before going on.
2

Observe — learn what your traffic scores

Leave the policy in Observe and send real prompts, including ones you expect to be borderline. Read the per-category scores on each event.You are looking for two numbers: how high your acceptable traffic scores, and how high the traffic you want refused scores. A threshold between them is the only one worth setting. Take the category names from these events too.
3

Enforce — confirm a violation is refused

This step needs a threshold, or Block On Flagged, already set on the policy — neither of which you can do from the form, so hand your numbers from step two to whoever manages your gateway first. Once one of them is in place, switch to Enforce and resend the prompt that scored above it.Expect the decision block, a 403 naming the category and the score, and no time at the provider in the timing breakdown. That the provider leg is empty is the evidence that matters: the request never reached the model.If the same prompt is allowed, the policy has no threshold and no Block On Flagged — see the warning at the top of this page.
Every decision is emitted as a metadata event, in Observe mode too. See the event schema for the fields recorded.

Troubleshooting