> ## 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 semantic Responses API events and reconstruct the final result correctly.

Set `stream: true` to receive semantic Server-Sent Events instead of waiting for one final JSON response.

Use this when you want to render text progressively, react to tool calls early, or inspect structured lifecycle events.

## Enable Streaming

<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.responses.create(
      model="gpt-4.1-mini",
      input="Stream a short explanation of backpressure.",
      stream=True,
  )

  for event in stream:
      if event.type == "response.output_text.delta":
          print(event.delta, end="")
  ```

  ```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.responses.create({
    model: 'gpt-4.1-mini',
    input: 'Stream a short explanation of backpressure.',
    stream: true,
  });

  for await (const event of stream) {
    if (event.type === 'response.output_text.delta') {
      process.stdout.write(event.delta);
    }
  }
  ```

  ```bash cURL theme={null}
  curl -N https://api.naga.ac/v1/responses \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-4.1-mini",
      "input": "Stream a short explanation of backpressure.",
      "stream": true
    }'
  ```
</CodeGroup>

## Event Lifecycle

Per the protocol tests, a normal text stream looks like this:

```text theme={null}
event: response.created
data: {"type":"response.created", ...}

event: response.in_progress
data: {"type":"response.in_progress", ...}

event: response.output_text.delta
data: {"type":"response.output_text.delta","delta":"Hel"}

event: response.output_text.delta
data: {"type":"response.output_text.delta","delta":"lo"}

event: response.completed
data: {"type":"response.completed","response":{...}}

data: [DONE]
```

The final text is reconstructed by concatenating the `delta` values from `response.output_text.delta` events.

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Responses API

    Client->>Responses API: POST /v1/responses with stream: true
    Responses API-->>Client: response.created
    Responses API-->>Client: response.in_progress
    Responses API-->>Client: response.output_text.delta
    Responses API-->>Client: response.output_text.delta
    Responses API-->>Client: response.completed
    Responses API-->>Client: [DONE]
```

## What to listen for

* `response.output_text.delta` for visible text
* `response.function_call_arguments.delta` for tool arguments
* `response.completed` for the final snapshot
* `[DONE]` for the stream terminator

## Manual SSE Parsing Example

```javascript theme={null}
const response = await fetch('https://api.naga.ac/v1/responses', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-4.1-mini',
    input: 'Say hello in two words.',
    stream: true,
  }),
});

const decoder = new TextDecoder();
let buffer = '';
let text = '';

for await (const chunk of response.body) {
  buffer += decoder.decode(chunk, { stream: true });

  let splitIndex;
  while ((splitIndex = buffer.indexOf('\n\n')) >= 0) {
    const frame = buffer.slice(0, splitIndex);
    buffer = buffer.slice(splitIndex + 2);

    const dataLine = frame.split('\n').find((line) => line.startsWith('data: '));
    if (!dataLine) continue;

    const data = dataLine.slice(6);
    if (data === '[DONE]') continue;

    const payload = JSON.parse(data);
    if (payload.type === 'response.output_text.delta') {
      text += payload.delta;
    }
  }
}

console.log(text);
```

## Tool Call Streaming

When the model emits a tool call, the stream includes argument deltas such as `response.function_call_arguments.delta` followed by `response.function_call_arguments.done`.

## Error Events

If an error occurs after headers are already sent, the stream may emit an `error` event and then a failed terminal event before `[DONE]`.

## Common mistakes

* treating the stream as plain text instead of parsing structured events
* ignoring tool or reasoning deltas because the client only listens for text
* forgetting that usage and the final response snapshot arrive at the end, not in each text delta

## Related Docs

* [Capability-level Streaming Comparison](/build/streaming)
* [Tool Calling](/api/responses/tool-calling)
* [Create response reference](/api-reference/endpoints/responses/create)
