Skip to content
Good MorningDocs
Dashboard

Streaming

GM forwards the streaming format native to each compatibility surface.

Set stream: true in the request body. Consume the stream with the normal SDK iterator or parse Server-Sent Events when using HTTP directly.

stream = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Say gm."}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)

Use the streaming action and explicitly request SSE:

POST /v1beta/models/{model}:streamGenerateContent?alt=sse

The settled cost and cost_nano_usd fields (costNanoUsd on Gemini) ride the stream’s final usage-bearing event, in the same location the non-streaming response would carry them:

  • OpenAI Chat Completions: a final chunk with "choices": [] carries the cumulative usage plus the cost fields, delivered ahead of data: [DONE] for every request, whether or not stream_options.include_usage was set.
  • OpenAI Responses: the response.completed (or response.incomplete) event’s response.usage carries the fields.
  • Anthropic: the final message_delta — which already carries cumulative usage — carries the cost fields, immediately ahead of message_stop.
  • Gemini: the terminal chunk’s usageMetadata carries the camelCase cost fields.

A stream that ends in an error, timeout, or truncation bills zero and carries no cost fields; on the Anthropic surface, message_delta itself is withheld after a provider error terminal. See per-request cost for what the figure means.

  • Set application-level timeouts long enough for the first token and full response.
  • Do not assume every network chunk contains one complete event.
  • Stop reading when the surface’s normal terminal event arrives.
  • If the connection breaks after output has started, retrying may create a second billable request.