Skip to content

Streaming API replies in every format

How to receive a reply as it is written in each format, Chat Completions, Responses, Messages and Gemini, with usage, errors mid-stream and tips.

Updated October 2, 2026
On this page

With streaming, the reply arrives in parts as the model writes it, so your user sees text at once instead of waiting for the whole reply. Every format supports it, through Server-Sent Events: lines that start with data:, sometimes after an event: line.

Turn it on#

  • Chat Completions, Responses and Messages: add "stream": true to the body.
  • Gemini: call :streamGenerateContent?alt=sse instead of :generateContent.

With cURL, add -N so the parts print as they arrive. In Python with requests, pass stream=True and read the lines with iter_lines. The official libraries handle all of this for you.

curl --request POST "https://api.5abeer.ai/v1/chat/completions" \
  --header "Authorization: Bearer $KHABEER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"model":"claude-sonnet-5.5","messages":[{"role":"user","content":"Write a product idea in one sentence."}]}'
Response
{
  "id": "chatcmpl-9f2",
  "object": "chat.completion",
  "model": "claude-sonnet-5.5",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello! How can I help you today?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 21,
    "completion_tokens": 12,
    "total_tokens": 33
  }
}

The key is read from KHABEER_API_KEY, so it never appears in your code.

What arrives in each format#

  • Chat Completions: data: lines, each a chat.completion.chunk with text in choices[0].delta.content. It ends with data: [DONE].
  • Responses: named events, response.created, then response.output_text.delta and the function call events. It ends with response.completed, which holds the full reply.
  • Messages: message_start, then for each block content_block_start, content_block_delta and content_block_stop, then message_delta. It ends with message_stop.
  • Gemini: each event is a partial reply in the same shape as the full one. The last event carries finishReason and usageMetadata.

Full examples of each stream are in the references: Chat Completions, Responses, Messages and Gemini.

Usage numbers#

  • Chat Completions: add "stream_options": {"include_usage": true} and the last part before [DONE] carries usage, with an empty choices. GPT models always send it, even without the option.
  • Responses: usage is in response.completed.
  • Messages: the input usage is in message_start, the output usage in message_delta.
  • Gemini: usageMetadata is in the last event.

Errors mid-stream#

An error before the stream starts arrives as a normal JSON response with its HTTP status. Once the stream has started, the status is already 200, so the error arrives inside the stream:

  • Chat Completions and Gemini: a data: line with an error object.
  • Responses: a response.failed event.
  • Messages: an error event.

Each one carries the same code as a normal error; see Limits and error codes. Show the user what was written so far, and offer to try again.

Tips#

  • Read the stream line by line and ignore empty lines and event: lines you don't use.
  • Keep your timeouts generous: a long answer can stream for several minutes.
  • Don't parse partial JSON from a tool call until its block ends; join the arguments or input_json_delta parts first.