SupaNexus

Streaming — Markdown source

Raw Markdown for copying or feeding to AI agents.

> **AI Agents**: Index `/api/llms.txt` | Full EN `/api/llms-full-en.txt` | Full ZH `/api/llms-full-zh.txt` | OpenAPI `/api/openapi.yaml`
> Base URL: `<BASE_URL>/v1`

# Streaming

Stream chat completion tokens using **Server-Sent Events (SSE)**.

## Enable streaming

Set `"stream": true` in the chat completions request body:

```json
{
  "model": "deepseek/deepseek-chat",
  "messages": [{"role": "user", "content": "Count to five."}],
  "stream": true
}
```

**Use `stream: true` for reasoning / long-thinking models.** Non-streaming requests may be cut off by CDN (e.g. Cloudflare) ~100s first-byte limits. On the streaming path the gateway periodically sends SSE comment lines (`: keepalive`), which SDKs ignore.

## Response format

- **Content-Type**: `text/event-stream`
- Each line: `data: <json chunk>`
- Terminator: `data: [DONE]`

Example (`data:` JSON is usually one line on the wire; line breaks here are for readability):

```http
data: {
  "id": "chatcmpl-...",
  "object": "chat.completion.chunk",
  "choices": [
    {
      "index": 0,
      "delta": { "content": "One" },
      "finish_reason": null
    }
  ]
}

data: {
  "id": "chatcmpl-...",
  "object": "chat.completion.chunk",
  "choices": [
    {
      "index": 0,
      "delta": { "content": ", two" },
      "finish_reason": null
    }
  ]
}

data: [DONE]
```

## Usage in stream

The final stream chunks may include a `usage` object with token counts (model-dependent).

## curl example

```bash
curl -N "${SNX_BASE_URL}/chat/completions" \
  -H "Authorization: Bearer ${SNX_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-chat",
    "stream": true,
    "messages": [{"role": "user", "content": "Say hi"}]
  }'
```

Use `-N` to disable curl buffering.

## OpenAI SDK (Python)

```python
stream = client.chat.completions.create(
    model="deepseek/deepseek-chat",
    messages=[{"role": "user", "content": "Say hi"}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    print(delta, end="", flush=True)
```

## Error handling

| Phase | Behavior |
|-------|----------|
| **Pre-stream** | HTTP 4xx/5xx with JSON `error` object (same as non-streaming) |
| **Mid-stream** | Client should handle truncated SSE |

Quota, balance, and auth errors typically occur **before** the first byte of the stream.

## Related

- [Chat Completions](./chat-completions.md)
- [Errors](./errors.md)