Extended thinking — Claude reasoning step-by-step before answering — improves results on hard problems, but every thinking token is billed at the output rate and adds latency. The API has moved through two generations of control for this: an explicit per-request token budget, and the current approach of adaptive thinking plus an effort level. Which one you use depends on the model, so this is also a migration story.
The old dial: budget_tokens
Manual extended thinking is configured as thinking: {"type": "enabled", "budget_tokens": N}. The budget must be less than max_tokens (with one exception for interleaved thinking during tool use, where the budget is a total across thinking blocks), and Claude may not spend the whole allocation — especially above 32k, where actual usage often comes in under budget.
The catch: manual mode is generational. It returns a 400 error on the newest models — Claude Fable 5, Opus 4.8, Opus 4.7, and Sonnet 5 — is deprecated on Opus 4.6 and Sonnet 4.6, and remains the supported mechanism on older models such as Opus 4.5 and Haiku 4.5. If your code sets budget_tokens today, a model upgrade will break it.
The current dials: adaptive thinking + effort
The replacement is thinking: {"type": "adaptive"}, with no budget number at all. In adaptive mode Claude decides per request whether and how much to think, and interleaved thinking between tool calls comes automatically. On Fable 5 adaptive thinking is always on and cannot be disabled; on Sonnet 5 it is on by default; on Opus 4.8 and 4.7 you must set it explicitly.
Depth is then steered with the effort parameter: output_config: {"effort": "..."}, with levels low, medium, high (the default — setting it is exactly equivalent to omitting it), xhigh, and max. Effort is a behavioral signal, not a strict cap: at low effort Claude still thinks on genuinely hard problems, just less, and it affects all output — text length, tool-call verbosity, and thinking alike.
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=16000,
thinking={"type": "adaptive"},
output_config={"effort": "medium"},
messages=[{"role": "user", "content": task}],
)
details = response.usage.output_tokens_details
print(details.thinking_tokens, response.usage.output_tokens)
Tuning without overshooting
Anthropic's published starting points: default high for most work; xhigh for long-horizon agentic and coding tasks (on Opus 4.7/4.8, pair it with a large max_tokens — 64k is the suggested starting point); medium on Sonnet 5 lands roughly where Sonnet 4.6 does at high. Then tune against evidence, not vibes:
Watch two usage fields. usage.output_tokens_details.thinking_tokens tells you how much reasoning you paid for; output_tokens remains the authoritative billing total. If thinking dominates output on tasks your evals say are easy, drop a level.
Respect the max_tokens interaction. Thinking tokens count toward max_tokens. If responses end with stop_reason: "max_tokens", either raise the cap or lower effort — otherwise you pay for reasoning and still get a truncated answer.
Don't confuse visibility with cost. thinking.display: "omitted" (default on the newest models) hides the reasoning text and improves time-to-first-token, but you are billed for the full thinking tokens either way. Omitting reduces latency, not cost.
Platform availability
Adaptive thinking, effort, and manual extended thinking are generally available on the Claude API, Claude Platform on AWS, Amazon Bedrock, Google Vertex AI, and Microsoft Foundry. The per-model rules (which mode a model accepts) travel with the model, not the platform, so the migration guidance above applies identically everywhere.
Where to go next
See the max_tokens article for the cap that thinking shares, token counting for pre-flight estimates, and the feature matrix for platform status.