Responses API streaming
Set "stream": true on POST /v1/responses to receive Server-Sent
Events. Kindo emits the standard OpenAI Responses stream — your
existing parser works without changes.
Request
curl -N https://api.kindo.ai/v1/responses \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $KINDO_API_KEY" \ -d '{ "model": "claude-sonnet-4-5-20250929", "stream": true, "input": "Write a haiku about observability." }'stream is consumed by the Kindo route handler to flip the response
into Content-Type: text/event-stream mode. It is not forwarded as
a model parameter.
Event types
Each event has a named event: line and a JSON data: payload. The
event names match OpenAI’s Responses streaming spec:
| Event | Meaning |
|---|---|
response.created | Initial response object is allocated. |
response.in_progress | Generation has started. |
response.output_item.added | A new output item (message, function call, etc.) has begun. |
response.output_item.done | An output item has completed. |
response.content_part.added | A new content part within a message has begun. |
response.content_part.done | A content part has completed. |
response.output_text.delta | Incremental text chunk for an output_text content part. |
response.output_text.done | The full text for a content part is now stable. |
response.function_call_arguments.delta | Incremental JSON for a function-call’s arguments. |
response.function_call_arguments.done | Function-call arguments are complete. |
response.completed | The whole response is finished. |
response.failed | The response terminated in an error state. |
error | Mid-stream error. See “Mid-stream errors” below. |
Example stream
event: response.createddata: {"id":"resp_abc123","status":"in_progress","object":"response"}
event: response.output_text.deltadata: {"item_id":"msg_xyz","delta":"Logs flow through"}
event: response.output_text.deltadata: {"item_id":"msg_xyz","delta":" the gate;\nMetrics rise like steam"}
event: response.output_text.donedata: {"item_id":"msg_xyz","text":"Logs flow through the gate;\nMetrics rise like steam,\ntraces find their way."}
event: response.completeddata: {"id":"resp_abc123","status":"completed","object":"response"}SDK consumption
Standard OpenAI SDK stream=True works as expected:
import osfrom openai import OpenAI
client = OpenAI(base_url="https://api.kindo.ai/v1", api_key=os.environ["KINDO_API_KEY"])
stream = client.responses.create( model="claude-sonnet-4-5-20250929", input="Write a haiku about observability.", stream=True,)
for event in stream: if event.type == "response.output_text.delta": print(event.delta, end="", flush=True)import OpenAI from 'openai';
const client = new OpenAI({ baseURL: 'https://api.kindo.ai/v1', apiKey: process.env.KINDO_API_KEY});
const stream = await client.responses.create({ model: 'claude-sonnet-4-5-20250929', input: 'Write a haiku about observability.', stream: true});
for await (const event of stream) { if (event.type === 'response.output_text.delta') { process.stdout.write(event.delta); }}Pre-stream errors
If the upstream request fails before streaming begins (for example, auth fails, the model isn’t found, the body is invalid), Kindo returns a normal HTTP error response with a JSON envelope — no SSE switch. See Errors for shapes.
Mid-stream errors
Once the first SSE byte has been written, the outer HTTP status is
already committed at 200. Errors that arise after that point arrive
as an error event followed by the appropriate terminal event:
event: errordata: {"error":{"message":"upstream stream interrupted","type":"server_error","code":"stream_error"}}
event: response.faileddata: {"id":"resp_abc123","status":"failed","object":"response"}Treat any error SSE event as terminal — the response will not
resume.
See also
- Quickstart — non-streaming round trip.
- Request shape — every field Kindo honors.
- Tool use — streaming tool-call events.
- Errors — pre-stream error envelopes.