Skip to main content
stream: true переключает /api/v1/chat/completions на Server-Sent Events: вместо одного ответа в конце вы получаете прирастающий текст. Это единственный способ обойти потолок запроса в 300 секунд — поток идёт до 15 минут.
В примерах ниже $TEXT_MODEL — переменная окружения с идентификатором модели из GET /api/v1/models. Идентификаторы не зашивают в код: состав каталога меняется. Разбор — в разделе Модели и цены.

Формат кадра

Каждый кадр — одна строка data: с JSON-объектом chat.completion.chunk. Между кадрами идут пустые строки-разделители.
Сервер никогда не пишет поле event:. Все события безымянные и приходят по data:. Клиент или фреймворк, который разбирает поток по event: и без него молчит, покажет пустой ответ — при том, что HTTP-статус 200 и данные шли. Всегда читайте data:.
Структура delta повторяет форму сообщения: role приходит в первом кадре, дальше идёт content, при рассуждении — reasoning и reasoning_content, при вызове функций — tool_calls. finish_reason приходит пустым (null) во всех промежуточных кадрах и заполненным в последнем.

Маркер [DONE]

Поток завершается строкой data: [DONE]. Это не JSON — парсить его как объект нельзя. Ниже, после [DONE], сервер может дописать технические поля ([DONE]-строка не обязана быть самой последней), поэтому прекращайте разбор на ней, а не на закрытии соединения.
Python

Кадр со списанием

Непосредственно перед [DONE] приходит кадр, у которого choices — пустой массив, а в usage лежит разобранный расход:
Именно здесь списываются деньги. Этот кадр приходит всегда, даже если вы не задавали stream_options.include_usage — параметр на чат-эндпоинте ничего не отключает.
Списывание происходит по факту завершения генерации, а не по факту прочтения. Если кадр с usage не пришёл — генерация не была оплачена как завершённая; сверяйте расход по эндпоинту баланса.

Ошибка внутри потока

Если провайдер оборвал генерацию, в середине потока приходит кадр с объектом error:
После него поток закрывается. [DONE] не придёт.
Python
Поэтому обрыв соединения без [DONE] — это сигнал, что что-то пошло не так, а не просто «поток закончился». Каждый кадр проверяйте на наличие error; формат ошибок разобран в Ошибках.

Деньги и разрыв соединения

Поток выполняется на контексте, отвязанном от вашего соединения. Закрыв соединение или остановив чтение, вы не отменяете генерацию — она доходит до конца, и вы платите за все произведённые токены, даже если не прочитали ни один. Единственный способ не платить — не отправлять запрос.
Практические следствия:
  • Закрытие вкладки или отмена fetch не освобождает деньги.
  • Слот параллельной генерации освобождается, а расход уже произведён.
  • Не открывайте поток, если не планируете его читать: полная цена не зависит от того, сколько вы успели прочитать.
  • Ставьте клиентский таймаут больше серверного, иначе обрыв будет на ровном месте.

Таймауты

Переход на stream: true снимает 300-секундный потолок для длинных генераций. Клиент при этом должен быть готов держать соединение дольше: поставьте 900–1000 секунд. Полный список ограничений — в разделе Лимиты.

Примеры

curl

Флаг -N отключает буферизацию вывода — без него curl накопит весь поток в памяти и напечатает разом в самом конце, хотя запрос отработал корректно.
cURL
Разбор кадров на лету — печать только текста:
Флаги --line-buffered у grep и sed обязательны: без них пайп буферизует вывод блоками и поток снова выглядит как единый ответ в конце.

Python, синхронно

Python

Python, асинхронно

Python

TypeScript

TypeScript
В fetch чтение по response.body обязательно: если прочитать тело целиком через response.json(), вы потеряете эффект потока, а на длинных ответах упрётесь в таймаут. Разбирать поток нужно построчно: SSE — не JSON-массив, кадры разделены переводом строки, поэтому нужен разбор с накоплением буфера.

Отмена

Отмена на стороне клиента освобождает слот параллельной генерации, но не возвращает деньги — генерация завершится и будет оплачена. Способ не тратить средства здесь один: не начинать запрос.

Что дальше

Запрос чату

Сводная таблица полей и формат кадра

Ошибки

Ошибки внутри потока и коды повторов

Лимиты

Таймауты и параллельные потоки

Учёт средств

Как читать списание из кадра