Search the documentation

Pick a page and open it with Enter.

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].

stream.ts
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: error

Error after the stream started — as its own event: error event; the stream ends afterwards.