Claude Fable 5.1 shipped on September 1, 2026, and the API model ID is the exact string claude-fable-5-1, with no date suffix. It costs the same $10 per million input tokens and $50 per million output tokens as Fable 5, with cache reads cut to $0.25 per million, and it carries three breaking changes that Fable 5 did not have.
This guide walks the whole path: getting a key, sending a first request, controlling effort, streaming, tool use without forced tool_choice, refusal fallbacks, progress updates, and reading the usage object to confirm your cache is working at the new rate. Every request is plain HTTP with JSON, so you can build and debug it in Apidog before it goes into application code.
If you are migrating an existing Fable 5 or Opus 5 service rather than starting fresh, read the full migration guide alongside this one. For the model overview, start with what Claude Fable 5.1 is.

Before your first call: three things that return 400
1. Thinking cannot be configured, only steered. Fable 5.1 runs adaptive thinking on every request. Omit the thinking field, or send {"type": "adaptive"}. Both {"type": "disabled"} and {"type": "enabled", "budget_tokens": N} return a 400. If you are coming from Opus 5, where disabled was accepted at high effort or below, remove it and control spend with output_config.effort instead.
2. Forced tool use is gone. tool_choice: {"type": "any"} and {"type": "tool", "name": "..."} return tool_choice: type "tool" and "any" are not supported for this model. The fix is in the tool-use step below.
3. Your org needs 30-day data retention. Fable 5.1 is a Covered Model. A request from an organization or workspace on zero data retention returns 400 invalid_request_error with no other clue. If your first call fails and the body looks right, check retention before anything else.
All three are documented in Anthropic’s What’s new in Claude Fable 5.1.
Step 1: Get an API key
Sign in to the Claude Console, open the API keys section of your organization settings, and create a key. Copy it once; you cannot read it back later. Export it rather than pasting it into code:
export ANTHROPIC_API_KEY="sk-ant-..."
In Apidog, store it as an environment variable named ANTHROPIC_API_KEY and reference it as {{ANTHROPIC_API_KEY}} in the header, so the key never lands in a saved request body.
Step 2: Send your first request
Create a POST to https://api.anthropic.com/v1/messages with three headers: x-api-key, anthropic-version: 2023-06-01, and content-type: application/json.
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-fable-5-1",
"max_tokens": 16000,
"messages": [
{"role": "user", "content": "Explain the difference between idempotent and safe HTTP methods, with one example each."}
]
}'
The same call in Python with the official SDK:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
messages=[{"role": "user", "content": "Explain the difference between idempotent and safe HTTP methods, with one example each."}],
)
if response.stop_reason == "refusal":
print("declined:", response.stop_details.category if response.stop_details else None)
else:
for block in response.content:
if block.type == "text":
print(block.text)
Two habits to build from the first call. Check stop_reason before reading content, because a classifier refusal is an HTTP 200 with an empty content array. And give max_tokens real room. It caps thinking tokens plus response tokens together, and thinking is always on, so a tight value tuned for a no-thinking model will truncate here.
The response contains a thinking block whose text is empty under the default display of "omitted". That is expected. Pass it back unchanged on the next turn.
Step 3: Control cost and depth with effort
The effort parameter is the primary lever on Fable 5.1. It goes inside output_config, not at the top level, and accepts low, medium, high, xhigh, and max. The default is high.
{
"model": "claude-fable-5-1",
"max_tokens": 16000,
"output_config": {"effort": "medium"},
"messages": [{"role": "user", "content": "Summarize this changelog in five bullets."}]
}
Anthropic’s guidance: start at high, then sweep the others against your own evals, and re-run the sweep even if you did one on Fable 5, because level names do not correspond to the same amount of thinking across models. Their claim is that medium roughly matches Fable 5 at lower cost and that low is often competitive with Opus and Sonnet on cost per task. Two effort-specific behaviors to know: at low, Fable 5.1 calls search and retrieval tools less often and answers from memory more, and at xhigh and max it can draft a long deliverable in its thinking and then write it again, so set max_tokens for both.
Changing effort mid-conversation (beta). On Fable 5, changing the top-level effort between requests dropped the cached prefix. On Fable 5.1, a role: "system" message with empty content and an output_config changes effort from the next user turn onward without invalidating the cache. It requires the mid-conversation-output-config-2026-07-01 beta header and the client.beta.messages namespace.
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
output_config={"effort": "high"},
betas=["mid-conversation-output-config-2026-07-01"],
messages=[
{"role": "user", "content": "Plan a migration from SQLite to PostgreSQL in three short steps."},
{"role": "assistant", "content": "1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts."},
{"role": "system", "content": [], "output_config": {"effort": "low"}},
{"role": "user", "content": "Summarize the plan in one sentence."},
],
)
Lowering effort this way is reliable. Raising it works best for large jumps, such as low to xhigh. The effort parameter guide for Opus 5 covers the five levels in depth, and the same semantics apply here.
Step 4: Stream the response
Fable 5.1 turns on hard tasks can run for minutes at higher effort, so stream anything that might be long. The SDK requires streaming for max_tokens values near the 128,000 cap to avoid HTTP timeouts.
with client.messages.stream(
model="claude-fable-5-1",
max_tokens=64000,
messages=[{"role": "user", "content": "Write a test plan for a rate-limited public API."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
print(final.stop_reason, final.usage.output_tokens)
In Apidog, streaming responses render as they arrive, which is the quickest way to see how long a high-effort turn spends thinking before the first text token.
Step 5: Add tool use without forcing it
Define tools the same way as on Fable 5. What changes is how you guarantee a call. On Fable 5 you could force it with tool_choice: {"type": "tool", ...}. On Fable 5.1 that returns a 400, because a forced call would skip thinking and the model would write its working-out into the arguments.
The replacement has three parts: keep tool_choice at auto, name the tool in the instruction, and set strict: true (strict tool use) on the tool with additionalProperties: false in the schema so the arguments always validate.
record_summary_tool = {
"name": "record_summary",
"description": "Record the structured summary of the document.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {"summary": {"type": "string"}},
"required": ["summary"],
"additionalProperties": False,
},
}
response = client.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
tools=[record_summary_tool],
tool_choice={"type": "auto"},
messages=[{"role": "user", "content": "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result."}],
)
If the forced call only existed to get JSON back, use structured outputs (output_config.format) instead of a tool at all. If your application, not the user, requires a specific call on the current turn of a multi-turn conversation, append a role: "system" message after the latest user turn that names the tool and says the call is required, and keep that message in the history afterwards. tool_choice: {"type": "none"} still works for a turn that must not call tools.
The agentic loop itself is unchanged: when stop_reason is tool_use, execute every tool_use block, return all the tool_result blocks in one user message, and append the assistant turn back exactly as returned, thinking blocks included. That last clause matters more on Fable 5.1 than on any prior model, for reasons the preserved thinking guide explains.
One behavior to watch: in long loops where the next independent reads are only implied by the task, Fable 5.1 may issue one tool call per turn where Fable 5 batched several. Anthropic’s fix is a one-sentence nudge appended after each tool-result message: “First privately list what you need next; then request every item that doesn’t depend on another’s result in this one response.” Send it as a turn-scoped system message (clear_at: "next_user_message", beta header mid-conversation-system-clear-at-2026-08-21) and leave every earlier copy in place.
Step 6: Handle refusals with fallbacks
Fable 5.1 runs safety classifiers. A declined request comes back as HTTP 200 with stop_reason: "refusal" and a stop_details object naming the category: cyber, bio, frontier_llm, reasoning_extraction, or general_harms. A refusal before any output is not billed.
Opt into fallbacks by default. The simplest form is fallbacks: "default" with the server-side-fallback-2026-07-01 beta header, which retries a declined request on the model Anthropic recommends for that category. For Fable 5.1 the permitted targets are claude-opus-4-8 and claude-opus-5.
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
fallbacks="default",
betas=["server-side-fallback-2026-07-01"],
messages=[{"role": "user", "content": "Audit this authentication middleware for logic bugs."}],
)
fallback_ran = any(
entry.type == "fallback_message" for entry in (response.usage.iterations or [])
)
if fallback_ran and response.stop_reason != "refusal":
print("served by", response.model)
The response names the serving model in its top-level model field, and a fallback content block marks the handoff. Keep that block where it appeared when you echo the turn back. Two limits: fallbacks is rejected on the Batches API, and it is not available on Bedrock, Google Cloud, or Foundry, where you register the SDK’s BetaRefusalFallbackMiddleware on the client instead. The refusal handling guide covers billing, sticky routing, and the manual retry with fallback credit.
Step 7: Get progress updates during long turns
Between tool calls, Fable 5.1 writes short notes on what it found and what it will do next. Each arrives as its own thinking block immediately before the tool call, and under the default display those blocks are empty. Set display: "updates" with the thinking-display-updates-2026-08-18 beta header to receive them as text while the reasoning itself stays hidden.
{
"model": "claude-fable-5-1",
"max_tokens": 16000,
"thinking": {"type": "adaptive", "display": "updates"},
"tools": [...],
"messages": [{"role": "user", "content": "Review the PRs open against our billing service."}]
}
Any thinking block with non-empty text is then a status line you can render. Fable 5.1 writes fewer of them than Fable 5, so if your UI depends on narration, also remove any prompt line that tells the model to hold findings for the final response.
Step 8: Read the usage object for the $0.25 cache rate
Prompt caching is where Fable 5.1’s pricing change lands. Put cache_control on the stable prefix and confirm hits in usage:
response = client.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
system=[{"type": "text", "text": LONG_STABLE_SYSTEM_PROMPT, "cache_control": {"type": "ephemeral"}}],
messages=[{"role": "user", "content": "Which endpoints in the spec lack an error schema?"}],
)
u = response.usage
print(u.input_tokens, u.cache_creation_input_tokens, u.cache_read_input_tokens)
On the first send, cache_creation_input_tokens is nonzero (billed at $12.50 per million for the 5-minute TTL). On the second send within five minutes, cache_read_input_tokens should be nonzero, billed at $0.25 per million. If it stays zero across identical requests, something in the prefix changes each time: a timestamp in the system prompt, unsorted JSON, a varying tools array. The minimum cacheable prompt is 512 tokens.
Two cache facts specific to this model. Because a miss costs 40x a hit, keeping the cache warm matters more than it did on Fable 5, and both per-message effort and turn-scoped system messages exist partly so you can change things mid-session without a reset. And the same edits that reset the cache (rebuilding system, editing earlier turns) now also invalidate thinking blocks, so the append-only discipline pays twice.
Test and debug the whole flow in Apidog
Save each step above as a request in one Apidog collection: first call, effort variants, streaming, tool loop, fallback, cache check. Use environment variables for the key and for model, so switching a whole collection between claude-fable-5 and claude-fable-5-1 is one edit. Then add assertions: stop_reason is not refusal on your benign test prompts, usage.cache_read_input_tokens is greater than zero on the second cache request, and no input_transformations entry has reason: "prefix_binding_mismatch" when you run with the thinking-binding header. Run the collection before and after any harness change. Download Apidog to set it up; the same collection works as a CI check through the Apidog CLI.
Errors and gotchas you will hit
- 400
tool_choice: type "tool" and "any" are not supported for this model.Switch toautoplus an instruction andstrict: true. - 400 on
thinking: {"type": "disabled"}. Remove the field. Lower effort instead. - 400
invalid_request_errorwith a valid body. Check that the org or workspace has 30-day retention. - 400
Invalid signature in thinking block. The block is bound to a different conversation.Your code edited an earlier turn, the system prompt, or the tools array. See the preserved thinking guide. - Silent empty thinking text. Expected under
display: "omitted". Use"summarized"or"updates"if you render it. - Cache reads at zero. A volatile prefix. Audit for timestamps and unsorted objects.
- Priority Tier request fails validation. Fable 5.1 does not support Priority Tier. Fable 5 does.
FAQ
What is the model ID for the Claude Fable 5.1 API? claude-fable-5-1. On Amazon Bedrock it is anthropic.claude-fable-5-1; Google Cloud, Microsoft Foundry, and Claude Platform on AWS use claude-fable-5-1.
Do I need a beta header to use Claude Fable 5.1? No. The base model, adaptive thinking, effort, tools, and caching all work on the standard anthropic-version: 2023-06-01 header. Beta headers are only needed for per-message effort, turn-scoped system messages, progress updates, server-side fallbacks, and the thinking-binding controls.
Can I force a tool call on Claude Fable 5.1? No. tool_choice any and tool return a 400. Use auto, name the tool in the prompt, and set strict: true for schema-valid arguments, or use structured outputs for JSON extraction.
What is the max output on the Claude Fable 5.1 API? 128,000 tokens on the Messages API. Stream for anything large. The 300,000-token Batch API beta is not listed for Fable 5.1.
How do I see the cheaper cache reads? Look at usage.cache_read_input_tokens on a repeat request. Those tokens bill at $0.25 per million on Fable 5.1, versus $1 on Fable 5 and $0.50 on Opus 5. The pricing breakdown works the numbers.
Does the Fable 5 API guide still apply? Mostly. The Fable 5 API guide covers the same endpoint, but its forced tool-use examples now return a 400 and it predates per-message effort and progress updates.



