IronStratum

Streaming

Set "stream": true and the response is a server-sent-events (SSE) stream of chat completion chunks — same envelope, token by token.

The stream, end to end

curl -N -sS -w '\n%{http_code}\n' $IRONSTRATUM_BASE_URL/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $IRONSTRATUM_API_KEY" \
  -d '{
    "model": "qwen3.8-27b",
    "messages": [{"role": "user", "content": "Count slowly from one to three."}],
    "stream": true,
    "max_tokens": 48
  }'

Events arrive as data: {…} lines. Each carries a chat.completion.chunk:

  • the first chunk carries choices[0].delta = {"role": "assistant"};
  • content chunks carry delta.content fragments;
  • choices[0].finish_reason is null until the final content chunk, which sets it ("stop" on a clean end);
  • a final usage chunk always arrives, with empty choices and the full usage object — regardless of stream_options. This is a deliberate divergence from the OpenAI opt-in: your cost is always machine-readable from the stream itself, and usage.cost is our retail charge, not an estimate.
  • the stream terminates with data: [DONE] — exactly once.

Keep-alives

While the first byte is pending, the connection emits : ping comment lines roughly every 15 seconds. They are SSE comments: compliant clients ignore them automatically, and they are never a data event.

Interruptions and retries

If the model connection dies mid-stream, you receive a terminal data: {"error":{…}} event with code stream_interrupted — never a bare connection drop and never a silently truncated answer.

The retry semantics are exact:

  • Only completed successful turns are cached for idempotent replay. An interrupted stream is never cached.
  • Retrying an interrupted request with the same Idempotency-Key and identical body re-executes fresh — you get a new generation, billed once for what actually ran.
  • Retrying after a completed turn replays the original response bytes with the original x-request-id — see idempotency.

Client notes

Use a no-buffering HTTP client (curl -N above). Read the stream incrementally, split on \n\n, and stop at [DONE] — the usage chunk has already arrived by then.