DocsGuidesStreaming

Streaming

SSE event formats in all three dialects, plus parsing tips.

All three dialects support streaming over Server-Sent Events (SSE): deltas are pushed as the model generates, so you don't wait for the full response. Event formats differ per dialect and match the official APIs.

OpenAI format (Responses)

Set "stream": true in the request body. Events carry a type field such as response.created, response.output_text.delta, response.completed:

python
stream = client.responses.create(
    model="claude-fable-5",
    input="Tell me a story",
    stream=True,
)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

Anthropic format (Messages)

Also "stream": true, but events use SSE named events (event: + data: lines): message_startcontent_block_start → repeated content_block_deltacontent_block_stopmessage_deltamessage_stop.

SSE
event: message_start
data: {"type":"message_start","message":{...}}

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

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

Gemini format

Call the :streamGenerateContent action with ?alt=sse; each data: line is a GenerateContentResponse fragment with delta text in candidates[].content.parts[].text. Without alt=sse, you get one complete JSON array (non-streaming).

stream.sh
curl "https://api.soleapi.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse" \
  -H "x-goog-api-key: $SOLEAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents": [{"parts": [{"text": "Tell me a story"}]}]}'

Parsing tips

  • SSE events are delimited by blank lines, but TCP segmentation can split one event across reads — buffer input and parse only complete frames. This is the most common pitfall in hand-written parsers.
  • For long generations, raise your read timeout to 5+ minutes so reasoning models with long silent stretches aren't cut off client-side.
  • Treat reconnects as new requests (streams cannot resume mid-way), and consider falling back to a non-streaming call.
  • When rendering UI, batch deltas with throttling so each tiny delta doesn't trigger a separate repaint.
  • Token usage for streamed requests arrives in the final event; billing settles when the stream ends.