Stream answers

Show an answer as the model writes it, and know how many units it used.

With stream set to true, the answer arrives as the model writes it, as server-sent events. Your app can show words as they come instead of waiting for the whole answer.

Stream with an SDK

Ask for usage too, so the last event says what the call used.

const stream = await client.chat.completions.create({
  model: "openai/gpt-oss-120b",
  messages: [
    { role: "user", content: "Write a short poem about the ocean." },
  ],
  stream: true,
  stream_options: { include_usage: true },
})

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "")
  if (chunk.usage) console.log(`\n${chunk.usage.units} AI units`)
}

What arrives

  • Each event is a line starting data: with one chunk of the answer, then a blank line.
  • A chunk's delta.content is the next piece of the answer. A reasoning model's thinking arrives first, in delta.reasoning, so you can show it apart or leave it out.
  • The chunk that ends the answer has finish_reason: tool_calls when the model wants a tool.
  • A line starting with : is a keep-alive comment, sent every 15 seconds while the model is thinking. Skip it; the SDKs do.
  • With include_usage, the last chunk has no choices and holds usage, with units.
  • The stream ends with data: [DONE].

When a stream fails

Once a stream has started, its status is already 200. If it fails partway, the last event is data: followed by an error in the same shape as any other, all on one line, and the stream ends without [DONE]. Here is that error, spread out to read:

{
  "error": {
    "message": "A service this request depends on is unavailable, try again shortly.",
    "type": "model_unavailable",
    "code": "model_unavailable",
    "param": null
  },
  "requestId": "01m3c081dbf3j55x7hsa7wc1yj"
}

The SDKs raise it as an error. What the model wrote before it stopped still counts toward your units.

When your app stops reading

If your app closes the connection, the model stops too, and only what it wrote until then counts.

Last updated