> ## Documentation Index
> Fetch the complete documentation index at: https://docs.naga.ac/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming

> Stream OpenAI-compatible chat completion chunks.

Set `stream: true` to receive `chat.completion.chunk` payloads over SSE.

Use this when your client already expects chat chunks and incremental deltas rather than Responses-style semantic events.

## Request

Use `stream_options.include_usage` when you want the final usage trailer.

<CodeGroup>
  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      base_url="https://api.naga.ac/v1",
      api_key="YOUR_API_KEY",
  )

  stream = client.chat.completions.create(
      model="gpt-5",
      messages=[
          {"role": "user", "content": "Explain retries in one paragraph."}
      ],
      stream=True,
      stream_options={"include_usage": True},
  )

  for chunk in stream:
      if chunk.choices and chunk.choices[0].delta.content:
          print(chunk.choices[0].delta.content, end="", flush=True)
  ```

  ```javascript Node.js theme={null}
  import OpenAI from 'openai';

  const client = new OpenAI({
    baseURL: 'https://api.naga.ac/v1',
    apiKey: 'YOUR_API_KEY',
  });

  const stream = await client.chat.completions.create({
    model: 'gpt-5',
    messages: [
      { role: 'user', content: 'Explain retries in one paragraph.' },
    ],
    stream: true,
    stream_options: { include_usage: true },
  });

  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content || '');
  }
  ```

  ```bash cURL theme={null}
  curl -N https://api.naga.ac/v1/chat/completions \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-5",
      "messages": [
        {
          "role": "user",
          "content": "Explain retries in one paragraph."
        }
      ],
      "stream": true,
      "stream_options": {
        "include_usage": true
      }
    }'
  ```
</CodeGroup>

## Chunk Shape

The first chunk usually establishes the assistant role:

```json theme={null}
{
  "id": "resp_1",
  "object": "chat.completion.chunk",
  "created": 1,
  "model": "gpt-5",
  "choices": [
    {
      "index": 0,
      "delta": {
        "role": "assistant"
      },
      "finish_reason": null
    }
  ]
}
```

Text then streams in `choices[0].delta.content`.

## What to listen for

* `choices[0].delta.role` for the initial assistant role
* `choices[0].delta.content` for text deltas
* `choices[0].delta.tool_calls` for tool-call deltas
* `finish_reason` on the terminal chunk

## Tool Call Deltas

Tool calls stream through `choices[0].delta.tool_calls`.

```json theme={null}
{
  "choices": [
    {
      "index": 0,
      "delta": {
        "tool_calls": [
          {
            "id": "call_1",
            "type": "function",
            "function": {
              "name": "lookup_weather",
              "arguments": "{\"city\":\"Prague\"}"
            }
          }
        ]
      },
      "finish_reason": null
    }
  ]
}
```

## Final Chunks

When generation finishes, the stream ends with a chunk whose `finish_reason` is set.

If `stream_options.include_usage` is `true`, the stream can then include a usage trailer with empty choices:

```json theme={null}
{
  "choices": [],
  "usage": {
    "prompt_tokens": 5,
    "completion_tokens": 7,
    "total_tokens": 12,
    "completion_tokens_details": {
      "image_tokens": 0
    }
  }
}
```

## Error Behavior

If a failure happens after headers are sent, the stream can end with a payload that contains a top-level `error` object.

## Common mistakes

* assuming all chunks contain text
* forgetting to enable `stream_options.include_usage` when you need final usage data
* treating chat chunks like Responses semantic events

## Related Docs

* [Capability-level Streaming Comparison](/build/streaming)
* [Chat Completions API](/api/chat-completions)
* [Create chat completion](/api-reference/endpoints/chat/completions)
