Handling Fable 5 Refusals: A Working Guide to the Fallback API

The Fable 5 Moment
31 parts- 1Claude Mythos 5 Explained: What It Is, Who Can Access It, and Why It's Gated
- 2Migrating to Claude Fable 5: The Practical Guide
- 3Claude Fable 5 Access After the June 22 Deadline: Where Things Stand
- 4Claude Fable 5 vs GPT-5.6 Sol: Benchmarks, Pricing, and When Each Wins
- 5Fable 5 vs Opus 4.8: A Data-Driven Decision Guide for Engineering Teams
- 6How to Model Fable 5 Costs Before They Blow Up Your Budget
- 7Claude Fable 5 API: Production Integration Patterns, Rate Limits, and Migration Gotchas
- 8Handling Fable 5 Refusals: A Working Guide to the Fallback APICurrent
- 9Why Fable 5 Refuses Your Cybersecurity Queries (And How the Fallback Works)
- 10Fable 5's Hidden Guardrails: What Developers Need to Know About Silent Degradation
- 11Fable 5 Broke Enterprise ZDR Agreements: What Dev Teams Must Do Now
- 12Claude Managed Agents: Dreaming, Outcomes, and Multi-Agent Orchestration Explained
- 13Claude Managed Agents Public Beta: What's Actually Available vs What's Gated
- 14Dario Amodei Wants FAA-Style AI Regulation: Open Questions for Developers
- 15The Exponential and the Working Developer: Sitting With Amodei's Hardest Questions
- 16The Dario Paradox: Warning About the Exponential While Shipping It
- 17The Pushback on Amodei's Exponential Essay: Too Slow, Too Convenient, or About Right?
- 18Fable 5 Before June 22: The Decision Checklist for Every Plan Tier
- 19Fable 5 on AWS Bedrock: When Your Data Leaves the AWS Boundary
- 20Why Claude Desktop Installs a 1.8 GB Hyper-V VM on Windows
- 21Anthropic Model Names Explained: Fable, Mythos, Opus, Sonnet
- 22Managed Agents vs LangGraph vs Rolling Your Own: Who Should Run Your Agent Loop in 2026
- 23Claude Usage Limits With Fable 5: Windows and Burn Rates
- 24Fable 5 for Government and Regulated Teams: The GovCloud Question
- 25Fable 5 vs DeepSeek V4: The Cost-Quality Gap Measured in Real Tasks
- 26Fable 5 Orchestrator Playbook: Smart Model, Cheap Workers
- 27Prompt Caching Economics on Fable 5: When the 5-Minute TTL Pays
- 28Fable 5 with 1M Context: What Actually Works in Practice
- 29Claude Effort Levels Explained: Fable 5, Opus 5.5, Haiku 5.5
- 30Fable 5 Effort Levels vs Switching Models: When to Dial and When to Change
- 31Recursive Self-Improvement: What Fable 5, Dario's Essay, and Anthropic's Own Data Actually Tell Us
TL;DR
Handle Claude Fable 5 refusals with the fallback API: what a refusal looks like on the wire, three ways to handle it with code, and the billing rules.
Last updated: November 1, 2026
Re-verified November 1, 2026 against Anthropic's refusals and fallback and fallback credit docs. Changes since launch: the beta headers moved to
2026-07-01,fallbacksaccepts"default", two refusal categories were added, and some pre-output refusals are now billed. The sections below reflect the current docs.
Claude Fable 5 is the same model as the restricted-access Mythos 5, wrapped in safety classifiers. When a classifier fires, Fable 5 doesn't answer. In the Claude apps, the request silently falls back to Opus 4.8. On the API, handling that is your job. If you have not yet moved your integration over, see Migrating to Claude Fable 5 and the June 22 deadline post for the cutover timeline.
This matters even if your product has nothing to do with security or biology. The classifiers are tuned conservative and they catch normal work: developers reported a base64 implementation flagged as cyber, genome-alignment pipelines rerouted, and prompts asking the model to "explain its reasoning" tripping the extraction filter. Anthropic's own number is that under 5% of sessions hit a fallback. Across production traffic, that's not an edge case. That's Tuesday.
Here's how refusals work on the wire, and the three ways to handle them.
What a refusal looks like#
A refusal is not an error. You get HTTP 200 with a new stop reason:
{
"id": "msg_...",
"model": "claude-fable-5",
"stop_reason": "refusal",
"stop_details": {
"type": "refusal",
"category": "cyber",
"explanation": "This request was flagged by safety classifiers..."
},
"content": [...],
"usage": {...}
}
Three things to know:
stop_details.categoryis"cyber","bio","frontier_llm","reasoning_extraction","general_harms", ornull. Displayexplanationrather than parsing it; the docs say the text is not stable.- A refusal can happen before any output or mid-stream. Mid-stream, you pay for input plus whatever already streamed. Before any output, billing depends on the category (see the billing rules below), and the request still counts against your rate limits.
- If your code only checks for HTTP errors, refusals will surface as mysteriously short responses. Check
stop_reasonon every call.
Option 1: Manual retry on Opus 4.8#
The simplest approach. Catch the refusal, replay the conversation on claude-opus-4-8:
def create_with_fallback(client, **kwargs):
response = client.messages.create(model="claude-fable-5", **kwargs)
if response.stop_reason == "refusal":
# Optional: strip thinking blocks to save input tokens
clean_messages = strip_thinking_blocks(kwargs["messages"])
response = client.messages.create(
model="claude-opus-4-8",
**{**kwargs, "messages": clean_messages},
)
return response
On thinking blocks: the docs now say that when you are not redeeming a fallback credit you can leave earlier thinking and redacted_thinking blocks in place or strip them to save input tokens, because a fallback model that cannot read them has the API drop them without billing. When you do redeem a credit, send the body unchanged and do not strip them.
The bigger problem with manual retry is cost. Prompt caches are per-model. If you've built up a large cached prefix on Fable 5 and a refusal forces you to Opus 4.8, you pay full cache-write costs all over again on the new model. On a long agentic session with hundreds of thousands of cached tokens, that's real money. Anthropic shipped a fix for this, covered below.
Option 2: Server-side fallback (the good one)#
In beta. You ask for a fallback in the request and Anthropic handles the reroute server-side. The simplest form lets the API pick the model it recommends for the refusal category:
response = client.beta.messages.create(
model="claude-fable-5",
max_tokens=1024,
messages=messages,
fallbacks="default",
betas=["server-side-fallback-2026-07-01"],
)
Or name your own chain, up to three models, tried in order:
response = client.beta.messages.create(
model="claude-fable-5",
max_tokens=1024,
messages=messages,
fallbacks=[{"model": "claude-opus-4-8"}],
betas=["server-side-fallback-2026-07-01"],
)
Details that matter, per the current docs:
- The header is
server-side-fallback-2026-07-01. The earlier2026-06-01header is still referenced for older behavior, so check which one your SDK sends. - With
"default", categories that have no recommended fallback keep the refusal.reasoning_extractionis one: change the prompt instead of retrying. - Each named entry can override
max_tokens,thinking,output_configandspeedfor that attempt only. - Only a safety-classifier decline triggers the fallback. Rate limits, overload, and 5xx errors do not. If the fallback model is itself rate limited, you get the refusal back with
stop_details.recommended_modelas a hint. - Permitted fallback targets are published per model as
allowed_fallback_modelson the Models API when you set the beta header. - After a conversation falls back, the API routes later requests that include
fallbacksstraight to the fallback model for roughly an hour ("sticky routing").
The response tells you exactly what happened. The top-level model field reports whichever model actually answered, a new fallback content block marks the handoff:
{"type": "fallback", "from": {"model": "claude-fable-5"}, "to": {"model": "claude-opus-4-8"}}
and usage.iterations[] breaks out token usage per attempted model, which is what you want for cost attribution. The block now also carries a trigger with the refusal category.
Availability caveat: the docs list server-side fallback on the Claude API, Claude Models on Google Cloud (Anthropic managed) and Claude Platform on AWS. A batch request that includes fallbacks produces a per-item errored result, and the server-side-fallback header returns a 400 on Amazon Bedrock and Google-managed Claude. On those platforms, and for Claude Haiku 5.5 (which has no server-side fallback), you need option 3.
Option 3: SDK middleware#
The SDKs include a refusal-fallback middleware that implements the catch-refusal-retry-and-bill-correctly loop client-side. This is the Python form from Anthropic's docs; other languages have equivalents on client.beta.messages:
from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware
client = Anthropic(
middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)
state = BetaFallbackState() # pins follow-ups to the model that accepted
with state:
message = client.beta.messages.create(
max_tokens=1024,
model="claude-fable-5",
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.model)
Share one BetaFallbackState across a conversation so follow-ups stay on the model that accepted. This is the right answer on any platform where server-side fallback isn't available, and for teams who want the behavior without a server-side beta. It sends the fallback-credit header and applies the credit automatically, which brings us to billing.
The billing rules#
Scattered across three docs pages, collected here:
- Refusal before any output: billed when the category is
bio,frontier_llmorreasoning_extraction, at the rates of the model that ran it. Not billed forcyber,general_harmsor anullcategory. Anthropic says the billed categories are those where it measures low false-positive volume as of September 2026, and that the list may change. Either way the request counts against your rate limits. - Mid-stream refusal: you pay for input plus already-streamed output at normal rates.
- The fallback answer is billed at the fallback model's rates. On top of that, the refusal that triggered the fallback is billed too when it arrived mid-stream or is in a billed category. Check
usage.iterationsfor the per-attempt record. - Cache re-write costs are refundable via fallback credit, except after a Claude Haiku 5.5 refusal, which carries none.
That last one deserves explanation. When a refusal forces you onto a new model, the prompt cache for the new model has to be written from scratch. The refusal response carries a one-time token in stop_details:
"stop_details": {
"type": "refusal",
"fallback_credit_token": "fct_...",
"fallback_has_prefill_claim": true
}
Echo it as a top-level fallback_credit_token on your retry with the fallback-credit-2026-07-01 beta header (the server-side-fallback header also grants the fields), and the retry is billed as if the conversation had always been on the new model. No double-paying for cache writes. Redemption rules from the docs:
- The token expires 5 minutes after the refusal and only redeems from the same organization and workspace.
- The retry body must match the refused request on
system,messages,tools,tool_choice,thinkingandcache_control(plus a few optional fields).model,max_tokens,stop_sequences,stream,metadataandservice_tiermay change. - If
fallback_has_prefill_claimistrue, append one assistant message echoing the refusedcontentso the fallback model continues instead of starting over. - Batch refusals never mint tokens.
You only need to touch this if you're hand-rolling retries over raw HTTP. Server-side fallback and the SDK middleware both apply it for you.
Which option to use#
- New project on the Claude API: server-side fallback. Least code, correct billing, per-model usage breakdown.
- Bedrock, Google-managed Claude, Foundry, or Claude Haiku 5.5: SDK middleware. Server-side fallback is not offered there.
- Batch workloads: manual handling. A batch item with
fallbackserrors, so collect refused items and resubmit them on Opus 4.8 as a new batch or direct requests. - No SDK (raw HTTP): manual retry plus the fallback-credit token.
Reduce refusals before you handle them#
The cheapest refusal is the one that never fires. Two prompt-level fixes with outsized impact:
First, remove any instruction asking the model to reproduce its reasoning in responses. "Show your thought process" style prompts trigger the reasoning_extraction classifier. If you need process visibility, set thinking: {"display": "summarized"} and read the thinking blocks.
Second, if you work in security or life sciences legitimately, expect false positives and design for them rather than fighting them. The fallback path to Opus 4.8 is the supported answer. Anthropic says safeguards are set per model and per category, so a flagged request might fall back to a less capable model or simply be declined; for flagged requests, a clean fallback is a better experience than an argument with a classifier.
Log every refusal with its category. A week of data will tell you whether your workload has a 0.1% fallback rate or a 15% one, and that number should drive how much engineering you invest here.
FAQ#
Is a Fable 5 refusal billed the same as a normal request?#
It depends on the category. Per Anthropic's docs, a refusal before any output is billed for bio, frontier_llm and reasoning_extraction and not billed for cyber, general_harms or null; every refusal counts against rate limits. A mid-stream refusal bills input plus the output already streamed. The fallback answer is billed at the fallback model's rates, in addition to any billed refusal.
Does server-side fallback work on Bedrock or Vertex?#
Not per the current docs. Server-side fallback is listed for the Claude API and Claude Models on Google Cloud (Anthropic managed), and its beta header returns a 400 on Amazon Bedrock and Google-managed Claude. Elsewhere, use the SDK middleware, which applies the same catch-refusal-retry-and-bill-correctly logic client-side.
Can I avoid refusals instead of just handling them?#
Partially. Two prompt-level changes reduce false positives: dropping instructions that ask the model to reproduce its reasoning in the response (which can trip the reasoning-extraction classifier), and expecting false positives if you legitimately work in security or life sciences, then designing the fallback path for them rather than fighting the classifier.
What should I use if I am hand-rolling retries in raw HTTP?#
Manual retry plus the fallback-credit token. Echo the fallback_credit_token from the refusal response back on your retry within 5 minutes, with the fallback-credit-2026-07-01 beta header and a body that matches the refused request, so the retry is billed as if the conversation had always been on the fallback model, avoiding a double charge for cache writes.
Continue Reading#
- The Underground Relay Market for AI API Tokens: How Resellers Get 97% Off
- Claude Sonnet 5 Launch Analysis: The Most Agentic Sonnet Yet
- Claude Sonnet 5 vs Sonnet 4.6: Should You Upgrade?
- Claude Fable 5.1 in Claude Code: How to Switch, Pin, and Pay Less - what /model fable runs now and why cheaper cache reads matter for long sessions
- Claude Fable 5 - pricing, limits, and alternatives on one page
- Claude - the full model family, including the fallback tiers
Sources#
Get the next deep dive like this in your inbox
One email a week on Claude and the rest of the AI dev stack. Free.
Read next on Claude Code
Migrating to Claude Fable 5: The Practical Guide
Migrating to Claude Fable 5 from Opus 4.8 or older models - every breaking change, what to delete from your code, and the prompt audit to run before switching.
9 min readClaude Fable 5 Access After the June 22 Deadline: Where Things Stand
Claude Fable 5 access after the June 22 free window closed on Pro, Max, Team and Enterprise plans: what credits cost now and how to control Fable 5 spend.
6 min readWhy Fable 5 Refuses Your Cybersecurity Queries (And How the Fallback Works)
Why Claude Fable 5 refuses cybersecurity, bio and distillation queries, how it falls back to Opus 4.8, and what API developers must configure first.
8 min readTechnical content at the intersection of AI and development. Building with AI agents, Claude Code, and modern dev tools - then showing you exactly how it works.







