Streaming
Receive tokens as server-sent events and parse them correctly.
Set "stream": true to receive the response as server-sent events. Each event is a line starting with data: followed by a JSON chunk; the stream ends with data: [DONE].
Chunk format
text/event-stream
data: {"id":"chatcmpl-9f2c1a","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[{"index":0,"delta":{"role":"assistant","content":""}}]}
data: {"id":"chatcmpl-9f2c1a","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[{"index":0,"delta":{"content":"42"}}]}
data: {"id":"chatcmpl-9f2c1a","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[{"index":0,"delta":{"content":" — according to Douglas Adams."}}]}
data: {"id":"chatcmpl-9f2c1a","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":14,"completion_tokens":9,"total_tokens":23}}
data: [DONE]| Field | Description |
|---|---|
choices[0].delta.content | The new text in this chunk. Append it to your output. |
choices[0].finish_reason | Set on the final content chunk (stop, length, …). |
usage | Token counts, sent on the last chunk. |
Parsing SSE manually
SDKs handle this for you. Without one, read the body incrementally, split on newlines and keep any partial line for the next read:
TypeScript (fetch)
const res = await fetch(url, { method: "POST", headers, body });
const reader = res.body!.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() ?? ""; // keep partial line
for (const line of lines) {
if (!line.startsWith("data: ")) continue;
const data = line.slice(6).trim();
if (data === "[DONE]") return;
const chunk = JSON.parse(data);
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
}Errors that happen before streaming starts return a normal JSON error with a status code. Lines starting with
: are keep-alive comments — ignore them.