Home / The Claude API for builders
Moving to Opus 5.5 without breaking your code
Moving from Claude Opus 5 to Claude Opus 5.5 is not just a matter of changing the identifier: four old settings now return a 400 error, and the notes written between two tool calls arrive empty until the code sets thinking.display.
Claude Opus 5.5, announced on 22 September 2026, is called claude-opus-5-5 in the API. The official page on what is new lists four breaking changes for code already running on Claude Opus 5, and a fifth change that makes no request fail but alters the shape of the response. Code that only changes the identifier is exposed to all five.
Four requests the API refuses
- Thinking can no longer be switched off. A
thinkingfield of typedisabled, like a manual budget of typeenabledwithbudget_tokens, returns a 400 error. The field is omitted, or takes the typeadaptive, and depth is set withoutput_config.effort. - Tool forcing disappears. A
tool_choiceof typeanyortoolreturns a 400 error, including on the endpoint that counts tokens. What remains isauto, the default, andnone. - A thinking block is tied to its model and to the conversation: on accounts created from 31 August 2026, replaying it after a change to the system prompt, the tools or an earlier message returns a 400 error.
- On the Claude API and Google Cloud, the
computer_20251124tool is refused in favour of thecomputer_toolset_20260801toolset.
To replace forcing, the documentation advises keeping auto and setting strict: true on the tool. This setting constrains the arguments: when Claude calls the tool, its input respects the declared schema. It does not decide that the call will happen. For that, the message says in so many words when the tool applies. The schema must be complete, and each object in it carries additionalProperties: false. Here is a request accepted by Claude Opus 5 and refused by Claude Opus 5.5:
{
"model": "claude-opus-5",
"max_tokens": 1024,
"thinking": { "type": "disabled" },
"tools": [{
"name": "find_customer",
"description": "Retrieves a customer record from their number",
"input_schema": {
"type": "object",
"properties": {
"number": { "type": "string" }
},
"required": ["number"],
"additionalProperties": false
}
}],
"tool_choice": { "type": "tool", "name": "find_customer" },
"messages": [{ "role": "user", "content": "Find the record for customer 4021" }]
}
The same request corrected for Claude Opus 5.5:
{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"output_config": { "effort": "low" },
"tools": [{
"name": "find_customer",
"description": "Retrieves a customer record from their number",
"input_schema": {
"type": "object",
"properties": {
"number": { "type": "string" }
},
"required": ["number"],
"additionalProperties": false
},
"strict": true
}],
"tool_choice": { "type": "auto" },
"messages": [{ "role": "user", "content": "Find the record for customer 4021. Use the find_customer tool." }]
}
The change that returns no error
Between two tool calls, Claude Opus 5 wrote short notes in blocks of type text. Claude Opus 5.5 puts them in blocks of type thinking, and with the default setting, display: "omitted", their thinking field arrives empty. An interface that used to display these notes goes quiet, without the slightest error. Sorting blocks by their type field avoids mistaking a thinking block for the answer, but does not return the text: you also need to set thinking.display. The value "updates", in beta under the thinking-display-updates-2026-08-18 header, returns the notes alone; "summarized" mixes in the full summary of the reasoning, with no way to tell the two apart.
# request: "thinking": {"type": "adaptive", "display": "updates"}, beta header thinking-display-updates-2026-08-18
for block in response.content:
if block.type == "thinking" and block.thinking:
show(block.thinking) # note written between two tool calls
elif block.type == "text":
show(block.text)
This sorting is only for display. In a tool loop, the assistant's message is sent back as is, thinking blocks included, even empty ones: the API rejects a block that has been modified, moved or removed.
The effort applied when the field is missing drops one notch, as the table shows. The per-token price goes down, as the figure puts it, but always-on thinking is billed in output tokens even when its text is not returned: the trade-off in the lesson on choosing a model has to be recalculated at the chosen effort. The tool declaration from the lesson on tools is the first thing affected, and an instruction written for the old behaviour ages, as the lesson on instructions that age shows.
What changes between Claude Opus 5 and Claude Opus 5.5, identifier replaced alone
| Setting or behaviour | On Claude Opus 5 | On Claude Opus 5.5 |
|---|---|---|
| Thinking disabled, thinking of type disabled | Accepted at effort high or below | Refused, 400 error |
| Forced tool, tool_choice of type tool or any | Accepted | Refused, 400 error |
| computer_20251124 tool on the Claude API and Google Cloud | Accepted with the dedicated beta header | Refused, 400 error |
| Effort applied when the field is omitted | high | medium |
| Notes written between two tool calls | Blocks of type text | Blocks of type thinking, empty at the default display setting |
The price of Claude Opus 5.5 per million tokens
A team migrates its integration from claude-opus-5 to claude-opus-5-5 by changing the model identifier in its code. This code walks through the blocks of each response, keeps those whose type field is text and displays their content. After the migration, the area of the interface that used to display the model's notes between two tool calls stays empty throughout the task, and every call returns a success code.
Write in one sentence what this situation establishes, and in one sentence what it does not establish.
What this establishes: The change of identifier altered what this code finds to display between two tool calls, without any request error signalling this change.
What this does not establish: It does not establish that the model stopped writing these notes, since the code discards blocks of type thinking and the situation says nothing about the display setting sent.
The three most common miscalibrations
- Too broad The model stopped producing notes between two tool calls, and the interface faithfully shows what it now returns.
- Too narrow The empty area may come from a passing display glitch, and the migration stays out of the picture until the trial has been repeated.
- Beside the point The success code returned on each call shows that the declared tools respect the schema required by strict use.
- A manual thinking budget, type enabled with budget_tokens, is refused just like switching thinking off: effort becomes the only lever for depth.
- The strict: true setting guarantees the shape of a called tool's arguments, and it is the message that must say when to call it.
- Sorting blocks by type protects the reading of the response, and it is the thinking.display setting that makes the notes written between two tool calls readable.
- Thinking blocks are sent back intact in a tool loop, including those whose text is empty.
- The official migration guide lists each change by starting model, and its list for Claude Opus 5 fits in a single group.
Open the code that calls the Claude API and look in it for the three patterns that cause a 400 error: thinking of type disabled or enabled, tool_choice of type any or tool, a tool of type computer_20251124. Fix each one according to the official migration guide. Then look, separately, for any reading of the response by position such as content[0].text: this pattern returns no error, it silently breaks the display. If your interface displays the notes written between two tool calls, set thinking.display to updates with the beta header thinking-display-updates-2026-08-18, and display the non-empty thinking blocks.
Every datable claim in this lesson links here to the public text behind it. A source that does not open proves nothing.
- Anthropic, what is new in Claude Opus 5.5, consulted on 2026-09-28 consultée le 2026-09-28
- Anthropic, migration guide to Claude Opus 5.5, consulted on 2026-09-28 consultée le 2026-09-28
- Anthropic, strict tool use, consulted on 2026-09-28 consultée le 2026-09-28
- Anthropic, release notes, entry of 22 September 2026 consultée le 2026-09-28