DEV Community

Cover image for How to Use the Claude Fable 5.1 API (Step-by-Step with Apidog)
Hassann
Hassann

Posted on Originally published at apidog.com

How to Use the Claude Fable 5.1 API (Step-by-Step with Apidog)

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.

Try Apidog today

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.

Claude Fable 5.1 API workflow

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"}
Enter fullscreen mode Exit fullscreen mode

These configurations return 400:

{"type": "disabled"}
Enter fullscreen mode Exit fullscreen mode
{"type": "enabled", "budget_tokens": N}
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode
{"type": "tool", "name": "..."}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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-..."
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Use these headers:

x-[REDACTED CREDENTIAL]
anthropic-version: 2023-06-01
content-type: application/json
Enter fullscreen mode Exit fullscreen mode

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."
      }
    ]
  }'
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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:

  • low
  • medium
  • high
  • xhigh
  • 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."
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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:

  • medium can roughly match Fable 5 at lower cost.
  • low is 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 xhigh and max, it may draft a long deliverable during thinking and then write it again. Allocate max_tokens accordingly.

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
Enter fullscreen mode Exit fullscreen mode

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.",
        },
    ],
)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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:

  1. Keep tool_choice set to auto.
  2. Name the tool explicitly in the instruction.
  3. Set strict: true, and use additionalProperties: false in 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."
            ),
        }
    ],
)
Enter fullscreen mode Exit fullscreen mode

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:

  1. Wait for stop_reason == "tool_use".
  2. Execute every tool_use block.
  3. Return all tool_result blocks in one user message.
  4. 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"
Enter fullscreen mode Exit fullscreen mode

The stop_details.category value can be:

  • cyber
  • bio
  • frontier_llm
  • reasoning_extraction
  • general_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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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:

  • fallbacks is rejected on the Batches API.
  • It is unavailable on Bedrock, Google Cloud, and Foundry.
  • For those platforms, register the SDK’s BetaRefusalFallbackMiddleware on 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"
}
Enter fullscreen mode Exit fullscreen mode

Also send the beta header:

thinking-display-updates-2026-08-18
Enter fullscreen mode Exit fullscreen mode

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."
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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,
)
Enter fullscreen mode Exit fullscreen mode

Expected behavior:

  • First request: cache_creation_input_tokens is nonzero and billed at $12.50 per million for the five-minute TTL.
  • Second request within five minutes: cache_read_input_tokens is 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_reason is not refusal on benign test prompts.
  • usage.cache_read_input_tokens > 0 on the second cache request.
  • No input_transformations entry has reason: "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

    Use auto, explicitly name the tool in the instruction, and set strict: true.

  • 400 for {"type": "disabled"} in thinking

    Remove the field and lower output_config.effort instead.

  • 400 invalid_request_error with 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 with display: "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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)