For how zero data retention (ZDR) applies to this feature, see API and data retention.
A model that answers in a single pass has to get everything right on the first try: no scratch work, no checking, no changing course halfway through. For a proof, a tricky bug, or a long agentic task, the first approach is often not the best one.
Thinking removes that constraint. When thinking is active, Claude works through the problem in its own words before answering: it restates what is being asked, tries approaches, checks intermediate results, and abandons paths that do not hold up. That reasoning arrives in thinking content blocks ahead of the response, and Claude draws on it to produce the final answer. This is why thinking improves performance on complex tasks like math, coding, analysis, and long-running agentic work, where the quality of the answer depends on intermediate work that would otherwise be compressed into the response itself or skipped.
Thinking has a cost: the tokens Claude spends reasoning are billed as output tokens, even when the thinking text isn't returned to you, and they count toward max_tokens alongside the response text. This page covers how thinking behaves across the API surface: turning it on, reading its output, and managing its interactions with tools, streaming, caching, and the context window.
Whether Claude thinks on a given request, and how deeply, depends on your thinking configuration and the complexity of the request.
Here is what thinking looks like in a response: one or more thinking content blocks arrive before the text blocks. The thinking block is still generated content, like the text block that follows it, but it is separated from the canonical response. Each thinking block also carries a signature field, an encrypted copy of the full reasoning that you pass back unchanged in multi-turn and tool-use conversations (see Thinking encryption):
{
"content": [
{
"type": "thinking",
"thinking": "Let me break this down. The question has two parts, so I'll start with the simpler one and use its result to constrain the second...",
"signature": "WaUjzkypQ2mUEVM36O2Txu...."
},
{
"type": "text",
"text": "Based on my analysis..."
}
]
}You don't always see this text, and what you see is never the raw chain of thought: the text in a thinking block is a summary of Claude's reasoning. The display field on the thinking configuration controls whether that summary is returned at all: "summarized" returns it, while "omitted", the default on the newest models, returns thinking blocks with an empty thinking field. Either way the block is billed the same and passed back the same in multi-turn conversations; see Controlling thinking display for per-model defaults and details.
If Claude uses tools, thinking can also appear between tool calls; see Thinking with tool use. For the full response format, see the Messages API reference.
On current models, thinking is on by default or one parameter away. Which configuration each model accepts, and what it defaults to, is listed in the per-model configuration table on the Troubleshooting page.
On Claude Sonnet 5, Claude Fable 5, Claude Mythos 5, and Claude Mythos Preview, thinking is already on: no configuration needed. The first thing most developers need on these models is to see the thinking text, since display defaults to "omitted" there. Opt in with thinking: {"type": "adaptive", "display": "summarized"}, which is exactly the following request with the model string swapped.
On Claude Opus 4.8, Claude Opus 4.7, Claude Opus 4.6, and Claude Sonnet 4.6, thinking is off until you set thinking: {type: "adaptive"} in your request. The following examples do that, set display: "summarized" so the thinking text is visible, and use a roomy max_tokens:
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=16000,
thinking={"type": "adaptive", "display": "summarized"},
messages=[
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?",
}
],
)
for block in response.content:
if block.type == "thinking":
print(f"\nThinking: {block.thinking}")
elif block.type == "text":
print(f"\nResponse: {block.text}")Running the example prints the summarized thinking, then the answer:
Thinking: Use Euclidean algorithm.
1071 = 2*462 + 147
462 = 3*147 + 21
147 = 7*21 + 0
GCD = 21
Response: ## Finding GCD of 1071 and 462
I'll use the **Euclidean algorithm**, repeatedly dividing and taking remainders...Thinking tokens count toward max_tokens, so set it high enough to leave room for both the thinking and the response text. See Cost control on the steering page and Thinking and the context window.
On Claude Sonnet 5, where thinking is on by default, you can turn it off:
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=4096,
thinking={"type": "disabled"},
messages=[{"role": "user", "content": "Summarize this article in one sentence."}],
)Claude Fable 5, Claude Mythos 5, and Claude Mythos Preview reject thinking: {type: "disabled"}: thinking cannot be turned off on these models.
If your model supports only extended thinking (see the per-model configuration table), configure it with type: "enabled" and a budget_tokens value instead; the Extended thinking page covers that configuration. And if any thinking configuration comes back with a 400 error, Troubleshooting thinking matches each error message to its fix.
The display field on the thinking configuration controls how thinking content is returned in API responses. display works in both modes: set it alongside type: "adaptive" or type: "enabled". It accepts two values:
"summarized": thinking blocks contain summarized thinking text, a readable summary of Claude's reasoning. This is the default on Claude Opus 4.6, Claude Sonnet 4.6, and earlier models."omitted": thinking blocks are returned with an empty thinking field. The signature field still carries the encrypted full thinking for multi-turn continuity (see Thinking encryption). This is the default on Claude Fable 5, Claude Mythos 5, Claude Sonnet 5, Claude Opus 4.8, Claude Opus 4.7, and Claude Mythos Preview.Set display: "omitted" when your application doesn't surface thinking content to users. The primary benefit is faster time-to-first-text-token when streaming: the server skips streaming thinking tokens entirely and delivers only the signature, so the final text response begins streaming sooner.
With display: "omitted", the response contains thinking blocks with an empty thinking field:
{
"content": [
{
"type": "thinking",
"thinking": "",
"signature": "EosnCkYICxIMMb3LzNrMu..."
},
{
"type": "text",
"text": "The answer is 12,231."
}
]
}Keep the following in mind when working with omitted thinking:
signature to reconstruct the original thinking for prompt construction (see Preserving thinking blocks). Any text you place in the thinking field of a round-tripped omitted block is ignored.display is invalid with thinking.type: "disabled" (there is nothing to display).thinking.type: "adaptive" and the model skips thinking for a simple request, no thinking block is produced regardless of display.display: "omitted", no thinking_delta events are emitted; see Streaming thinking for the event sequence.The signature field is identical whether display is "summarized" or "omitted". Switching display values between turns in a conversation is supported.
In the Ruby SDK, set this field as display_: (with a trailing underscore) to avoid shadowing Ruby's Kernel#display; the wire field is still display.
When display is "summarized", the thinking text you receive is a summary of Claude's full thinking process rather than the raw chain of thought. Summarized thinking provides the full intelligence benefits of thinking while preventing misuse. No display setting returns the raw chain of thought.
Keep the following in mind when working with summarized thinking:
In rare cases where you need access to full thinking output, contact Anthropic sales.
Thinking works with streaming. Thinking blocks stream as thinking_delta events inside content_block_delta events, followed by a single signature_delta event just before the block's content_block_stop. Text blocks stream afterward as usual.
The following examples stream a response with adaptive thinking, printing thinking and text deltas as they arrive:
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-opus-4-8",
max_tokens=16000,
thinking={"type": "adaptive", "display": "summarized"},
messages=[
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?",
}
],
) as stream:
for event in stream:
if event.type == "content_block_start":
print(f"\nStarting {event.content_block.type} block...")
elif event.type == "content_block_delta":
if event.delta.type == "thinking_delta":
print(event.delta.thinking, end="", flush=True)
elif event.delta.type == "text_delta":
print(event.delta.text, end="", flush=True)When display: "omitted" is set, the thinking block opens, a single signature_delta arrives, and the block closes without any thinking_delta events. Text streaming begins immediately after:
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"thinking","thinking":"","signature":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"signature_delta","signature":"EosnCkYICxIMMb3LzNrMu..."}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"text","text":""}}When using streaming with thinking enabled, you might notice that text sometimes arrives in larger chunks alternating with smaller, token-by-token delivery. This is expected behavior, especially for thinking content.
The streaming system needs to process content in batches for optimal performance, which can result in this "chunky" delivery pattern, with possible delays between streaming events.
For general streaming mechanics, see Streaming Messages.
The thinking parameter controls whether Claude thinks in thinking blocks before answering; the effort parameter controls how much work Claude puts into the whole response, which in adaptive mode includes how often and how deeply it thinks. Don't pass adaptive as an effort value: adaptive is a thinking mode, not an effort level.
For what each effort level does to thinking behavior, see the per-level thinking behavior table on the Steering thinking page; the Effort page documents the parameter itself, including which levels each model supports. On Claude Opus 4.5, the only extended-thinking-only model that supports effort, effort composes with budget_tokens; see Budget rules and tuning.
With the two controls separated this way, pick the one that matches your goal:
effort first. It scales the whole response down, thinking included.effort, or see Steering how often Claude thinks on the steering page.thinking: {type: "disabled"} on models that allow it (see the per-model configuration table).max_tokens. Effort is soft guidance; max_tokens is a strict limit.Thinking works alongside tool use, letting Claude reason through tool selection and process tool results. Two constraints apply in both thinking modes:
tool_choice: {"type": "auto"} (the default) or tool_choice: {"type": "none"}. Using tool_choice: {"type": "any"} or tool_choice: {"type": "tool", "name": "..."} results in an error because these options force tool use, which is incompatible with thinking.A tool-use loop is one assistant turn. From the model's perspective, an assistant turn doesn't complete until Claude finishes its full response, which may include multiple tool calls and results. This whole sequence is a single assistant turn:
User: "What's the weather in Paris?"
Assistant: [thinking] + [tool_use: get_weather]
User: [tool_result: "20°C, sunny"]
Assistant: [text: "The weather in Paris is 20°C and sunny"]The entire turn runs in a single thinking mode: you can't toggle thinking in the middle of a turn, including during the tool-use loop. In extended (manual) mode, the API additionally enforces that the final assistant turn of a thinking-enabled request begins with a thinking block. Adaptive mode relaxes this: no assistant turn needs to start with one.
Mid-turn conflicts degrade gracefully. If you toggle thinking mid-turn (for example, between sending a tool call and returning its result), the API doesn't error. Instead, it silently disables thinking for that request. To preserve model quality, the API may strip thinking blocks that would create an invalid turn structure, or disable thinking when the conversation history is incompatible with thinking being enabled. To confirm whether thinking was active, check for the presence of thinking blocks in the response.
Toggle between turns, not within them. Plan your thinking strategy at the start of each turn. Complete the assistant turn, then change the thinking configuration for the next one:
User: "What's the weather?"
Assistant: [tool_use] (thinking disabled)
User: [tool_result]
Assistant: [text: "It's sunny"]
User: "What about tomorrow?"
Assistant: [thinking] + [text: "..."] (thinking enabled - new turn)Note that toggling thinking modes also invalidates prompt caching; see Thinking and prompt caching.
When Claude invokes a tool, it pauses construction of its response to await external information. When you return the tool result, Claude continues building that same response, so its earlier reasoning must still be present. Pass every thinking block back to the API complete and unmodified, alongside the tool_use block it accompanied. This matters for two reasons:
In short:
You don't need to prune old thinking yourself. Pass all thinking blocks back in multi-turn conversations, and the API automatically filters them, keeps the blocks needed to preserve the model's reasoning, and bills input tokens only for the blocks actually shown to Claude. Which prior-turn blocks are kept is per-model; see Thinking block preservation by model. To override the default, use the clear_thinking_20251015 context-editing strategy.
Within the latest assistant message, the sequence of consecutive thinking blocks must match what the model generated in the original request: you can't rearrange, edit, or partially drop them. This includes redacted_thinking blocks.
Modified thinking blocks are rejected with a 400 error; see A 400 error says thinking blocks cannot be modified for the exact message, the common causes, and the fix. The one exception: text placed in the empty thinking field of an omitted block is ignored rather than rejected.
For a complete two-turn walkthrough with code in every SDK, see Thinking in tool and multi-turn workflows. It defines a tool, receives a thinking-plus-tool-use response, and echoes the assistant turn back with the tool result.
Interleaved thinking lets Claude think between tool calls, reasoning about each tool result before acting on it. With interleaved thinking, Claude can:
Consecutive tool calls do not require interleaved thinking. Claude can chain tool calls with or without interleaved thinking; interleaving changes where thinking blocks appear between tool calls, not whether tool calls can chain.
With adaptive thinking, interleaved thinking is automatic on every model that supports adaptive thinking; no beta header is needed. On Claude Fable 5, Claude Mythos 5, Claude Mythos Preview, Claude Opus 4.8, and Claude Opus 4.7, reasoning between tool calls always appears in thinking blocks. Claude Haiku 4.5 does not support interleaved thinking. On models using manual extended thinking, interleaving requires a beta header and changes how the thinking budget is counted; Interleaved thinking in manual mode covers the per-model rules and platform-specific header behavior.
With interleaved thinking, the thinking allocation can span the entire assistant turn rather than a single response. Interleaved thinking is only supported for tools used through the Messages API.
For a worked comparison showing what interleaved thinking changes in a two-tool workflow, see How interleaved thinking changes the flow.
Whether thinking blocks from previous assistant turns stay in context by default depends on the model:
Preservation brings two benefits:
The tradeoff is context usage: long conversations consume more context space on keep-all models, since retained thinking blocks count as input like any other conversation history (see Thinking and the context window). The behavior is automatic in both regimes; no code changes or beta headers are required, and you should keep passing complete, unmodified thinking blocks back as described in Preserving thinking blocks. To override the default in either direction, use thinking block clearing.
Switching models mid-conversation. When you switch between any two models, for example after a classifier refusal fallback, strip thinking and redacted_thinking blocks from prior assistant turns. Thinking blocks are tied to the model that produced them. Other models silently ignore them rather than rejecting the request, but ignored blocks still add input tokens.
Prompt caching interacts with thinking in a few specific ways. The following rules apply in both thinking modes.
Configuration changes invalidate caching. The thinking configuration and the resolved effort level are rendered into the prompt itself, so changing any of them starts a new cache prefix. Switching between adaptive, enabled, and disabled, changing budget_tokens, and changing the effort value all invalidate cache breakpoints: message-level breakpoints always miss, and tool and system-prompt breakpoints can miss too, depending on where the model renders the configuration. Treat any thinking or effort change as starting the cache over. Consecutive requests that keep the same configuration preserve the cache, and setting a parameter explicitly to its default value is equivalent to omitting it. A worked demonstration with usage output is on the Steering thinking page.
Thinking blocks are cached with tool results. During a tool-use loop, caching occurs when you make a follow-up request that includes tool results. At that point the previous conversation history, including its thinking blocks, can be cached, and those cached thinking blocks count as input tokens in your usage metrics when read from the cache. This happens automatically, even without explicit cache_control markers, and behaves the same for regular and interleaved thinking. The tradeoff: thinking blocks you never see again in responses still contribute to input token usage when read from cache.
Whether prior blocks are in context at all is per-model. The preservation default governs this. On keep-all models, previous turns' thinking blocks stay cached and in context. On last-turn-only models, once you send a user message that isn't a tool result, all previous thinking blocks are stripped from context. On those models, a conversation like this:
User: ["What's the weather in Paris?"],
Assistant: [thinking_block_1] + [tool_use block 1],
User: [tool_result_1, cache=True],
Assistant: [thinking_block_2] + [text block 2],
User: [Text response, cache=True]is processed as if the thinking blocks were never there:
User: ["What's the weather in Paris?"],
Assistant: [tool_use block 1],
User: [tool_result_1, cache=True],
Assistant: [text block 2],
User: [Text response, cache=True]On keep-all models, the same request keeps thinking_block_1 and thinking_block_2 in context and in the cache.
Degradation strips thinking from the cacheable history. If thinking becomes disabled mid-turn and you pass thinking content in the current tool-use turn, the thinking content is stripped and thinking remains disabled for that request (see graceful degradation). Interleaved thinking amplifies cache invalidation effects, since thinking blocks can occur between multiple tool calls.
Thinking-heavy tasks often take longer than the default 5-minute cache lifetime to complete. Consider the 1-hour cache duration to maintain cache hits across longer thinking sessions and multistep workflows.
max_tokens, which includes all thinking Claude generates in the current turn, is enforced as a strict limit. On Claude 4.5 models and newer, if input tokens plus max_tokens exceeds the context window size, the API accepts the request; if generation then reaches the context window limit, it stops with stop_reason: "model_context_window_exceeded" instead of returning an error. On earlier models, the API returns a validation error instead. See Handling stop reasons.
How thinking counts against the window depends on when it was generated:
max_tokens, is billed as output tokens, and occupies context window space for the turn that generated it.In practice:
max_tokens and then drops out of the window.The following diagrams illustrate the last-turn-only (stripping) regime. The first shows a multi-turn conversation: each turn's thinking block is generated in the output but not carried into later turns' input.
The second shows the same regime with tool use: thinking stays in context alongside its tool result for the duration of the assistant turn, then drops out on the next user turn.
Use the token counting API to get accurate counts for your specific use case, especially for multi-turn conversations that include thinking.
Full thinking content is encrypted and returned in the signature field on each thinking block. The API uses the signature to verify that thinking blocks were generated by Claude when you pass them back.
Keep the following in mind when working with signatures:
signature_delta inside a content_block_delta event just before the content_block_stop event.signature values are significantly longer in Claude 4 and later models than in previous models.signature field is opaque: don't interpret or parse it.signature values are compatible across platforms (Claude APIs, Amazon Bedrock, and Google Cloud). Values generated on one platform work on another.In addition to regular thinking blocks, the API may return redacted_thinking blocks when portions of Claude's reasoning are safety-redacted. A redacted_thinking block contains encrypted thinking content in a data field, with no readable text:
{
"type": "redacted_thinking",
"data": "..."
}The data field is opaque and encrypted. Like the signature field on regular thinking blocks, pass redacted_thinking blocks back to the API unchanged when continuing a multi-turn conversation with tools.
If your code filters content blocks by type (for example, block.type == "thinking") when round-tripping responses with tool use, also include redacted_thinking blocks. Filtering on block.type == "thinking" alone silently drops redacted_thinking blocks and breaks the multi-turn protocol described in Preserving thinking blocks.
redacted_thinking blocks are a distinct content block type returned when thinking is safety-redacted. This is separate from the display: "omitted" option, which returns regular thinking blocks with an empty thinking field.
On Claude Fable 5 and Claude Mythos 5, the raw chain of thought is never returned; the blocks you receive are regular thinking blocks, not redacted_thinking, and the display setting works the same as on other models (summarized text, or an empty thinking field when omitted, the default here). For the response shape of thinking blocks, see the Messages API reference.
When continuing a conversation on the same model, pass each thinking block back to the API exactly as received, including blocks whose thinking field is empty. Don't edit or reconstruct them. Reading the summary text for display is fine: the API rejects blocks whose returned content has been modified, not blocks you have read. Text placed in an empty omitted thinking field is ignored rather than rejected.
For what happens to thinking blocks when you switch models mid-conversation, see Thinking block preservation by model.
Two exceptions, covered in Fallback credit:
fallback blocks from a mid-output fallback stay where they appeared.To get visibility into the model's reasoning, read the thinking blocks described on this page rather than prompting for reasoning in the response text. On Claude Fable 5, a request that attempts to elicit the model's internal reasoning as part of the response text can be refused with stop_details.category: "reasoning_extraction". See Refusal categories for the field reference and handling guidance.
Sampling parameters. On Claude Fable 5, Claude Mythos 5, Claude Mythos Preview, Claude Opus 4.8, Claude Opus 4.7, and Claude Sonnet 5, non-default temperature, top_p, or top_k values return a 400 error on every request, regardless of whether thinking is used. On older models, the restriction applies only while thinking is on: temperature and top_k are incompatible with thinking, and top_p is allowed at values between 0.95 and 1.
Response prefill and forced tool use. You can't pre-fill the assistant response while thinking is on. Forced tool use (tool_choice: {"type": "any"} or {"type": "tool", ...}) is incompatible with thinking; see Thinking with tool use.
Output limits. Claude Fable 5, Claude Mythos 5, Claude Mythos Preview, Claude Opus 4.8, Claude Opus 4.7, Claude Sonnet 5, Claude Opus 4.6, and Claude Sonnet 4.6 support up to 128k output tokens per request. Claude Haiku 4.5, Claude Sonnet 4.5, and Claude Opus 4.5 support up to 64k. On the Message Batches API, the output-300k-2026-03-24 beta header raises the limit to 300k for Claude Opus 4.8, Claude Opus 4.7, Claude Sonnet 5, Claude Opus 4.6, and Claude Sonnet 4.6. See the models overview for limits on legacy models.
Long requests. The SDKs require streaming when max_tokens is greater than 21,333, to avoid HTTP timeouts on long-running requests. This is a client-side validation, not an API restriction. If you don't need to process events incrementally, use .stream() with .get_final_message() (Python) or .finalMessage() (TypeScript) to get the complete Message object without handling individual events; see Streaming Messages. Expect longer response times when thinking is active, since generating thinking blocks adds processing time. For workloads that push thinking above roughly 32k tokens per request, use batch processing to avoid networking issues: such requests can run long enough to hit system timeouts and open connection limits.
Tune when and how deeply Claude thinks: effort levels, prompt-based steering, cost control, and pricing.
Walk through a complete two-turn tool-use round trip and see what interleaved thinking changes.
Match thinking configuration 400s, empty thinking fields, and cache misses to their causes and fixes.
Control how many tokens Claude spends across text, tool calls, and thinking with the effort parameter.
Was this page helpful?