stream: true работает на /v1/messages, /v1/chat/completions и /v1/responses с серверным промптом и без него. Формат зависит от API: Anthropic SSE, OpenAI Chat chunks или Responses events соответственно.
stream: trueSSEcontent_block_deltamessage_stopchat.completion.chunkdata: [DONE]response.output_text.deltaresponse.completed| Endpoint | Терминальное событие | Особенности |
|---|---|---|
/v1/messages без серверного промпта | message_stop | Нативные text/tool/thinking/signature/citations deltas |
/v1/messages с применённым промптом | message_stop | Text и client tools; без signed thinking и citations deltas |
/v1/chat/completions | data: [DONE] | OpenAI-compatible chunks |
/v1/responses | response.completed | Responses events; при лимите финальный объект имеет status: incomplete |
curl -N https://api.guardrelay.ai/v1/messages \
-H "x-api-key: $GUARD_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5-5",
"max_tokens": 256,
"stream": true,
"messages": [{"role": "user", "content": "Напиши хайку про море"}]
}'Типы событий Claude Messages без применённого серверного промпта:
message_start— начало ответа, метаданные.content_block_start/content_block_delta/content_block_stop— куски контента.message_delta— изменения верхнего уровня (например, stop_reason).message_stop— конец ответа.
Без применённого серверного промпта внутри content_block_delta дополнительно могут приходить thinking_delta, signature_delta, input_json_delta и citations_delta. Обрабатывайте неизвестные типы событий без падения — Anthropic может добавлять новые.
Responses SSE включается stream: true на /v1/responses и /codex/v1/responses. Native WebSocket использует wss://api.guardrelay.ai/v1/responses либо прежний wss://api.guardrelay.ai/codex/v1/responses: клиент отправляет события response.create и получает Responses events. Chat Completions и Messages поддерживают SSE, но не переименовываются в Responses events.
Kimi стримит на всех трёх поверхностях; кадры обычного Chat Completions и повторный usage разобраны на странице Kimi: streaming и usage. Composer и Grok стримят на всех трёх поверхностях, в родном для каждой формате.
Передайте stream: true — ответ пойдёт кадрами SSE в обычной OpenAI-форме. Каждый кадр это chat.completion.chunk, кусок текста лежит в choices[0].delta.content, а завершает поток строка data: [DONE].
curl -N -X POST https://api.guardrelay.ai/v1/chat/completions \
-H "Authorization: Bearer gd-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "k3",
"messages": [{"role": "user", "content": "Напиши хайку про море"}],
"max_tokens": 256,
"stream": true
}'Итоговую статистику Kimi кладёт в завершающий кадр рядом с finish_reason, даже если stream_options.include_usage не запрошен. При include_usage: true та же статистика придёт ещё раз отдельным кадром с пустым choices. Это одно и то же число, складывать их не нужно.
| Endpoint | События Composer и Grok |
|---|---|
/v1/messages | message_start, content_block_start, content_block_delta, content_block_stop, message_delta с итоговым usage, message_stop |
/v1/chat/completions | кадры chat.completion.chunk, последний кадр несёт finish_reason: "stop" и usage, затем data: [DONE] |
/v1/responses | response.created, response.output_text.delta, response.output_text.done, response.completed с usage |
curl -N -X POST https://api.guardrelay.ai/v1/chat/completions \
-H "Authorization: Bearer gd-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "cursor-grok-4.6-low",
"messages": [{"role": "user", "content": "Напиши хайку про море"}],
"max_tokens": 256,
"stream": true
}'curl -N -X POST https://api.guardrelay.ai/v1/chat/completions \
-H "Authorization: Bearer gd-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "composer-2.5",
"messages": [{"role": "user", "content": "Напиши хайку про море"}],
"max_tokens": 256,
"stream": true
}'Добавьте stream: true в то же тело. События остаются нативными для выбранного API: Guard не переводит Messages, Chat и Responses друг в друга.
curl -N https://api.guardrelay.ai/glm/v1/responses \
-H "Authorization: Bearer $GUARD_API_KEY" \
-H "content-type: application/json" \
-d '{"model":"glm-5.3","input":"Explain 2+2 briefly","max_output_tokens":4096,"store":false,"stream":true}'| API | Текст | Успешный финал | Ограниченный финал |
|---|---|---|---|
| Messages | content_block_delta | message_delta + message_stop | stop_reason: max_tokens |
| Chat | choices[].delta.content | finish_reason + [DONE] | finish_reason: length |
| Responses | response.output_text.delta | response.completed | response.incomplete + max_output_tokens |
response.incomplete — терминальное событие, а не transport error. Сохраните уже полученный вывод и проверьте incomplete_details.reason.
Если клиент отменяет поток до точных финальных счётчиков, Guard освобождает резерв без предполагаемого списания; не делайте из этого вывод, что расход GLM равен нулю.
Поток SSE работает во всех трёх API: передайте stream: true. Кадры — как у выбранного API: события Anthropic в Messages, chat.completion.chunk и data: [DONE] в Chat Completions, события response.* в Responses. Размышления, если их показ запрошен, приходят отдельными кадрами: thinking_delta в Messages и response.reasoning_summary_text.delta в Responses. В Chat Completions показ размышлений не запрашивается.
Поток SSE работает во всех трёх API: передайте stream: true. Кадры — как у выбранного API: события Anthropic в Messages, chat.completion.chunk и data: [DONE] в Chat Completions, события response.* в Responses.