handle-streaming-refusals changedtest-and-evaluate/strengthen-guardrails/handle-streaming-refusals
Nearest release: v2.1.312, published under an hour before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Recorded here
Lines+8added
Lines−8removed
From line
4
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits15to this page, all time
The whole hunk
from line 4, old and new numbered
/
from line 4
44description: Detect and handle refusal stop reasons in streaming responses, and retry refused requests on a fallback model.
55---
66
7Starting with Claude 4 models, streaming responses from Claude's API return **`stop_reason`: `"refusal"`** when streaming classifiers intervene to handle potential policy violations. This safety feature helps maintain content compliance during real-time streaming.
7Starting with Claude 4 models, streaming responses from Claude’s API return **`stop_reason`: `"refusal"`** when streaming classifiers intervene to handle potential policy violations. This safety feature helps maintain content compliance during real-time streaming.
88
99<Tip>
1010 This page covers how refusals appear in streaming responses. For every `stop_reason` value and how to handle it, see [Stop reasons and fallback](https://platform.claude.com/docs/en/build-with-claude/handling-stop-reasons). To retry refused requests on another Claude model, see [Refusals and fallback](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback).
from line 12
1212
1313## API response format
1414
15When streaming classifiers detect content that violates Anthropic's policies, the API returns this response:
15When streaming classifiers detect content that violates Anthropic’s policies, the API returns this response:
1616
1717```json
1818{
from line 54
5454
5555## Implementation guide
5656
57Here's how to detect and handle streaming refusals in your application:
57Here’s how to detect and handle streaming refusals in your application:
5858
5959<CodeGroup exclude="shell:cURL, shell:CLI">
6060 <CodeGroupItem language="cURL">
from line 305
305305* **Monitor for refusals:** Include **`stop_reason`: `refusal`** checks in your error handling.
306306* **Reset automatically:** Implement automatic context reset when refusals are detected.
307307* **Fall back to another model:** Configure [server-side fallback or the SDK middleware](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback) so refused requests are retried on another Claude model instead of surfacing a refusal to the user. Claude Haiku 5.5 has no server-side fallback, so set up its retry in your client.
308* **Redeem fallback credit on manual retries:** If you build the retry yourself, pass the refusal's [fallback credit](https://platform.claude.com/docs/en/build-with-claude/fallback-credit) token so the retry doesn't pay the prompt-cache cost twice. Claude Haiku 5.5 refusals carry no fallback credit.
308* **Redeem fallback credit on manual retries:** If you build the retry yourself, pass the refusal’s [fallback credit](https://platform.claude.com/docs/en/build-with-claude/fallback-credit) token so the retry doesn’t pay the prompt-cache cost twice. Claude Haiku 5.5 refusals carry no fallback credit.
309309* **Provide custom messaging:** Create user-friendly messages for better UX when refusals occur.
310310* **Track refusal patterns:** Monitor refusal frequency to identify potential issues with your prompts.
311311
312312## Migration notes
313313
314If you built refusal handling when this feature first shipped, or you're adding it to an existing integration, check the following:
314If you built refusal handling when this feature first shipped, or you’re adding it to an existing integration, check the following:
315315
316* **Refusals are responses, not errors.** A refusal arrives as a successful HTTP 200 response with `stop_reason`: `"refusal"`, so monitoring built only on error rates won't surface it. Track refusals as their own signal.
316* **Refusals are responses, not errors.** A refusal arrives as a successful HTTP 200 response with `stop_reason`: `"refusal"`, so monitoring built only on error rates won’t surface it. Track refusals as their own signal.
317317* **Refusals include structured detail.** On every model, a refusal also includes a `stop_details` object that identifies the policy category behind the decline. See [What a refusal looks like](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback#refusal-response) for the full response shape.
318318* **Retry on a different model.** Re-sending a refused request to the same model usually results in another refusal. Instead of only resetting context, retry on a fallback model with [server-side fallback, the SDK middleware, or a manual retry](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback), and redeem [fallback credit](https://platform.claude.com/docs/en/build-with-claude/fallback-credit) when you build the retry yourself. Claude Haiku 5.5 has no server-side fallback, and its refusals carry no fallback credit, so set up its retry in your client.
319319* **Check batch results for refusals.** A refused request in a [Message Batch](https://platform.claude.com/docs/en/build-with-claude/batch-processing) is returned as a succeeded result with `stop_reason`: `"refusal"`, not as an errored result.
from line 335
335335 </Card>
336336
337337 <Card title="Multilingual support" icon="text-aa" href="https://platform.claude.com/docs/en/build-with-claude/multilingual-support">
338 Serve users across languages with Claude's cross-lingual capabilities.
338 Serve users across languages with Claude’s cross-lingual capabilities.
339339 </Card>
340340</CardGroup>
341341
No line in this hunk matches that.