ReferenceReference

Streaming

Server-sent events, how bytes are relayed, and how usage is captured.

By the end: You can consume a stream correctly and know when usage arrives.

A streaming request returns text/event-stream. Each event is a data: line containing a JSON object, terminated by a blank line.

Reading a stream

Node

const res = await fetch(url, { method: 'POST', headers, body });
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = '';

for (;;) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });

  let i;
  while ((i = buffer.indexOf('\n')) >= 0) {
    const line = buffer.slice(0, i).trim();
    buffer = buffer.slice(i + 1);
    if (!line.startsWith('data:')) continue;
    const payload = line.slice(5).trim();
    if (!payload || payload === '[DONE]') continue;
    process(JSON.parse(payload));
  }
}

What the gateway does

Where usage appears

OpenAI-shaped streams put usage in a final event when stream_options.include_usage is set. Anthropic reports it on message_start and message_delta. Gemini reports usageMetadata on its last chunk.