Skip to content

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

Terminal window
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:

EventMeaning
response.createdInitial response object is allocated.
response.in_progressGeneration has started.
response.output_item.addedA new output item (message, function call, etc.) has begun.
response.output_item.doneAn output item has completed.
response.content_part.addedA new content part within a message has begun.
response.content_part.doneA content part has completed.
response.output_text.deltaIncremental text chunk for an output_text content part.
response.output_text.doneThe full text for a content part is now stable.
response.function_call_arguments.deltaIncremental JSON for a function-call’s arguments.
response.function_call_arguments.doneFunction-call arguments are complete.
response.completedThe whole response is finished.
response.failedThe response terminated in an error state.
errorMid-stream error. See “Mid-stream errors” below.

Example stream

event: response.created
data: {"id":"resp_abc123","status":"in_progress","object":"response"}
event: response.output_text.delta
data: {"item_id":"msg_xyz","delta":"Logs flow through"}
event: response.output_text.delta
data: {"item_id":"msg_xyz","delta":" the gate;\nMetrics rise like steam"}
event: response.output_text.done
data: {"item_id":"msg_xyz","text":"Logs flow through the gate;\nMetrics rise like steam,\ntraces find their way."}
event: response.completed
data: {"id":"resp_abc123","status":"completed","object":"response"}

SDK consumption

Standard OpenAI SDK stream=True works as expected:

import os
from 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: error
data: {"error":{"message":"upstream stream interrupted","type":"server_error","code":"stream_error"}}
event: response.failed
data: {"id":"resp_abc123","status":"failed","object":"response"}

Treat any error SSE event as terminal — the response will not resume.

See also