migration-guide changedmodels/sonnet-5-5/migration-guide
Nearest release: v2.1.284, published 8 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
## Send a request to Claude Sonnet 5.5 ## Thinking runs by default ### Handle thinking in responses ### Turn off up-front thinking ## Migration checklist by starting model ### Every starting model ### Claude Sonnet 4.6 or earlier ### Claude Sonnet 4.5 or earlier ### Claude Sonnet 4 or earlier ### Claude Haiku 4.5 only ## Migrating to Claude Sonnet 5.5 from Claude Sonnet 5 ### Forced tool use is not supported ### Thinking blocks are tied to the model and the conversation ### Computer use needs the toolset on the Claude API and Google Cloud ### The advisor tool accepts fewer advisors ### Text between tool calls is returned in thinking blocks ### Safety classifiers and fallback ### Other changes ### Recommended changes ## Migrating to Claude Sonnet 5.5 from Claude Sonnet 4.6 and earlier Sonnet models ### Breaking changes ### Other changes ### Migrating from Claude Sonnet 4.5 or earlier ### Migrating from Claude Sonnet 4 or earlier ## Migrating to Claude Sonnet 5.5 from Claude Haiku 4.5
The whole hunk
1252 lines, new pageA whole new page. There's nothing to diff it against, so here is what it says.
---
title: Migrating to Claude Sonnet 5.5
url: https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide
description: "Move code to Claude Sonnet 5.5 from Claude Sonnet 5, Claude Sonnet 4.6, Claude Sonnet 4.5, Claude Sonnet 4, Claude 3.7 Sonnet, or Claude Haiku 4.5: settings that return errors, thinking changes, and a checklist for each starting model."
---
This guide lists the code changes for moving to Claude Sonnet 5.5 from Claude Sonnet 5, Claude Sonnet 4.6, Claude Sonnet 4.5, Claude Sonnet 4, Claude 3.7 Sonnet, or Claude Haiku 4.5. Read the first two sections, then read down to the section for your current model. The [migration checklist](https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#migration-checklist) lists every change by starting model.
<Note>
This guide covers migrating [Messages API](https://platform.claude.com/docs/en/build-with-claude/working-with-messages) code. If you use [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview), no changes beyond updating the model name are required.
</Note>
<Tip>
**Automate your migration with the Claude API skill.** In Claude Code, run `/claude-api migrate` to invoke the bundled [Claude API skill](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/claude-api-skill#migrating-to-a-newer-claude-model). It works for any current Claude model as the target:
```text wrap
/claude-api migrate this project to claude-sonnet-5-5
```
The skill applies the model ID swap and, as needed, breaking parameter changes, prefill replacement, and effort calibration for your target model across your code base, then produces a checklist of items to verify manually. It asks you to confirm the migration scope (entire working directory, a subdirectory, or a specific file list) before editing any files. The skill also detects Amazon Bedrock and Claude Platform on AWS clients and adjusts model ID formats and feature changes for those platforms.
</Tip>
Claude Sonnet 5.5 has the same prices as Claude Sonnet 5. See [Claude pricing](https://platform.claude.com/docs/en/about-claude/pricing). For its context window and output limits, see the [Claude Sonnet 5.5 model page](https://platform.claude.com/docs/en/models/sonnet-5-5/overview). For features and prompting, see [What's new in Claude Sonnet 5.5](https://platform.claude.com/docs/en/models/sonnet-5-5/whats-new-sonnet-5-5#feature-support) and [Prompting Claude Sonnet 5.5](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-sonnet-5-5).
## Send a request to Claude Sonnet 5.5
This request works on Claude Sonnet 5.5 as written. It sets an effort level, and the SDK tabs read the reply by block type. It leaves out five settings that return a 400 error: [thinking budgets](https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#sonnet-46-breaking-changes), [sampling parameters](https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#sonnet-46-breaking-changes), [assistant prefill](https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#migrating-from-sonnet-45), [forced tool choice](https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#forced-tool-use), and [`thinking: {"type": "disabled"}`](https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#turn-off-up-front-thinking).
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5-5",
"max_tokens": 4096,
"messages": [{
"role": "user",
"content": "Analyze the trade-offs between microservices and monolithic architectures"
}],
"output_config": {
"effort": "medium"
}
}'
```
```bash CLI
ant messages create \
--model claude-sonnet-5-5 \
--max-tokens 4096 \
--output-config '{effort: medium}' \
--message '{role: user, content: "Analyze the trade-offs between microservices and monolithic architectures"}'
```
```python Python
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Analyze the trade-offs between microservices and monolithic architectures",
}
],
output_config={"effort": "medium"},
)
print(f"Stop reason: {response.stop_reason}")
for block in response.content:
if block.type == "text":
print(block.text)
```
```typescript TypeScript
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-5-5",
max_tokens: 4096,
messages: [
{
role: "user",
content: "Analyze the trade-offs between microservices and monolithic architectures"
}
],
output_config: {
effort: "medium"
}
});
console.log(`Stop reason: ${response.stop_reason}`);
const textBlock = response.content.find(
(block): block is Anthropic.TextBlock => block.type === "text"
);
console.log(textBlock?.text);
```
```csharp C#
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.ClaudeSonnet5_5,
MaxTokens = 4096,
Messages = [
new() {
Role = Role.User,
Content = "Analyze the trade-offs between microservices and monolithic architectures"
}
],
OutputConfig = new OutputConfig
{
Effort = Effort.Medium
}
};
var message = await client.Messages.Create(parameters);
Console.WriteLine($"Stop reason: {message.StopReason?.Raw()}");
foreach (var block in message.Content)
{
if (block.TryPickText(out var textBlock))
{
Console.WriteLine(textBlock.Text);
}
}
```
```go Go
client := anthropic.NewClient()
response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeSonnet5_5,
MaxTokens: 4096,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Analyze the trade-offs between microservices and monolithic architectures")),
},
OutputConfig: anthropic.OutputConfigParam{
Effort: anthropic.OutputConfigEffortMedium,
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println("Stop reason:", response.StopReason)
for _, block := range response.Content {
if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
fmt.Println(textBlock.Text)
}
}
```
```java Java
import com.anthropic.models.messages.OutputConfig;
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_SONNET_5_5)
.maxTokens(4096L)
.addUserMessage("Analyze the trade-offs between microservices and monolithic architectures")
.outputConfig(OutputConfig.builder()
.effort(OutputConfig.Effort.MEDIUM)
.build())
.build();
Message response = client.messages().create(params);
response.stopReason().ifPresent(reason -> IO.println("Stop reason: " + reason));
response.content().stream()
.flatMap(block -> block.text().stream())
.forEach(textBlock -> IO.println(textBlock.text()));
}
```
```php PHP
$client = new Client();
$message = $client->messages->create(
maxTokens: 4096,
messages: [
['role' => 'user', 'content' => 'Analyze the trade-offs between microservices and monolithic architectures']
],
model: 'claude-sonnet-5-5',
outputConfig: ['effort' => 'medium'],
);
echo "Stop reason: {$message->stopReason}", PHP_EOL;
foreach ($message->content as $block) {
if ($block->type === 'text') {
echo $block->text, PHP_EOL;
}
}
```
```ruby Ruby
client = Anthropic::Client.new
message = client.messages.create(
model: "claude-sonnet-5-5",
max_tokens: 4096,
messages: [
{ role: "user", content: "Analyze the trade-offs between microservices and monolithic architectures" }
],
output_config: {
effort: "medium"
}
)
puts "Stop reason: #{message.stop_reason}"
message.content.each do |block|
puts block.text if block.type == :text
end
```
</CodeGroup>
## Thinking runs by default
On Claude Sonnet 5.5, a request with no `thinking` field runs with [adaptive thinking](https://platform.claude.com/docs/en/build-with-claude/thinking), as does `thinking: {"type": "adaptive"}`. On Claude Sonnet 4.6 and earlier models and on Claude Haiku 4.5, that request ran without thinking. To keep running without up-front thinking, see [Turn off up-front thinking](https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#turn-off-up-front-thinking).
| Model | Thinking without a `thinking` field | `thinking.type` values accepted | Default `display` |
| -------------------------------------- | ----------------------------------- | ---------------------------------------------------- | ----------------- |
| Claude Sonnet 5.5 | On | `"adaptive"`, `"between_tools"` | `"omitted"` |
| Claude Sonnet 5 | On | `"adaptive"`, `"disabled"` | `"omitted"` |
| Claude Sonnet 4.6 | Off | `"adaptive"`, `"disabled"`, `"enabled"` (deprecated) | `"summarized"` |
| Claude Sonnet 4.5 and Claude Haiku 4.5 | Off | `"disabled"`, `"enabled"` | `"summarized"` |
### Handle thinking in responses
Code that ran without thinking needs all three items. Code from Claude Sonnet 5 likely has the first two.
* **Read content blocks by `type`.** A response can begin with `thinking` blocks, so code that reads `content[0].text` breaks.
* **Pass `thinking` blocks back unchanged** in tool-use loops, including empty ones. See [Preserving thinking blocks](https://platform.claude.com/docs/en/build-with-claude/thinking#preserving-thinking-blocks).
* **Revisit `max_tokens`.** It covers thinking plus text, and thinking tokens are billed as output tokens. See [Cost control](https://platform.claude.com/docs/en/build-with-claude/thinking-steering-and-cost#cost-control).
Thinking text is omitted by default. `thinking` blocks arrive with an empty `thinking` field and a `signature`. To get readable summaries, set `display: "summarized"`, the default on Claude Sonnet 4.6 and earlier models and on Claude Haiku 4.5. See [Controlling thinking display](https://platform.claude.com/docs/en/build-with-claude/thinking#controlling-thinking-display).
### Turn off up-front thinking
To turn off up-front thinking on Claude Sonnet 5.5, send `thinking: {"type": "between_tools"}`. It's the lowest thinking setting. Its progress updates between tool calls still come back as `thinking` blocks with their summary text. Without tools, the response contains only text. Claude Sonnet 5 turns thinking off with `thinking: {"type": "disabled"}` instead, and earlier models run without thinking by default. On Claude Sonnet 5.5, `disabled` returns a 400 `invalid_request_error`:
```text wrap
"thinking.type.disabled" is not supported for this model. Use "thinking.type.between_tools" for the lowest thinking setting, or "thinking.type.adaptive" and "output_config.effort" to control thinking behavior.
```
`between_tools` works on every platform that offers Claude Sonnet 5.5, with no beta header. It's accepted at `low`, `medium`, and `high` effort. At `xhigh` or `max`, it returns a 400 error. To run at those levels, use adaptive thinking: omit the `thinking` field or send `thinking: {"type": "adaptive"}`. `between_tools` takes no other field: `display`, `budget_tokens`, or `block_binding` sent with it returns a 400 error. With [server-side fallback](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback#server-side-fallback), a `between_tools` request that falls back to Claude Sonnet 5 runs there with `thinking: {"type": "disabled"}`.
With `between_tools`, effort can't change mid-conversation: a per-message `output_config.effort` that differs from the level in effect returns a 400 error. To vary effort per turn, use adaptive thinking. For prompting guidance, see [Running without up-front thinking](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-sonnet-5-5#running-without-up-front-thinking).
Before (Claude Sonnet 5):
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5",
"max_tokens": 16000,
"thinking": {"type": "disabled"},
"output_config": {"effort": "xhigh"},
"messages": [{"role": "user", "content": "..."}]
}'
```
```bash CLI
ant messages create \
--model claude-sonnet-5 \
--max-tokens 16000 \
--thinking '{type: disabled}' \
--output-config '{effort: xhigh}' \
--message '{role: user, content: "..."}'
```
```python Python
client.messages.create(
model="claude-sonnet-5",
max_tokens=16000,
thinking={"type": "disabled"},
output_config={"effort": "xhigh"},
messages=[{"role": "user", "content": "..."}],
)
```
```typescript TypeScript
await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 16000,
thinking: { type: "disabled" },
output_config: { effort: "xhigh" },
messages: [{ role: "user", content: "..." }]
});
```
```csharp C#
await client.Messages.Create(new MessageCreateParams
{
Cut at 300 lines. The page has the rest.
No line in this hunk matches that.