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.
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.
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.
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
| category | Meaning | explanation (verbatim) |
|---|---|---|
| reasoning_extraction | Terms 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_llm | Terms of Service: developing competing model products | This 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. |
| cyber | Cyber 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. |
| cyber | Cyber 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_harms | General harms, such as explosives | This 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, others | Biology and other content where the upstream gives no reason | No 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.