Last reviewed: October 30, 2026 (UTC).

Direct answer

Treat moderation and model safety handling as part of one logical request budget. Before dispatch, decide whether the workload needs an input check, an output check, or both; set the maximum number of safety and generation attempts; cap the text, image, output, and fallback work admitted to each attempt; and reserve the highest approved exposure. After every response, reconcile usage and the safety outcome before any retry. A blocked or refused request is an accounted attempt, not evidence that the next attempt is free.

The provider contracts differ, so the gateway must preserve their distinctions. OpenAI says its omni-moderation-latest model accepts text and image inputs, does not classify audio, and that the OpenAI moderation endpoint is free to use. It also supports returning moderation scores alongside a generated response. That describes OpenAI’s own surface; it does not establish that a third-party gateway route, model call, or extra retry carries no charge. Google Gemini exposes per-category safety_settings with a threshold, and reports a safety block as an error, including an error event while streaming. Anthropic’s Claude documentation says a streamed refusal ends with stop_reason: "refusal", usage metrics are still provided, and the conversation context must be reset before continuing.

Use the current CometAPI cost-estimation guide to build a route-specific reservation from the model-directory price and the endpoint’s billable units. Include the output limit and every allowed attempt in the estimate. Keep estimated exposure, settled usage, and unresolved usage in separate fields. This prevents a safety fallback from disappearing into an ordinary success-rate metric.

A simple request allowance can be expressed as:

request_exposure = settled_attempt_cost + unresolved_reservations
next_attempt_cost = safety_check_cost + generation_cost + approved_fallback_reserve
admit only if request_exposure + next_attempt_cost <= logical_request_budget

The values are policy inputs, not universal provider prices. If a route does not expose a credible billing unit or usage record, mark the exposure unresolved and stop widening traffic until the owner resolves it.

Who this is for

This guide is for platform engineers maintaining a shared AI gateway, FinOps owners reviewing token and task budgets, and product teams that must moderate user input or generated output before showing it or triggering a downstream action. It is useful for chat, image, document, and agent workloads where a blocked result can otherwise trigger a second model, a rewritten prompt, or an entire fallback chain.

The workflow assumes that the application can assign a stable logical-request ID and retain an attempt record. It does not assume that providers use the same safety categories, moderation endpoint, price unit, or refusal behavior. Those details belong in a versioned route contract.

Key takeaways

  • Count pre-checks, generation, output checks, and fallbacks under one logical request ID.
  • Separate a provider’s free or bundled moderation surface from gateway charges and model-attempt costs.
  • Treat blocked, refused, timed-out, and missing-usage outcomes as distinct accounting states.
  • Never retry a blocked payload unchanged; classify the result and apply a bounded, approved recovery path.
  • Reset conversation context when the provider requires it, and never let a retry inherit an unsafe or invalid turn by accident.
  • Reserve the next attempt before dispatch and release or reconcile that reservation only when usage evidence is available.
  • Measure cost per accepted result, not only cost per HTTP response.

For adjacent request overhead controls, see Control CometAPI Tool-Schema Tokens Before Input Costs Inflate . For preflight counting context, see Count CometAPI Tokens Before You Approve a Budget .

Sources checked

Four primary public references were fetched on October 30, 2026 UTC:

  • OpenAI Moderation documents the text-and-image omni-moderation-latest model, the free OpenAI moderation endpoint, its 20 MB image limit, and inline moderation results for generated responses.
  • Google Gemini safety settings documents per-category thresholds, safety-blocked errors, streaming error events, and built-in protections.
  • Claude: Handle streaming refusals documents refusal stop reasons, stop_details, usage on refusals, context reset requirements, and fallback options.
  • CometAPI: Estimate request cost before calling a model documents pre-call calculations from current model pricing and endpoint units, output caps, task multipliers, and post-call reconciliation.

These sources support provider behavior and the accounting method. They do not establish one price for every CometAPI route, one universal safety threshold, or a guaranteed cost reduction from adding moderation. Read the exact route and account pricing evidence before approving a production ceiling.

Contract details to verify

1. Define the logical request

Create the logical-request record before the first network call. Include request_id, workload class, route, resolved model, safety policy version, input class, output class, maximum attempts, and a monetary or unit allowance. Every pre-check, generation call, fallback, and post-check joins this record. A user action that invokes one input check, one generation call, and one output check is one logical request with three attempts or stages, not three unrelated successes.

Keep an attempt ID separate from the logical ID. Record the stage (input_moderation, generation, output_moderation, or fallback), provider route, model, start and end times, status, usage fields, and reservation state. Do not put prompts, completions, image bytes, or credentials in the ordinary cost ledger. A short workload label and a fixture hash are usually enough for review.

2. Choose the smallest safety path that meets the product requirement

An input-only check can be appropriate when the product must reject unsafe requests before generation. An output check is needed when generated content can introduce a policy issue or when downstream actions depend on the final text or image. Some workloads need both. Do not add a second model call merely because a framework has a default safety hook; confirm what it protects and what it costs.

OpenAI’s guide describes two useful shapes: a standalone moderation request, or moderation scores returned with the generated response. An inline result can avoid a separate moderation round trip on a supported route, while a standalone check can prevent an expensive generation from starting. Compare the total request cost and failure behavior using the exact route. OpenAI’s statement that its moderation endpoint is free applies to that OpenAI endpoint; it is not a blanket exemption for a gateway’s transport, an alternate model, or a fallback generation.

Google’s safety settings let an application attach a threshold to a harm category. Store the category and threshold in the policy version so an unexplained change does not look like a cost optimization. A less restrictive threshold can change the number of blocked responses and review cases, and Google warns that applications using less restrictive settings may be subject to review. Treat the setting as a product and policy decision as well as a traffic decision.

3. Set attempt, payload, and output ceilings

Give each logical request a maximum number of safety stages and generation attempts. A starting policy might permit one input check, one generation attempt, one output check, and one explicitly approved fallback, but those are example controls rather than a vendor limit. Set text length, image count and size, output tokens, tool calls, timeout, and retry ceilings for each route. Apply the reservation before dispatch, including the worst-case approved fallback.

Do not confuse a safety threshold with a spend cap. Google can block content at a configured threshold, but the threshold does not bound the size of a request or the number of retries your application launches. Likewise, a moderation score or refusal category does not say whether another model is cheaper or safe to call. The gateway owns those admission rules.

Use a reservation record such as:

{
  "request_id": "req_demo_42",
  "attempt_id": "attempt_02",
  "stage": "generation",
  "route": "approved-route-a",
  "model": "resolved-model-id",
  "policy_version": "safety-budget-v3",
  "input_units_estimate": 1800,
  "output_cap": 600,
  "reserved_cost": null,
  "usage_state": "reserved",
  "safety_state": "pending"
}

A null currency reservation means the route’s approved unit conversion is unresolved; it should trigger review, not be treated as zero.

4. Classify outcomes before recovery

Use separate branches for a policy block, malformed request, authentication or permission failure, provider overload, timeout, and missing usage. A 400-class request error usually needs a payload repair, not a different model. A policy block needs a safe user-facing response, a permitted rewrite, or a human review path. A timeout may qualify for one bounded retry if the route contract says the operation is safe to repeat and the remaining allowance covers it.

Anthropic’s streaming-refusal guidance is a concrete example of why state matters. The stream ends with a refusal stop reason and a stop_details object. Usage metrics still arrive, and the documentation says to reset or rephrase the conversation context before continuing. Continuing the same context blindly can create repeated refusals and additional billed attempts. If a fallback model is approved, start it with a clean, policy-checked input and a new attempt ID.

Google’s guide reports a safety block as an error and says a streaming block arrives as an error event. Close the stream, record the event, and stop downstream consumers before considering recovery. Do not let a client retry on every error event while the server-side request is still unresolved.

5. Reconcile the whole path

At settlement, join all attempts to the logical request. Store estimated units, reported input and output usage, safety result, retry count, final route, and accepted-result status. Reconcile unresolved reservations on a timer or with provider billing evidence. If a response has no usage field, label the amount unknown and keep it in exposure until an owner resolves it.

Report at least these denominators:

moderation_attempt_rate = moderation_attempts / logical_requests
blocked_rate = blocked_or_refused_requests / logical_requests
retry_rate = recovery_attempts / logical_requests
cost_per_accepted_result = settled_total_cost / accepted_results
unknown_exposure = unresolved_reservations + missing_usage_attempts

A lower blocked rate is not automatically a saving, and a lower per-attempt price is not useful if the output fails review and causes another request. Compare accepted results, customer impact, latency, and settled cost together.

Failure modes

The word “free” becomes a gateway policy. OpenAI documents a free moderation endpoint on its own service. A team assumes every routed safety check is free and omits its reservation. Keep provider pricing, gateway pricing, and generation pricing as separate evidence fields.

A blocked prompt is retried unchanged. The same input receives the same block, or a fallback repeats the unsafe request. Stop the chain, show a controlled message, or route a reviewed rewrite. Count the first attempt and require fresh admission for any new payload.

A refused stream is counted as zero. Anthropic says usage metrics are still provided for refusals, and billing depends on when the refusal arrives and its category. Preserve the usage and classify the result; do not infer zero from the absence of visible text.

An error event triggers parallel retries. Streaming clients can see an error before all local state is closed. Mark the attempt terminal, cancel pending work where supported, and use an idempotent retry coordinator keyed by the logical request.

A threshold change hides a product decision. A safety threshold is loosened to reduce blocks, and the spend or review burden rises. Version thresholds, record the approver, and evaluate policy outcomes separately from cost outcomes.

Input and output checks share one counter. A team reports “one moderation call” while an inline check and a post-generation check both run. Record each stage, then report cost per logical request and per accepted result.

Missing usage is silently zero. A provider or gateway returns a response without a meter. Keep the amount unresolved and stop budget expansion until the route’s usage contract is understood.

The fallback model changes semantics. A different provider can use different categories, thresholds, context behavior, or price units. Re-run its safety and quality acceptance checks; do not inherit the primary route’s contract by name.

Verification before rollout

Run a small, non-production matrix with sanitized fixtures:

CaseEvidence to capturePass condition
Safe text inputInput-stage usage, policy version, generation resultOne bounded path, complete usage record
Safe image inputImage size, route, moderation outcome, usageSize is within the approved limit and the stage is attributed
Provider policy blockError or refusal event, attempt state, user messageNo automatic unchanged retry; reservation remains accounted
Stream interruptionTerminal stream event, cancellation, retry decisionNo duplicate in-flight generation
TimeoutAttempt status, unresolved exposure, retry admissionAt most the approved retry and a fresh attempt ID
Missing usageRaw safe status, reconciliation stateCost remains unknown or pending, never zero
FallbackPrimary and fallback route recordsFallback only runs under the remaining logical budget

For each route, freeze the model, policy version, payload fixture, output cap, and retry policy. Compare a standalone input check with an inline or post-generation shape only when the route supports both, and keep the workload constant. The goal is to measure the full path, not to claim that one provider’s safety behavior generalizes to another.

OpenAI’s guide says omni-moderation-latest accepts images up to 20 MB and not audio; test those boundaries in the adapter rather than forwarding unsupported media. Google safety settings should be tested at the chosen category thresholds, including a blocked response and a streaming error event. Anthropic’s refusal test should verify stop_reason, nullable stop_details fields, context reset, and the behavior of any approved fallback.

Declare pass/fail thresholds before the canary: maximum attempts per logical request, maximum unresolved exposure age, maximum cost per accepted result, and the allowed rate of missing usage. These are workload controls, not claims about provider limits.

FAQ

Does free moderation mean the safety path has no cost?

No. OpenAI documents a free moderation endpoint on OpenAI’s platform, but a CometAPI-routed application may use a different endpoint, transport, model, or fallback. Verify the exact route’s billable units and retain the evidence. Generation, retries, storage, and review work can still cost money even when one moderation call is free.

Should every request use both input and output moderation?

No universal rule applies. Use the smallest path that meets the product’s safety requirement, then test whether inline results, input checks, output checks, or human review cover the actual risk. The cost decision belongs beside the policy decision.

Can I retry a safety block on a cheaper model?

Only with an approved, policy-checked recovery path. A cheaper model may classify categories differently or produce an output that still violates the policy. Never retry the unchanged blocked payload automatically.

How should streaming clients handle a safety error?

Close the attempt, record the terminal error or refusal event, stop downstream consumers, and decide on recovery once. Google documents an error event for streaming safety blocks; Anthropic documents a refusal stop reason and requires context reset before continuing.

What if the provider returns no usage for a refusal?

Mark usage unknown, retain the attempt and reservation, and reconcile it against the route’s billing evidence. Unknown is an accounting state, not zero.

What is the right retry limit?

Choose the smallest limit that meets the workload’s availability and safety requirements. Declare it before launch, price the worst-case approved path, and raise it only after measured results show that the added attempts improve accepted outcomes within the budget.

Reader next step

Choose one production-like workload and write a logical-request budget with separate stages for input safety, generation, output safety, and fallback. Add a stable request ID, a maximum attempt count, an output cap, a route-specific unit conversion, and an unresolved-usage state. Run the verification matrix with sanitized fixtures, including one blocked response and one stream interruption.

Then compare the canary’s settled cost per accepted result with the number of blocked, refused, retried, and unknown-usage attempts. Keep the policy only when the evidence is complete and the safety outcome meets the workload’s requirements. For the approved access path, Start with CometAPI , and keep the exact route, model, threshold, and price revision in the request record.