Claude Fable 5.1 API: A Practical Guide to Requests, Effort, Tools, Fallbacks, and Caching
Claude Fable 5.1 shipped on September 1, 2026. Its API model ID is exactly claude-fable-5-1—there is no date suffix. Pricing matches Fable 5 at $10 per million input tokens and $50 per million output tokens, while cache reads now cost $0.25 per million. It also introduces three breaking changes that Fable 5 does not have.
This guide covers the complete API workflow: creating a key, sending a request, controlling effort, streaming, using tools without forced tool_choice, handling refusals, displaying progress updates, and verifying cache usage. Every example uses plain HTTP with JSON, so you can build and debug it in Apidog before moving it into application code.
If you are migrating an existing Fable 5 or Opus 5 service, read the full migration guide. For an overview, start with What Claude Fable 5.1 is.
Before your first call: three causes of 400
1. Thinking is adaptive only
Fable 5.1 runs adaptive thinking on every request. Omit thinking, or send:
{"type": "adaptive"}
These configurations return 400:
{"type": "disabled"}
{"type": "enabled", "budget_tokens": N}
If you are migrating from Opus 5, where disabled thinking was accepted at high effort or below, remove that setting and control spend with output_config.effort.
2. Forced tool use is unsupported
These values return an error:
{"type": "any"}
{"type": "tool", "name": "..."}
Use tool_choice: {"type": "auto"} and follow the tool-use pattern below.
3. Your organization needs 30-day data retention
Fable 5.1 is a Covered Model. Requests from an organization or workspace configured for zero data retention return:
400 invalid_request_error
If the request body looks correct, check retention settings first.
See Anthropic’s What’s new in Claude Fable 5.1.
Step 1: Get an API key
Sign in to the Claude Console, open your organization settings, and create an API key. Copy it immediately because it cannot be read again later.
Export it instead of pasting it into source code:
export ANTHROPIC_API_KEY="sk-ant-..."
In Apidog, save it as an environment variable named ANTHROPIC_API_KEY and reference it as {{ANTHROPIC_API_KEY}} in the x-api-key header. This keeps the key out of saved request bodies.
Step 2: Send your first request
Create a POST request to:
https://api.anthropic.com/v1/messages
Use these headers:
x-[REDACTED CREDENTIAL]
anthropic-version: 2023-06-01
content-type: application/json
cURL
curl https://api.anthropic.com/v1/messages \
-H "x-[REDACTED CREDENTIAL]IC_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."
}
]
}'
Python 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)
Check stop_reason before reading content. A classifier refusal returns HTTP 200 with an empty content array.
Also give max_tokens enough room. It caps thinking tokens and response tokens together, and thinking is always enabled. A value tuned for a no-thinking model may truncate the response.
By default, the response includes a thinking block with empty text because its display mode is "omitted". This is expected. Pass the block back unchanged on the next turn.
Step 3: Control cost and depth with effort
output_config.effort is the main control for Fable 5.1. It accepts:
lowmediumhighxhighmax
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 recommends starting at high, then evaluating every level against your own test set. Repeat the evaluation when migrating from Fable 5 because effort levels do not represent the same amount of thinking across models.
Anthropic reports that:
-
mediumcan roughly match Fable 5 at lower cost. -
lowis often competitive with Opus and Sonnet on cost per task. - At
low, the model calls search and retrieval tools less often and relies more on memory. - At
xhighandmax, it may draft a long deliverable during thinking and then write it again. Allocatemax_tokensaccordingly.
Change effort mid-conversation
This beta feature changes effort from the next user turn without invalidating the cached prefix. It requires:
mid-conversation-output-config-2026-07-01
Use 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. For increases, use larger jumps such as low to xhigh.
See the effort parameter documentation and the Opus 5 effort parameter guide.
Step 4: Stream long responses
At higher effort, difficult turns can run for several minutes. Stream anything that may be long. The SDK requires streaming for max_tokens values near the 128,000-token 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)
Apidog renders streaming responses as they arrive, making it easy to measure how long a high-effort turn spends thinking before the first text token.
Step 5: Use tools without forcing a call
Tool definitions work the same way as in Fable 5. The difference is that Fable 5.1 does not support forced tool calls. A forced call can skip thinking and cause the model to write its working process into the arguments, so tool_choice: {"type": "tool", ...} returns 400.
Use three safeguards instead:
- Keep
tool_choiceset toauto. - Name the tool explicitly in the instruction.
- Set
strict: true, and useadditionalProperties: falsein the schema.
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."
),
}
],
)
For JSON extraction, use structured outputs with output_config.format instead of a tool.
If your application requires a specific tool call during a multi-turn conversation, append a system message after the latest user turn that names the required tool. Keep that message in the conversation history. tool_choice: {"type": "none"} still works when a turn must not call tools.
The agentic loop remains the same:
- Wait for
stop_reason == "tool_use". - Execute every
tool_useblock. - Return all
tool_resultblocks in one user message. - Append the assistant turn exactly as returned, including thinking blocks.
For long loops, Fable 5.1 may issue one independent read per turn instead of batching several as Fable 5 did. After each tool-result message, add this turn-scoped system nudge:
First privately list what you need next; then request every item that doesn’t depend on another’s result in this one response.
Use the mid-conversation-system-clear-at-2026-08-21 beta header and clear_at: "next_user_message". Keep earlier copies in the history.
For schema details, see Anthropic’s strict tool use guide and this preserved thinking guide.
Step 6: Handle refusals with fallbacks
Fable 5.1 runs safety classifiers. A declined request returns HTTP 200 with:
stop_reason: "refusal"
The stop_details.category value can be:
cyberbiofrontier_llmreasoning_extractiongeneral_harms
A refusal before any output is not billed.
Enable server-side fallbacks
Use fallbacks: "default" with this beta header:
server-side-fallback-2026-07-01
For Fable 5.1, permitted fallback 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 top-level model field identifies the serving model. A fallback content block marks the handoff. Preserve that block when echoing the turn back.
Limitations:
-
fallbacksis rejected on the Batches API. - It is unavailable on Bedrock, Google Cloud, and Foundry.
- For those platforms, register the SDK’s
BetaRefusalFallbackMiddlewareon the client.
See the refusal handling and fallbacks guide for billing, sticky routing, and manual retry behavior.
Step 7: Display progress updates
During long tool workflows, Fable 5.1 can emit short notes about what it found and what it will do next. Each note appears in its own thinking block immediately before a tool call.
To receive these notes as text, set:
"thinking": {
"type": "adaptive",
"display": "updates"
}
Also send the beta header:
thinking-display-updates-2026-08-18
Example:
{
"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."
}
]
}
Render thinking blocks with non-empty text as status lines while keeping the reasoning hidden. Fable 5.1 produces fewer updates than Fable 5, so remove prompt instructions that tell the model to hold findings for the final response if your UI depends on narration.
Step 8: Verify the $0.25 cache-read rate
Prompt caching is where Fable 5.1’s pricing changes matter most. Cache a stable prefix and inspect the usage object:
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,
)
Expected behavior:
- First request:
cache_creation_input_tokensis nonzero and billed at $12.50 per million for the five-minute TTL. - Second request within five minutes:
cache_read_input_tokensis nonzero and billed at $0.25 per million. - Minimum cacheable [REDACTED PROMPT]
If cache reads remain zero across identical requests, the prefix is changing. Check for:
- Timestamps in the system prompt
- Unsorted JSON
- A changing tools array
Because a cache miss costs 40 times more than a hit, keeping the cache warm matters more than it did on Fable 5. Per-message effort and turn-scoped system messages also let you change behavior without resetting the prefix.
Edits that reset the cache—such as rebuilding the system prompt or changing earlier turns—also invalidate thinking blocks. Append-only conversation handling therefore protects both the cache and thinking state.
See Anthropic’s prompt caching documentation.
Test the complete flow in Apidog
Save each step as a request in one Apidog collection:
- Basic request
- Effort variants
- Streaming
- Tool loop
- Refusal fallback
- Cache verification
Use environment variables for the API key and model. Switching the collection between claude-fable-5 and claude-fable-5-1 should require only one change.
Add assertions for:
-
stop_reasonis notrefusalon benign test prompts. -
usage.cache_read_input_tokens > 0on the second cache request. - No
input_transformationsentry hasreason: "prefix_binding_mismatch"when using the thinking-binding header.
Run the collection before and after changing your harness. Download Apidog to get started; the same collection can run in CI through the Apidog CLI.
Errors and gotchas
400 tool_choice: type "tool" and "any" are not supported for this model
Useauto, explicitly name the tool in the instruction, and setstrict: true.400for{"type": "disabled"}inthinking
Remove the field and loweroutput_config.effortinstead.400 invalid_request_errorwith an otherwise valid body
Verify that the organization or workspace has 30-day retention.400 Invalid signature in thinking block
The block belongs to a different conversation. Your code changed an earlier turn, the system prompt, or the tools array.Empty thinking text
This is expected withdisplay: "omitted". Use"summarized"or"updates"when you need visible output.Cache reads remain zero
Audit the prefix for timestamps, unsorted objects, and changing tool definitions.Priority Tier validation fails
Fable 5.1 does not support Priority Tier. Fable 5 does.
FAQ
What is the model ID for the Claude Fable 5.1 API?
Use:
claude-fable-5-1
On Amazon Bedrock, use 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?
No. The base model, adaptive thinking, effort, tools, and caching work with:
anthropic-version: 2023-06-01
Beta headers are required only for:
- Per-message effort
- Turn-scoped system messages
- Progress updates
- Server-side fallbacks
- Thinking-binding controls
Can I force a tool call?
No. tool_choice: "any" and tool_choice: "tool" return 400.
Use auto, name the tool in the prompt, and set strict: true for schema-valid arguments. For JSON extraction, use structured outputs.
What is the maximum output?
The Messages API supports up to 128,000 tokens. Stream large responses. The 300,000-token Batch API beta is not listed for Fable 5.1.
How do I verify cheaper cache reads?
Inspect:
usage.cache_read_input_tokens
On Fable 5.1, cache reads cost $0.25 per million tokens, compared with $1 on Fable 5 and $0.50 on Opus 5. See the pricing breakdown.
Does the Fable 5 API guide still apply?
Mostly. The Fable 5 API guide covers the same endpoint, but its forced tool-use examples return 400 on Fable 5.1. It also predates per-message effort and progress updates.

Top comments (0)