← Back to daily report

build-with-claude/streaming.md

Changed on 2026-02-05 12:43:36 EST

+29 lines added
-19 lines removed
Visual Diff
# Streaming Messages¶

---¶

When creating a Message, you can set `"stream": true` to incrementally stream the response using [server-sent events](https://developer.mozilla.org/en-US/Web/API/Server-sent%5Fevents/Using%5Fserver-sent%5Fevents) (SSE).¶

## Streaming with SDKs¶

Our [Python](https://github.com/anthropics/anthropic-sdk-python) and [TypeScript](https://github.com/anthropics/anthropic-sdk-typescript) SDKs offer multiple ways of streaming. The Python SDK allows both sync and async streams. See the documentation in each SDK for details.¶

<CodeGroup>¶
```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

with client.messages.stream(¶
max_tokens=1024,¶
messages=[{"role": "user", "content": "Hello"}],¶
model="claude-
sonnetopus-4-56",¶
) as stream:¶
for text in stream.text_stream:¶
print(text, end="", flush=True)¶
```¶

```typescript TypeScript¶
import Anthropic from '@anthropic-ai/sdk';¶

const client = new Anthropic();¶

await client.messages.stream({¶
messages: [{role: 'user', content: "Hello"}],¶
model: 'claude-
sonnetopus-4-56',¶
max_tokens: 1024,¶
}).on('text', (text) => {¶
console.log(text);¶
});¶
```¶
</CodeGroup>¶

## Get the final message without handling events¶

If you don't need to process text as it arrives, the SDKs provide a way to use streaming under the hood while returning the complete `Message` object — identical to what `.create()` returns. This is especially useful for requests with large `max_tokens` values, where the SDKs require streaming to avoid HTTP timeouts.¶

<CodeGroup>¶
```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

with client.messages.stream(¶
max_tokens=128000,¶
messages=[{"role": "user", "content": "Write a detailed analysis..."}],¶
model="claude-opus-4-6",¶
) as stream:¶
message = stream.get_final_message()¶

print(message.content[0].text)¶
```¶

```typescript TypeScript¶
import Anthropic from '@anthropic-ai/sdk';¶

const client = new Anthropic();¶

const stream = client.messages.stream({¶
max_tokens: 128000,¶
messages: [{role: 'user', content: 'Write a detailed analysis...'}],¶
model: 'claude-opus-4-6',¶
});¶

const message = await stream.finalMessage();¶
console.log(message.content[0].text);¶
```¶
</CodeGroup>¶

The `.stream()` call keeps the HTTP connection alive with server-sent events, then `.get_final_message()` (Python) or `.finalMessage()` (TypeScript) accumulates all events and returns the complete `Message` object. No event handling code is needed.¶

## Event types¶

Each server-sent event includes a named event type and associated JSON data. Each event will use an SSE event name (e.g. `event: message_stop`), and include the matching event `type` in its data.¶

Each stream uses the following event flow:¶

1. `message_start`: contains a `Message` object with empty `content`.¶
2. A series of content blocks, each of which have a `content_block_start`, one or more `content_block_delta` events, and a `content_block_stop` event. Each content block will have an `index` that corresponds to its index in the final Message `content` array.¶
3. One or more `message_delta` events, indicating top-level changes to the final `Message` object.¶
4. A final `message_stop` event.¶

<Warning>¶
The token counts shown in the `usage` field of the `message_delta` event are *cumulative*.¶
</Warning>¶

### Ping events¶

Event streams may also include any number of `ping` events.¶

### Error events¶

We may occasionally send [errors](/docs/en/api/errors) in the event stream. For example, during periods of high usage, you may receive an `overloaded_error`, which would normally correspond to an HTTP 529 in a non-streaming context:¶

```json Example error¶
event: error¶
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Overloaded"}}¶
```¶

### Other events¶

In accordance with our [versioning policy](/docs/en/api/versioning), we may add new event types, and your code should handle unknown event types gracefully.¶

## Content block delta types¶

Each `content_block_delta` event contains a `delta` of a type that updates the `content` block at a given `index`.¶

### Text delta¶

A `text` content block delta looks like:¶
```json Text delta¶
event: content_block_delta¶
data: {"type": "content_block_delta","index": 0,"delta": {"type": "text_delta", "text": "ello frien"}}¶
```¶

### Input JSON delta¶

The deltas for `tool_use` content blocks correspond to updates for the `input` field of the block. To support maximum granularity, the deltas are _partial JSON strings_, whereas the final `tool_use.input` is always an _object_.¶

You can accumulate the string deltas and parse the JSON once you receive a `content_block_stop` event, by using a library like [Pydantic](https://docs.pydantic.dev/latest/concepts/json/#partial-json-parsing) to do partial JSON parsing, or by using our [SDKs](/docs/en/api/client-sdks), which provide helpers to access parsed incremental values.¶

A `tool_use` content block delta looks like:¶
```json Input JSON delta¶
event: content_block_delta¶
data: {"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}}¶
```¶
Note: Our current models only support emitting one complete key and value property from `input` at a time. As such, when using tools, there may be delays between streaming events while the model is working. Once an `input` key and value are accumulated, we emit them as multiple `content_block_delta` events with chunked partial json so that the format can automatically support finer granularity in future models.¶

### Thinking delta¶

When using [extended thinking](/docs/en/build-with-claude/extended-thinking#streaming-thinking) with streaming enabled, you'll receive thinking content via `thinking_delta` events. These deltas correspond to the `thinking` field of the `thinking` content blocks.¶

For thinking content, a special `signature_delta` event is sent just before the `content_block_stop` event. This signature is used to verify the integrity of the thinking block.¶

A typical thinking delta looks like:¶
```json Thinking delta¶
event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "
Let me solve this step by step:\n\n1. First break down 27 * 453I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}¶
```¶

The signature delta looks like:¶
```json Signature delta¶
event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}¶
```¶

## Full HTTP Stream response¶

We strongly recommend that you use our [client SDKs](/docs/en/api/client-sdks) when using streaming mode. However, if you are building a direct API integration, you will need to handle these events yourself.¶

A stream response is comprised of:¶
1. A `message_start` event¶
2. Potentially multiple content blocks, each of which contains:¶
- A `content_block_start` event¶
- Potentially multiple `content_block_delta` events¶
- A `content_block_stop` event¶
3. A `message_delta` event¶
4. A `message_stop` event¶

There may be `ping` events dispersed throughout the response as well. See [Event types](#event-types) for more details on the format.¶

### Basic streaming request¶

<CodeGroup>¶
```bash Shell¶
curl https://api.anthropic.com/v1/messages \¶
--header "anthropic-version: 2023-06-01" \¶
--header "content-type: application/json" \¶
--header "x-api-key: $ANTHROPIC_API_KEY" \¶
--data \¶
'{¶
"model": "claude-
sonnetopus-4-56",¶
"messages": [{"role": "user", "content": "Hello"}],¶
"max_tokens": 256,¶
"stream": true¶
}'¶
```¶

```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

with client.messages.stream(¶
model="claude-
sonnetopus-4-56",¶
messages=[{"role": "user", "content": "Hello"}],¶
max_tokens=256,¶
) as stream:¶
for text in stream.text_stream:¶
print(text, end="", flush=True)¶
```¶
</CodeGroup>¶

```json Response¶
event: message_start¶
data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-
sonnet-4-5-20250929opus-4-6", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}¶

event: content_block_start¶
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}¶

event: ping¶
data: {"type": "ping"}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "Hello"}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "!"}}¶

event: content_block_stop¶
data: {"type": "content_block_stop", "index": 0}¶

event: message_delta¶
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence":null}, "usage": {"output_tokens": 15}}¶

event: message_stop¶
data: {"type": "message_stop"}¶

```¶

### Streaming request with tool use¶

<Tip>¶
Tool use
now supports [fine-grained streaming for parameter values as a beta feature. For more details, see [Fine-grained tool streaming](/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming) for parameter values. Enable it per tool with `eager_input_streaming`.¶
</Tip>¶

In this request, we ask Claude to use a tool to tell us the weather.¶

<CodeGroup>¶
```bash Shell¶
curl https://api.anthropic.com/v1/messages \¶
-H "content-type: application/json" \¶
-H "x-api-key: $ANTHROPIC_API_KEY" \¶
-H "anthropic-version: 2023-06-01" \¶
-d '{¶
"model": "claude-
sonnetopus-4-56",¶
"max_tokens": 1024,¶
"tools": [¶
{¶
"name": "get_weather",¶
"description": "Get the current weather in a given location",¶
"input_schema": {¶
"type": "object",¶
"properties": {¶
"location": {¶
"type": "string",¶
"description": "The city and state, e.g. San Francisco, CA"¶
}¶
},¶
"required": ["location"]¶
}¶
}¶
],¶
"tool_choice": {"type": "any"},¶
"messages": [¶
{¶
"role": "user",¶
"content": "What is the weather like in San Francisco?"¶
}¶
],¶
"stream": true¶
}'¶
```¶

```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

tools = [¶
{¶
"name": "get_weather",¶
"description": "Get the current weather in a given location",¶
"input_schema": {¶
"type": "object",¶
"properties": {¶
"location": {¶
"type": "string",¶
"description": "The city and state, e.g. San Francisco, CA"¶
}¶
},¶
"required": ["location"]¶
}¶
}¶
]¶

with client.messages.stream(¶
model="claude-
sonnetopus-4-56",¶
max_tokens=1024,¶
tools=tools,¶
tool_choice={"type": "any"},¶
messages=[¶
{¶
"role": "user",¶
"content": "What is the weather like in San Francisco?"¶
}¶
],¶
) as stream:¶
for text in stream.text_stream:¶
print(text, end="", flush=True)¶
```¶
</CodeGroup>¶

```json Response¶
event: message_start¶
data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-
sonnet-4-5-20250929opus-4-6","stop_sequence":null,"usage":{"input_tokens":472,"output_tokens":2},"content":[],"stop_reason":null}}¶

event: content_block_start¶
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}¶

event: ping¶
data: {"type": "ping"}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Okay"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" let"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'s"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" check"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" weather"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" San"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Francisco"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" CA"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":":"}}¶

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":"tool_use","id":"toolu_01T1x1fJ34qAmk2tNTrN7Up6","name":"get_weather","input":{}}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"location\":"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" \"San"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" Francisc"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"o,"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" CA\""}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":", "}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"unit\": \"fah"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"renheit\"}"}}¶

event: content_block_stop¶
data: {"type":"content_block_stop","index":1}¶

event: message_delta¶
data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":89}}¶

event: message_stop¶
data: {"type":"message_stop"}¶
```¶

### Streaming request with extended thinking¶

In this request, we enable extended thinking with streaming to see Claude's step-by-step reasoning.¶

<CodeGroup>¶
```bash Shell¶
curl https://api.anthropic.com/v1/messages \¶
--header "x-api-key: $ANTHROPIC_API_KEY" \¶
--header "anthropic-version: 2023-06-01" \¶
--header "content-type: application/json" \¶
--data \¶
'{¶
"model": "claude-
sonnetopus-4-56",¶
"max_tokens": 20000,¶
"stream": true,¶
"thinking": {¶
"type": "enabled",¶
"budget_tokens": 16000¶
},¶
"messages": [¶
{¶
"role": "user",¶
"content": "What is
27 * 453the greatest common divisor of 1071 and 462?"¶
}¶
]¶
}'¶
```¶

```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

with client.messages.stream(¶
model="claude-
sonnetopus-4-56",¶
max_tokens=20000,¶
thinking={¶
"type": "enabled",¶
"budget_tokens": 16000¶
},¶
messages=[¶
{¶
"role": "user",¶
"content": "What is
27 * 453the greatest common divisor of 1071 and 462?"¶
}¶
],¶
) as stream:¶
for event in stream:¶
if 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)¶
```¶
</CodeGroup>¶

```json Response¶
event: message_start¶
data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-
sonnet-4-5-20250929opus-4-6", "stop_reason": null, "stop_sequence": null}}¶

event: content_block_start¶
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "thinking", "thinking": ""}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "
Let me solve this step by step:\n\n1. First break down 27 * 453"}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n2. 453 = 400 + 50 + 3
I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n
3. 27 * 400 = 10,800462 = 3 × 147 + 21"}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n
4. 27 * 50 = 1,35147 = 7 × 21 + 0"}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n
5. 27 * 3 = 81"}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n6. 10,800 + 1,350 + 81 = 12,231
The remainder is 0, so GCD(1071, 462) = 21."}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}¶

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": ""}}¶

event: content_block_delta¶
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "text_delta", "text": "
27 * 453 = 12,231The greatest common divisor of 1071 and 462 is **21**."}}¶

event: content_block_stop¶
data: {"type": "content_block_stop", "index": 1}¶

event: message_delta¶
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence": null}}¶

event: message_stop¶
data: {"type": "message_stop"}¶
```¶

### Streaming request with web search tool use¶

In this request, we ask Claude to search the web for current weather information.¶

<CodeGroup>¶
```bash Shell¶
curl https://api.anthropic.com/v1/messages \¶
--header "x-api-key: $ANTHROPIC_API_KEY" \¶
--header "anthropic-version: 2023-06-01" \¶
--header "content-type: application/json" \¶
--data \¶
'{¶
"model": "claude-
sonnetopus-4-56",¶
"max_tokens": 1024,¶
"stream": true,¶
"tools": [¶
{¶
"type": "web_search_20250305",¶
"name": "web_search",¶
"max_uses": 5¶
}¶
],¶
"messages": [¶
{¶
"role": "user",¶
"content": "What is the weather like in New York City today?"¶
}¶
]¶
}'¶
```¶

```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

with client.messages.stream(¶
model="claude-
sonnetopus-4-56",¶
max_tokens=1024,¶
tools=[¶
{¶
"type": "web_search_20250305",¶
"name": "web_search",¶
"max_uses": 5¶
}¶
],¶
messages=[¶
{¶
"role": "user",¶
"content": "What is the weather like in New York City today?"¶
}¶
],¶
) as stream:¶
for text in stream.text_stream:¶
print(text, end="", flush=True)¶
```¶
</CodeGroup>¶

```json Response¶
event: message_start¶
data: {"type":"message_start","message":{"id":"msg_01G...","type":"message","role":"assistant","model":"claude-
sonnet-4-5-20250929opus-4-6","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":2679,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":3}}}¶

event: content_block_start¶
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll check"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the current weather in New York City for you"}}¶

event: ping¶
data: {"type": "ping"}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"."}}¶

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":"server_tool_use","id":"srvtoolu_014hJH82Qum7Td6UV8gDXThB","name":"web_search","input":{}}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"query"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\":"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" \"weather"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" NY"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"C to"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"day\"}"}}¶

event: content_block_stop¶
data: {"type":"content_block_stop","index":1 }¶

event: content_block_start¶
data: {"type":"content_block_start","index":2,"content_block":{"type":"web_search_tool_result","tool_use_id":"srvtoolu_014hJH82Qum7Td6UV8gDXThB","content":[{"type":"web_search_result","title":"Weather in New York City in May 2025 (New York) - detailed Weather Forecast for a month","url":"https://world-weather.info/forecast/usa/new_york/may-2025/","encrypted_content":"Ev0DCioIAxgCIiQ3NmU4ZmI4OC1k...","page_age":null},...]}}¶

event: content_block_stop¶
data: {"type":"content_block_stop","index":2}¶

event: content_block_start¶
data: {"type":"content_block_start","index":3,"content_block":{"type":"text","text":""}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":"Here's the current weather information for New York"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":" City:\n\n# Weather"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":" in New York City"}}¶

event: content_block_delta¶
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":"\n\n"}}¶

...¶

event: content_block_stop¶
data: {"type":"content_block_stop","index":17}¶

event: message_delta¶
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":10682,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":510,"server_tool_use":{"web_search_requests":1}}}¶

event: message_stop¶
data: {"type":"message_stop"}¶
```¶

## Error recovery¶

When a streaming request is interrupted due to network issues, timeouts, or other errors, you can recover by resuming from where the stream was interrupted. This approach saves you from re-processing the entire response.¶

The basic recovery strategy involves:¶

1. **Capture the partial response**: Save all content that was successfully received before the error occurred¶
2. **Construct a continuation request**: Create a new API request that includes the partial assistant response as the beginning of a new assistant message¶
3. **Resume streaming**: Continue receiving the rest of the response from where it was interrupted¶

### Error recovery best practices¶

1. **Use SDK features**: Leverage the SDK's built-in message accumulation and error handling capabilities¶
2. **Handle content types**: Be aware that messages can contain multiple content blocks (`text`, `tool_use`, `thinking`). Tool use and extended thinking blocks cannot be partially recovered. You can resume streaming from the most recent text block.

Unified Diff

--- a/build-with-claude/streaming.md
+++ b/build-with-claude/streaming.md
@@ -17,7 +17,7 @@
     with client.messages.stream(
         max_tokens=1024,
         messages=[{"role": "user", "content": "Hello"}],
-        model="claude-sonnet-4-5",
+        model="claude-opus-4-6",
     ) as stream:
       for text in stream.text_stream:
           print(text, end="", flush=True)
@@ -30,7 +30,7 @@
 
     await client.messages.stream({
         messages: [{role: 'user', content: "Hello"}],
-        model: 'claude-sonnet-4-5',
+        model: 'claude-opus-4-6',
         max_tokens: 1024,
     }).on('text', (text) => {
         console.log(text);
@@ -38,6 +38,44 @@
     ```
 </CodeGroup>
 
+## Get the final message without handling events
+
+If you don't need to process text as it arrives, the SDKs provide a way to use streaming under the hood while returning the complete `Message` object — identical to what `.create()` returns. This is especially useful for requests with large `max_tokens` values, where the SDKs require streaming to avoid HTTP timeouts.
+
+<CodeGroup>
+    ```python Python
+    import anthropic
+
+    client = anthropic.Anthropic()
+
+    with client.messages.stream(
+        max_tokens=128000,
+        messages=[{"role": "user", "content": "Write a detailed analysis..."}],
+        model="claude-opus-4-6",
+    ) as stream:
+        message = stream.get_final_message()
+
+    print(message.content[0].text)
+    ```
+
+    ```typescript TypeScript
+    import Anthropic from '@anthropic-ai/sdk';
+
+    const client = new Anthropic();
+
+    const stream = client.messages.stream({
+        max_tokens: 128000,
+        messages: [{role: 'user', content: 'Write a detailed analysis...'}],
+        model: 'claude-opus-4-6',
+    });
+
+    const message = await stream.finalMessage();
+    console.log(message.content[0].text);
+    ```
+</CodeGroup>
+
+The `.stream()` call keeps the HTTP connection alive with server-sent events, then `.get_final_message()` (Python) or `.finalMessage()` (TypeScript) accumulates all events and returns the complete `Message` object. No event handling code is needed.
+
 ## Event types
 
 Each server-sent event includes a named event type and associated JSON data. Each event will use an SSE event name (e.g. `event: message_stop`), and include the matching event `type` in its data.
@@ -104,7 +142,7 @@
 A typical thinking delta looks like:
 ```json Thinking delta
 event: content_block_delta
-data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "Let me solve this step by step:\n\n1. First break down 27 * 453"}}
+data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}
 ```
 
 The signature delta looks like:
@@ -138,7 +176,7 @@
      --header "x-api-key: $ANTHROPIC_API_KEY" \
      --data \
 '{
-  "model": "claude-sonnet-4-5",
+  "model": "claude-opus-4-6",
   "messages": [{"role": "user", "content": "Hello"}],
   "max_tokens": 256,
   "stream": true
@@ -151,7 +189,7 @@
 client = anthropic.Anthropic()
 
 with client.messages.stream(
-    model="claude-sonnet-4-5",
+    model="claude-opus-4-6",
     messages=[{"role": "user", "content": "Hello"}],
     max_tokens=256,
 ) as stream:
@@ -162,7 +200,7 @@
 
 ```json Response
 event: message_start
-data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-sonnet-4-5-20250929", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}
+data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-4-6", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}
 
 event: content_block_start
 data: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}
@@ -190,7 +228,7 @@
 ### Streaming request with tool use
 
 <Tip>
-Tool use now supports fine-grained streaming for parameter values as a beta feature. For more details, see [Fine-grained tool streaming](/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming).
+Tool use supports [fine-grained streaming](/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming) for parameter values. Enable it per tool with `eager_input_streaming`.
 </Tip>
 
 In this request, we ask Claude to use a tool to tell us the weather.
@@ -202,7 +240,7 @@
     -H "x-api-key: $ANTHROPIC_API_KEY" \
     -H "anthropic-version: 2023-06-01" \
     -d '{
-      "model": "claude-sonnet-4-5",
+      "model": "claude-opus-4-6",
       "max_tokens": 1024,
       "tools": [
         {
@@ -254,7 +292,7 @@
 ]
 
 with client.messages.stream(
-    model="claude-sonnet-4-5",
+    model="claude-opus-4-6",
     max_tokens=1024,
     tools=tools,
     tool_choice={"type": "any"},
@@ -272,7 +310,7 @@
 
 ```json Response
 event: message_start
-data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-sonnet-4-5-20250929","stop_sequence":null,"usage":{"input_tokens":472,"output_tokens":2},"content":[],"stop_reason":null}}
+data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-opus-4-6","stop_sequence":null,"usage":{"input_tokens":472,"output_tokens":2},"content":[],"stop_reason":null}}
 
 event: content_block_start
 data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
@@ -374,7 +412,7 @@
      --header "content-type: application/json" \
      --data \
 '{
-    "model": "claude-sonnet-4-5",
+    "model": "claude-opus-4-6",
     "max_tokens": 20000,
     "stream": true,
     "thinking": {
@@ -384,7 +422,7 @@
     "messages": [
         {
             "role": "user",
-            "content": "What is 27 * 453?"
+            "content": "What is the greatest common divisor of 1071 and 462?"
         }
     ]
 }'
@@ -396,7 +434,7 @@
 client = anthropic.Anthropic()
 
 with client.messages.stream(
-    model="claude-sonnet-4-5",
+    model="claude-opus-4-6",
     max_tokens=20000,
     thinking={
         "type": "enabled",
@@ -405,7 +443,7 @@
     messages=[
         {
             "role": "user",
-            "content": "What is 27 * 453?"
+            "content": "What is the greatest common divisor of 1071 and 462?"
         }
     ],
 ) as stream:
@@ -420,28 +458,22 @@
 
 ```json Response
 event: message_start
-data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-sonnet-4-5-20250929", "stop_reason": null, "stop_sequence": null}}
+data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-4-6", "stop_reason": null, "stop_sequence": null}}
 
 event: content_block_start
 data: {"type": "content_block_start", "index": 0, "content_block": {"type": "thinking", "thinking": ""}}
 
 event: content_block_delta
-data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "Let me solve this step by step:\n\n1. First break down 27 * 453"}}
-
-event: content_block_delta
-data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n2. 453 = 400 + 50 + 3"}}
-
-event: content_block_delta
-data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n3. 27 * 400 = 10,800"}}
-
-event: content_block_delta
-data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n4. 27 * 50 = 1,350"}}
-
-event: content_block_delta
-data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n5. 27 * 3 = 81"}}
-
-event: content_block_delta
-data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n6. 10,800 + 1,350 + 81 = 12,231"}}
+data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}
+
+event: content_block_delta
+data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n462 = 3 × 147 + 21"}}
+
+event: content_block_delta
+data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n147 = 7 × 21 + 0"}}
+
+event: content_block_delta
+data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\nThe remainder is 0, so GCD(1071, 462) = 21."}}
 
 event: content_block_delta
 data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}
@@ -453,7 +485,7 @@
 data: {"type": "content_block_start", "index": 1, "content_block": {"type": "text", "text": ""}}
 
 event: content_block_delta
-data: {"type": "content_block_delta", "index": 1, "delta": {"type": "text_delta", "text": "27 * 453 = 12,231"}}
+data: {"type": "content_block_delta", "index": 1, "delta": {"type": "text_delta", "text": "The greatest common divisor of 1071 and 462 is **21**."}}
 
 event: content_block_stop
 data: {"type": "content_block_stop", "index": 1}
@@ -477,7 +509,7 @@
      --header "content-type: application/json" \
      --data \
 '{
-    "model": "claude-sonnet-4-5",
+    "model": "claude-opus-4-6",
     "max_tokens": 1024,
     "stream": true,
     "tools": [
@@ -502,7 +534,7 @@
 client = anthropic.Anthropic()
 
 with client.messages.stream(
-    model="claude-sonnet-4-5",
+    model="claude-opus-4-6",
     max_tokens=1024,
     tools=[
         {
@@ -525,7 +557,7 @@
 
 ```json Response
 event: message_start
-data: {"type":"message_start","message":{"id":"msg_01G...","type":"message","role":"assistant","model":"claude-sonnet-4-5-20250929","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":2679,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":3}}}
+data: {"type":"message_start","message":{"id":"msg_01G...","type":"message","role":"assistant","model":"claude-opus-4-6","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":2679,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":3}}}
 
 event: content_block_start
 data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}