stream: true works on /v1/messages, /v1/chat/completions and /v1/responses with and without a server prompt. The format depends on the API: Anthropic SSE, OpenAI Chat chunks or Responses events respectively.
stream: trueSSEcontent_block_deltamessage_stopchat.completion.chunkdata: [DONE]response.output_text.deltaresponse.completed| Endpoint | Terminal event | Notes |
|---|---|---|
/v1/messages without a server prompt | message_stop | Native text/tool/thinking/signature/citation deltas |
/v1/messages with an applied prompt | message_stop | Text and client tools; no signed thinking or citation deltas |
/v1/chat/completions | data: [DONE] | OpenAI-compatible chunks |
/v1/responses | response.completed | Responses events; at the output limit the final object has 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",
"max_tokens": 256,
"stream": true,
"messages": [{"role": "user", "content": "Write a haiku about the sea"}]
}'Claude Messages event types without an applied server prompt:
message_start— start of the response, metadata.content_block_start/content_block_delta/content_block_stop— content chunks.message_delta— top-level changes (e.g. stop_reason).message_stop— end of the response.
Without an applied server prompt, content_block_delta may also contain thinking_delta, signature_delta, input_json_delta, and citations_delta. Ignore unknown event types safely — Anthropic may add more.
Kimi streams on all three surfaces; the plain Chat Completions frames and the repeated usage are covered on Kimi · Streaming and usage. Composer and Grok stream on all three surfaces, each in its native format.
Pass stream: true and the answer arrives as SSE frames in the ordinary OpenAI shape. Every frame is a chat.completion.chunk, the piece of text sits in choices[0].delta.content, and the line data: [DONE] closes the stream.
curl -N -X POST https://api.guardrelay.ai/v1/chat/completions \
-H "Authorization: Bearer gd-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "k3",
"messages": [{"role": "user", "content": "Write a haiku about the sea"}],
"max_tokens": 256,
"stream": true
}'Kimi puts the final statistics into the closing frame next to finish_reason, even when stream_options.include_usage was not asked for. With include_usage: true the same statistics arrive once more as a separate frame with an empty choices. It is the same number — do not add them up.
| Endpoint | Composer and Grok events |
|---|---|
/v1/messages | message_start, content_block_start, content_block_delta, content_block_stop, message_delta with the final usage, message_stop |
/v1/chat/completions | chat.completion.chunk frames, the last one carrying finish_reason: "stop" and usage, then data: [DONE] |
/v1/responses | response.created, response.output_text.delta, response.output_text.done, response.completed with usage |
curl -N -X POST https://api.guardrelay.ai/v1/chat/completions \
-H "Authorization: Bearer gd-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "cursor-grok-4.6-low",
"messages": [{"role": "user", "content": "Write a haiku about the sea"}],
"max_tokens": 256,
"stream": true
}'curl -N -X POST https://api.guardrelay.ai/v1/chat/completions \
-H "Authorization: Bearer gd-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "composer-2.5",
"messages": [{"role": "user", "content": "Write a haiku about the sea"}],
"max_tokens": 256,
"stream": true
}'