# Стриминг

Со `stream: true` ответ приходит частями по мере генерации, в формате Server-Sent Events. Стоимость та же. Ошибка до первого чанка приходит обычным ответом: HTTP-код и JSON, как без стриминга.

- `chat/completions` — События `data:` с объектами `chat.completion.chunk`. Поток кончается строкой `data: [DONE]`
- `include_usage` — Со `stream_options.include_usage: true` `usage` придёт в последнем чанке перед `[DONE]`. Его `choices` может быть пустым: проверяйте длину, прежде чем брать `choices[0]`. Без `include_usage` чанка с одним `usage` нет, но у многих моделей `usage` всё равно приходит в чанке с `finish_reason`
- `responses` — События от `response.created` до `response.completed`, или `response.incomplete`, если ответ упёрся в `max_output_tokens`. `usage` — в последнем. Тип события — в поле `type`; строки `event:` может не быть
- `stream_interrupted` — Поток оборвался после начала ответа: у провайдера или по таймауту, см. «Лимиты». Статус уже 200, поэтому ошибка приходит последним событием, `[DONE]` после неё нет. В Chat Completions это `data: {"error": {"code": "stream_interrupted", "type": "server_error", …}}`, SDK OpenAI бросают на нём исключение. В Responses — событие `error` с `"code": "stream_interrupted"`. Списываем только то, что дошло
- `обрыв соединения` — Если соединение оборвано, запрос дорабатывается у провайдера и оплачивается по фактическому `usage`: провайдер выставляет счёт за весь ответ, дошёл он до вас или нет. Поток дочитываем не дальше `max_tokens` запроса, без него не дальше лимита модели по умолчанию. Пока ответ дорабатывается, запрос занимает слот параллельности ключа. Так же и без стриминга

**Пример запроса**

curl:

```bash
curl -N https://api.polyapi.ru/v1/chat/completions \
  -H "Authorization: Bearer $POLYAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-6.1-sol",
    "stream": true,
    "messages": [{"role": "user", "content": "Привет"}]
  }'
```

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["POLYAPI_KEY"],
    base_url="https://api.polyapi.ru/v1",
)

stream = client.chat.completions.create(
    model="openai/gpt-6.1-sol",
    messages=[{"role": "user", "content": "Привет"}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
```

Node.js:

```js
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.POLYAPI_KEY,
  baseURL: "https://api.polyapi.ru/v1",
});

const stream = await client.chat.completions.create({
  model: "openai/gpt-6.1-sol",
  messages: [{ role: "user", content: "Привет" }],
  stream: true,
});
for await (const c of stream) process.stdout.write(c.choices[0]?.delta?.content ?? "");
```

n8n:

```
# Узел OpenAI Chat Model → Credential → Create new credential (OpenAI)

API Key     sk-…
Base URL    https://api.polyapi.ru/v1

# Узел: Model — из списка или By ID
Model       openai/gpt-6.1-sol
```

Codex:

```toml
# ~/.codex/config.toml
model = "gpt-6.1-sol"
model_provider = "polyapi"

[model_providers.polyapi]
name = "polyapi"
base_url = "https://api.polyapi.ru/v1"
env_key = "POLYAPI_KEY"

# в терминале:
# export POLYAPI_KEY="sk-…"
# codex
```

**Ответ, события SSE**

```text
data: {"id":"chatcmpl-5f0c2b9e7d3a4e18a6c1d2b3e4f5a6b7","object":"chat.completion.chunk","created":1794052800,"model":"openai/gpt-6.1-sol","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-5f0c2b9e7d3a4e18a6c1d2b3e4f5a6b7","object":"chat.completion.chunk","created":1794052800,"model":"openai/gpt-6.1-sol","choices":[{"index":0,"delta":{"content":"Привет!"},"finish_reason":null}]}

data: {"id":"chatcmpl-5f0c2b9e7d3a4e18a6c1d2b3e4f5a6b7","object":"chat.completion.chunk","created":1794052800,"model":"openai/gpt-6.1-sol","choices":[{"index":0,"delta":{"content":" Чем помочь?"},"finish_reason":null}]}

data: {"id":"chatcmpl-5f0c2b9e7d3a4e18a6c1d2b3e4f5a6b7","object":"chat.completion.chunk","created":1794052800,"model":"openai/gpt-6.1-sol","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]
```

Источник: https://polyapi.ru/docs/stream
