Skip to content

Messages API streaming

Set "stream": true on POST /v1/messages to receive a standard Anthropic Server-Sent Events stream. Existing Anthropic SDK consumers work unchanged.

Request

Terminal window
curl -N https://api.kindo.ai/v1/messages \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $KINDO_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"max_tokens": 512,
"stream": true,
"messages": [
{ "role": "user", "content": "Write a haiku about observability." }
]
}'

Kindo returns Content-Type: text/event-stream and emits Anthropic’s event sequence verbatim.

Event types

EventMeaning
message_startInitial message metadata.
content_block_startStart of a streamed content block.
content_block_deltaIncremental content chunk.
content_block_stopEnd of a content block.
message_deltaUpdated usage or stop-reason data.
message_stopEnd of the stream.
errorStream interruption after the stream has started.
pingKeepalive heartbeat; safe to ignore.

Example stream

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,"usage":{"input_tokens":12,"output_tokens":1}}}
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":"Logs flow through"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the gate;"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":32}}
event: message_stop
data: {"type":"message_stop"}

SDK consumption

import os
from anthropic import Anthropic
client = Anthropic(base_url="https://api.kindo.ai", api_key=os.environ["KINDO_API_KEY"])
with client.messages.stream(
model="claude-sonnet-4-5-20250929",
max_tokens=512,
messages=[{"role": "user", "content": "Write a haiku."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
baseURL: 'https://api.kindo.ai',
apiKey: process.env.KINDO_API_KEY
});
const stream = await client.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 512,
messages: [{ role: 'user', content: 'Write a haiku.' }]
});
for await (const event of stream) {
if (
event.type === 'content_block_delta' &&
event.delta.type === 'text_delta'
) {
process.stdout.write(event.delta.text);
}
}

Pre-stream errors

If the upstream request fails before streaming begins, Kindo returns a normal HTTP error response with Anthropic’s JSON envelope — no SSE switch. See Errors.

Mid-stream errors

Once the SSE has started, the outer HTTP status is committed at 200. Stream errors arrive as an event: error SSE frame in place of message_stop:

event: error
data: {"type":"error","error":{"type":"overloaded_error","message":"upstream overloaded"}}

Treat any error SSE event as terminal — no message_stop follows and the response will not resume.

See also