Streaming
Receive answers token by token over Server-Sent Events.
Instead of waiting for the full answer, the API delivers Server-Sent Events — token by token.
Endpoint
Streaming runs over POST /api/v1/chat/stream with the same body as /chat. The response is a text/event-stream of data: lines, each a JSON frame with a type, terminated by data: [DONE].
for await (const frame of parseSse(response.body)) {
if (frame.type === "reasoning") appendReasoning(frame.delta);
else if (frame.type === "content") appendContent(frame.delta);
else if (frame.type === "tool_call") startTool(frame);
else if (frame.type === "tool_result") finishTool(frame);
}Order
reasoning* → (tool_call → tool_result)* → content* → [DONE]. Multiple rounds are normal. Always link tool_call and tool_result by call_id, never by order.
Frame types
reasoning{ delta }The model's reasoning (reasoning models only, comes first). Kept separate from the content.
content{ delta }A chunk of the visible answer. Appended continuously and rendered as Markdown.
tool_call{ tool, call_id, arguments }A tool is being called. arguments is an object.
tool_result{ tool, call_id, ok, preview, length }Result. ok=false = failure, preview then carries the message.
errorevent: errorError after the stream started — as its own event: error event; the stream ends afterwards.