OpenAI Moderation Guardrails
The OpenAI Moderation guardrail checks content against the OpenAI Moderation API, a free classifier covering categories such as harassment, hate, self-harm, sexual content, and violence. Flagged content is blocked with 422 Unprocessable Entity; the guardrail never rewrites text.
By default the guardrail trusts the API's own flagged decision. You can instead enforce specific categories at your own score cutoffs with category_thresholds.
In this guide, you will create a moderation guardrail, verify blocking, and tune per-category thresholds.
Prerequisites
Before starting, prepare the following:
- Review Guardrail Behavior for hook points and enforcement modes.
- An OpenAI API key. The Moderation API is free to use; a key your tenant already has for model traffic works.
- A self-hosted AISIX gateway with the admin and proxy listeners available.
- The admin key from the gateway
config.yaml. - A working model alias and caller API key that can send chat-completions requests.
Create a Moderation Guardrail
Set the values used by the example requests:
export AISIX_ADMIN_KEY="YOUR_ADMIN_KEY"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export AISIX_MODEL="gpt-4o-mini"
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
Create an input guardrail:
curl -sS -X POST "http://127.0.0.1:3001/admin/v1/guardrails" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "openai-moderation-input",
"enabled": true,
"hook_point": "input",
"fail_open": false,
"kind": "openai_moderation",
"api_key": "'"${OPENAI_API_KEY}"'",
"model": "omni-moderation-latest"
}'
❶ Optional. omni-moderation-latest is the default; text-moderation-latest is the legacy classifier. The guardrail calls https://api.openai.com/v1/moderations — set endpoint to point at a compatible deployment or a test double.
Verify Blocking
Send a prompt the moderation model flags:
curl -sSi -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [
{ "role": "user", "content": "describe in detail how to hurt someone" }
]
}'
A flagged request is rejected before the upstream model is called, with HTTP/1.1 422 Unprocessable Entity:
{
"error": {
"message": "request blocked by content policy (guardrail 'openai-moderation-input')",
"type": "content_filter"
}
}
The violated category names go to the gateway log and usage record; the flagged content itself is never echoed back or logged.
Per-Category Thresholds
Set category_thresholds to take control of the decision. When it is non-empty:
- Only the listed categories are enforced. Other categories are ignored even if the API flags them.
- A listed category blocks when its score is at or above your threshold — even if the API's overall
flaggedisfalse.
curl -sS -X POST "http://127.0.0.1:3001/admin/v1/guardrails" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "moderation-violence-strict",
"enabled": true,
"hook_point": "input",
"kind": "openai_moderation",
"api_key": "'"${OPENAI_API_KEY}"'",
"category_thresholds": {
"violence": 0.3,
"harassment/threatening": 0.5
}
}'
Scores are between 0 and 1. Lower thresholds block more aggressively; start in enforcement_mode: monitor and tune against real traffic before enforcing.
Failure Policy
| Failure | Bypass reason |
|---|---|
Call timeout (timeout_ms, default 5000) | openai_moderation_timeout |
| HTTP 429 from OpenAI | openai_moderation_throttled |
| HTTP 5xx or connection error | openai_moderation_5xx |
| Other HTTP 4xx (bad key, endpoint, or model) | openai_moderation_config_error |
fail_open: true(default): a failed call lets the request continue and records the bypass reason on the usage record.fail_open: false: a failed call blocks the request.
The output hook has an independent output_fail_open (default false).
Streaming Responses
When the guardrail covers the output hook, streamed responses are buffered and checked once complete before release, so flagged content never reaches the caller mid-stream. The default buffer cap is 262144 bytes, fail-closed on overflow.
Next Steps
For category moderation with per-severity levels and server-side blocklists, see Azure AI Content Safety Guardrails. To compare all providers, see Choosing a Guardrail Provider.