Errors & refusals/Model refusals

Detecting Model Refusals

When a Claude model refuses, Wokey forwards Anthropic's refusal unchanged. Downstream platforms can detect refusals with the fields below and apply their own risk controls.

On this pageexpand_more

Summarylink

  • A refusal returns HTTP 200, not an error status. Detect it from fields in the response.
  • The refusal reason comes at the end of the response. In a stream, content sent before the refusal is not withdrawn.
  • Wokey does not rewrite refusals; the wording comes from Anthropic.

Detection by API formatlink

Anthropic Messages /v1/messages

Detect when stop_reason == "refusal"

The category is in stop_details.category and the reason in stop_details.explanation. Streams carry them in the final message_delta event; non-streaming responses carry them at the top level of the message.

SSE
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"refusal","stop_sequence":null,"stop_details":{"type":"refusal","category":"cyber","explanation":"This request triggered ..."}},"usage":{...}}

event: message_stop
data: {"type":"message_stop"}

OpenAI Chat Completions /v1/chat/completions

Detect when finish_reason == "content_filter"

The reason is in the refusal field: choices[0].delta.refusal in the last stream chunk, or choices[0].message.refusal without streaming, where message.content is null. This format has no category.

SSE
data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"refusal":"This request triggered ..."},"finish_reason":"content_filter"}],"usage":{...}}

data: [DONE]

OpenAI Responses /v1/responses

Detect when output contains a content part of type "refusal"

The reason is in the part's refusal field. Streams emit response.refusal.delta and response.refusal.done events, and output_text is an empty string. This format has no category.

SSE
event: response.refusal.done
data: {"type":"response.refusal.done","item_id":"msg_...","output_index":0,"content_index":0,"refusal":"This request triggered ..."}

Refusal categories and wordinglink

categoryMeaningexplanation (verbatim)
reasoning_extractionTerms of Service: reverse engineering or duplicating model outputs (distillation)This request was blocked as it seems to violate Anthropic's Terms of Service restrictions on reverse engineering or duplicating model outputs. To learn more, visit https://www.anthropic.com/legal/commercial-terms.
frontier_llmTerms of Service: developing competing model productsThis request was blocked as our automated systems flagged that it may violate Anthropic's Terms of Service restrictions on developing competing model products. To learn more, visit https://www.anthropic.com/legal/commercial-terms.
cyberCyber content (Opus 5 and later, Fable, Sonnet 5.5)This request triggered restrictions on violative cyber content and was blocked under Anthropic's Usage Policy. To learn more, see https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback.
cyberCyber content (Opus 4.x, Sonnet 5, Haiku 5.5)This request triggered cyber-related safeguards. To learn about the Cyber Verification Program and apply for access, visit our help center: https://support.claude.com/en/articles/14604842-real-time-cyber-safeguards-on-claude.
general_harmsGeneral harms, such as explosivesThis request triggered restrictions on content related to the development of high-yield explosives and was blocked under Anthropic's Usage Policy. To learn more, provide feedback, or request an exemption based on how you use Claude, visit our help center: https://support.claude.com/
bio, othersBiology and other content where the upstream gives no reasonNo explanation field in the Anthropic format; the OpenAI formats return "The upstream model refused this request."

Noteslink

  • Anthropic writes the wording and may change it at any time. Prefer the detection fields and category over matching the exact text.
  • The OpenAI formats carry no category. To classify a refusal there, match it against the wording above.