← All articles

LLM API Content Moderation and Safety Filters: Cross-Provider Comparison of Refusal Behavior, Moderation APIs, and Content Policies

We compared content moderation approaches across OpenAI, Anthropic, DeepSeek, DashScope, and Kimi — covering moderation API endpoints, refusal response formats, content policy categories, and what operators need to know when routing requests across providers with different safety policies.

· TheRouter

Every LLM API provider moderates content differently. OpenAI gives you a free moderation endpoint with per-category scores. Anthropic trains constitutional classifiers into its models and handles refusals inline. DeepSeek and Kimi apply server-side filters shaped by Chinese regulatory requirements. DashScope layers an optional Guardrails service on top of its built-in policy enforcement.

If you route requests across multiple providers, you will eventually hit a case where Provider A accepts a prompt that Provider B refuses. This reference maps each provider's moderation approach so you can build routing logic that handles these asymmetries without surprising your users.

OpenAI-compatible means a provider exposes a chat-completions endpoint whose request and response shape matches the OpenAI API contract closely enough that an unmodified OpenAI SDK call works against it after swapping three values: API key, base URL, and model name. The minimum surface in practice is POST /v1/chat/completions with messages, model, and an OpenAI-shaped streaming response.

TL;DR Comparison Table

ProviderDedicated Moderation APIInline ModerationRefusal FormatContent CategoriesConfigurable Filters
OpenAIYes — omni-moderation-latest (free)Yes — moderation param in Responses APIHTTP 200 + refusal text in responsehate, harassment, self-harm, sexual, violence (+ subcategories)No (model-level)
AnthropicNoYes — constitutional classifiersHTTP 200 + stop_reason: "end_turn" with polite refusalCBRN, weapons, child safety, election interference, fraudNo (model-level, classifier-level)
DeepSeekNoYes — server-side filtersHTTP 400 or refusal text in response bodyChina-regulated categories + general safetyNo
DashScopeNo (separate Guardrails product)Yes — built-in policy + optional GuardrailsHTTP 400 DataInspectionFailed (Guardrails); refusal text (built-in)China-regulated categories, customizable tags via GuardrailsPartially (Guardrails tag management)
KimiNoYes — server-side filtersRefusal text in response bodyChina-regulated categories + general safetyNo

OpenAI: Moderation Endpoint + Inline Scoring

OpenAI is unique among major providers in offering a standalone, free moderation endpoint. The omni-moderation-latest model accepts both text and image inputs (up to 20 MB per image) and returns per-category flags and confidence scores without generating a completion.

Standalone Moderation

from openai import OpenAI

client = OpenAI()

result = client.moderations.create(
    model="omni-moderation-latest",
    input="text to classify"
)

print(result.results[0].flagged)        # True/False
print(result.results[0].categories)     # per-category booleans
print(result.results[0].category_scores) # per-category 0.0–1.0

The endpoint is free and does not count toward your usage quota. Categories include hate, harassment, self-harm, sexual, violence, and subcategories like hate/threatening, self-harm/instructions, sexual/minors, and violence/graphic.

Inline Moderation with Responses API

Since mid-2026, OpenAI also supports inline moderation by passing a moderation parameter in Responses API calls:

response = client.responses.create(
    model="gpt-5.6",
    input=[{"role": "user", "content": "..."}],
    moderation={"model": "omni-moderation-latest"}
)

# Check input and output moderation
input_mod = response.moderation.input   # flagged, categories, scores
output_mod = response.moderation.output  # flagged, categories, scores

This returns moderation scores for both the input and the generated output in a single API call. The model still generates normally — treat the moderation signals as input to your application's content policy, not as an automatic block.

Key detail for operators: Inline moderation scores arrive after the full response is generated. If you stream a response, moderation results are not included with partial deltas. A response that discusses harmful content in a safety-aware way (e.g., a refusal explaining why something is dangerous) can still trigger a moderation flag. Source: OpenAI Moderation docs, retrieved 2026-08-10

Anthropic: Constitutional Classifiers

Anthropic does not offer a standalone moderation endpoint. Instead, Claude models are trained with Constitutional AI principles and defended by constitutional classifiers — input and output classifiers that filter requests at inference time.

How Refusals Work

When Claude determines a request violates its content policy, it returns a normal HTTP 200 response with stop_reason: "end_turn" containing a polite refusal. There is no special error code or HTTP status for content moderation refusals — the refusal is indistinguishable from a normal completion at the HTTP level.

{
  "content": [
    {
      "type": "text",
      "text": "I can't help with that request. Creating instructions for weapons could cause serious harm..."
    }
  ],
  "stop_reason": "end_turn"
}

Constitutional Classifiers

Anthropic published research on constitutional classifiers in early 2025. These are separate AI systems trained on synthetically generated data that guard models against jailbreaks. Key findings from their bug bounty program:

  • 183 participants spent over 3,000 hours attempting to find universal jailbreaks
  • No universal jailbreak was discovered during the two-month test period
  • Updated classifiers achieved robustness with only a 0.38% increase in refusal rates over baseline

With the release of Claude Fable 5 and Mythos 5 in mid-2026, Anthropic introduced a new generation of classifiers that detect potential misuse including jailbreak attempts. Source: Anthropic Constitutional Classifiers research, retrieved 2026-08-10

Content Policy Categories

Anthropic's Acceptable Use Policy covers:

  • CBRN (chemical, biological, radiological, nuclear) threats
  • Weapons and explosives
  • Child sexual abuse material (CSAM)
  • Election interference and political manipulation
  • Fraud and deception
  • Malware and cyberattacks

Unlike OpenAI, Anthropic does not expose per-category scores. You cannot programmatically determine why Claude refused a request — only that it did.

DeepSeek: Server-Side Filtering

DeepSeek applies content filtering server-side on all API requests. As a Chinese AI company, DeepSeek's content moderation is shaped by China's content regulation framework, which mandates filtering across categories including political sensitivity, violence, and other locally regulated topics.

Refusal Behavior

DeepSeek's refusal responses vary. The API may return:

  • A normal HTTP 200 response with refusal text like "Sorry, that's beyond my current scope. Let's chat about something else?"
  • An HTTP 400 error for content that triggers hard policy violations
{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "Sorry, that's beyond my current scope. Let's chat about something else?"
      },
      "finish_reason": "stop"
    }
  ]
}

What Operators Should Know

  • DeepSeek does not expose a moderation API or per-category scores
  • Content filtering is not configurable through the API
  • Refusals are indistinguishable from normal completions at the HTTP level (when soft refusals are returned)
  • The filtering scope reflects Chinese regulatory requirements, which differ materially from Western provider policies
  • Self-hosted DeepSeek open-weight models (V4, V4-0324) do not include these API-level filters — filtering applies only to the hosted API

Source: DeepSeek API docs, retrieved 2026-08-10

DashScope (Alibaba Cloud): Built-in Policy + Guardrails Service

DashScope (Alibaba Cloud Model Studio) operates a two-layer moderation system. A built-in content policy enforces baseline compliance on all Qwen model API calls. On top of this, operators can optionally enable the Guardrails service for more granular control.

Built-in Content Policy

All DashScope API calls pass through baseline content moderation aligned with Chinese regulatory requirements. When the built-in filter triggers, the model may return a refusal in the response body with finish_reason: "stop".

Guardrails Service (Optional)

The Guardrails service provides additional moderation with configurable tags. To enable it, pass the X-DashScope-DataInspection header:

from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {"role": "user", "content": "..."}
    ],
    extra_headers={
        "X-DashScope-DataInspection": '{"input":"cip","output":"cip"}'
    }
)

When Guardrails triggers, DashScope returns an HTTP 400 with error code DataInspectionFailed (OpenAI-compatible mode) or data_inspection_failed:

{
  "error": {
    "code": "data_inspection_failed",
    "message": "Output data may contain inappropriate content.",
    "type": "data_inspection_failed"
  }
}

Configurable Tag Management

Unlike other providers, DashScope's Guardrails lets operators enable or disable specific moderation tags based on their application requirements. Custom security policy configurations are available for enterprise users. This makes DashScope the most configurable Chinese provider for content moderation, though core policy compliance remains mandatory.

Source: Alibaba Cloud Guardrails service docs, retrieved 2026-08-10

Kimi (Moonshot AI): Inline Safety Filters

Kimi's API applies server-side content filtering on all requests, consistent with Chinese regulatory requirements. Like DeepSeek, Kimi does not expose a moderation API or per-category scores.

Refusal Behavior

Kimi K3 returns refusal messages inline in the response body. The API documentation states that the model "will reject any questions involving terrorism, racial discrimination, pornography, incitement to violence, etc."

Refusals arrive as normal HTTP 200 responses with the refusal text as the assistant's message:

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "I'm sorry, but I can't assist with that request..."
      },
      "finish_reason": "stop"
    }
  ]
}

What Operators Should Know

  • No dedicated moderation endpoint
  • Content filtering is not configurable via the API
  • Refusal behavior is inline (HTTP 200 + refusal text), not error-level
  • When Kimi K3 weights are released, self-hosted deployments will not include API-level filtering

Source: Kimi Platform docs, retrieved 2026-08-10

Impact on Multi-Provider Routing

When you route requests across providers with different content policies, three practical problems arise:

1. Detecting Moderation Refusals

The fundamental challenge is that most providers return refusals as normal HTTP 200 responses. Only DashScope with Guardrails enabled returns a distinct HTTP 400 error code. For OpenAI, Anthropic, DeepSeek, and Kimi, you need to parse the response text to determine whether the model actually answered or politely refused.

Approaches we have seen operators use:

  • Keyword matching — checking for phrases like "I can't help with that," "beyond my current scope," or "I'm unable to"
  • OpenAI inline moderation — using the moderation parameter to get machine-readable flags alongside the generation
  • Response length heuristics — moderation refusals tend to be short (under 200 tokens) relative to genuine answers

2. Asymmetric Refusal Handling

A prompt that passes OpenAI's moderation may be refused by a Chinese provider, and vice versa. The policy spaces overlap but do not align:

ScenarioOpenAIAnthropicChinese Providers
Political content (Western perspective)Generally allowedGenerally allowedMay be filtered
Political content (Chinese sensitivity)Generally allowedGenerally allowedFiltered
Weapons/explosivesModeratedRefusedRefused
CBRN contentModeratedRefusedRefused
Adult contentModeratedRefusedRefused
Historical/educational violenceUsually allowedUsually allowedMay be filtered

3. Fallback Strategy

When a primary provider refuses a request, your routing layer needs a policy decision:

  • Retry on fallback provider — useful when the refusal is provider-specific (e.g., political sensitivity on Chinese providers). Risk of policy arbitrage if not logged.
  • Surface the refusal — pass the moderation refusal back to the user. Safer from a compliance perspective.
  • Log and alert — record moderation events for audit trails regardless of whether you retry.

TheRouter supports provider fallback routing that can be configured to handle different error types. When a provider returns an error, the routing layer can fall back to an alternate provider. For content moderation refusals that arrive as HTTP 200, operators need application-level logic to detect refusals before the routing layer can act.

Decision Matrix: Choosing a Moderation Approach

Your NeedRecommended Approach
Pre-screen user inputs before generationOpenAI moderation endpoint (free, standalone)
Get moderation signals with every generationOpenAI inline moderation (moderation parameter)
Maximum control over moderation categoriesDashScope Guardrails (configurable tags)
Audit trail of all moderation eventsOpenAI moderation endpoint + application logging
Route around provider-specific refusalsApplication-level refusal detection + fallback routing
Self-hosted model without content filtersDeepSeek or Kimi open-weight models

FAQ

How do I programmatically detect a content moderation refusal?

OpenAI's inline moderation returns machine-readable flagged booleans and per-category scores. For all other providers, you need to parse the response text. Check for common refusal patterns, unusually short responses, or use a lightweight classifier on the output. DashScope with Guardrails is the exception — it returns a distinct HTTP 400 error code.

Can I use OpenAI's moderation endpoint with other providers' outputs?

Yes. The moderation endpoint accepts any text input regardless of which model generated it. Some operators run all LLM outputs through OpenAI's moderation endpoint as a second-pass safety check, regardless of the originating provider. The endpoint is free and does not require a generation API key — any OpenAI API key works.

Why does the same prompt get different moderation results across providers?

Each provider maintains independent content policies, trains different safety classifiers, and operates under different regulatory frameworks. Chinese providers (DeepSeek, DashScope, Kimi) must comply with Chinese content regulations, which cover categories that Western providers do not filter. Western providers (OpenAI, Anthropic) have their own policy categories that may not align with Chinese requirements.

What happens to content moderation in streaming responses?

OpenAI's inline moderation scores arrive after the full response is generated — they are not included with partial streaming deltas. If a response triggers a moderation flag mid-stream, your application will have already started sending tokens to the user. For providers that return inline refusals (Anthropic, DeepSeek, Kimi), the refusal text streams normally as part of the response.

Does TheRouter handle content moderation refusals in its routing?

TheRouter routes OpenAI-compatible requests through configured providers and supports fallback routing when a provider returns an error. For hard errors like DashScope's HTTP 400 DataInspectionFailed, the routing layer can trigger a fallback. For soft refusals (HTTP 200 with refusal text), detection and routing decisions happen at the application layer, since the response is technically successful from the HTTP perspective.

Are there regional differences in content moderation strictness?

Yes. Chinese providers operate under mandatory content regulation that covers political sensitivity, historical events, and other categories that Western providers generally do not filter. DashScope's international endpoint (dashscope-intl.aliyuncs.com) applies the same core content policies as the domestic endpoint. When routing between Chinese and Western providers, operators should test their specific use cases against both policy sets.

Further Reading

Help & contact