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.contentfragments; choices[0].finish_reasonisnulluntil the final content chunk, which sets it ("stop"on a clean end);- a final usage chunk always arrives, with empty
choicesand the fullusageobject — regardless ofstream_options. This is a deliberate divergence from the OpenAI opt-in: your cost is always machine-readable from the stream itself, andusage.costis 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-Keyand 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.