Docs/API access

Streaming

Set stream to true and read Server-Sent Events to receive the first token sooner.

On this page

Returning a long answer in one shot leaves users staring at a blank screen for seconds. With streaming, each fragment is pushed as it is generated and time-to-first-token typically drops to a few hundred milliseconds.

Turning it on

bash
curl https://api.apione.ai/v1/chat/completions \
  -H "Authorization: Bearer $APIONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "stream": true,
    "messages": [{ "role": "user", "content": "Write a 200-word product intro" }]
  }'

Wire format

The response Content-Type is text/event-stream. Each chunk is one data: line, and the stream ends with data: [DONE]:

text
data: {"id":"chatcmpl-01J8Z","choices":[{"delta":{"role":"assistant"},"index":0}]}

data: {"id":"chatcmpl-01J8Z","choices":[{"delta":{"content":"APIONE"},"index":0}]}

data: {"id":"chatcmpl-01J8Z","choices":[{"delta":{"content":" is a"},"index":0}]}

data: {"id":"chatcmpl-01J8Z","choices":[{"delta":{},"finish_reason":"stop","index":0}],
       "usage":{"prompt_tokens":18,"completion_tokens":126,"total_tokens":144}}

data: [DONE]
  • Text increments live in choices[0].delta.content; concatenate them in order.
  • usage appears only on the final content chunk — don't break early if you need billing data.
  • Keep-alive comment lines (starting with :) may appear; ignore them.

With the SDKs

python
stream = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Write a 200-word product intro"}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content, end="", flush=True)
javascript
const stream = await client.chat.completions.create({
  model: "claude-sonnet-4-6",
  messages: [{ role: "user", content: "Write a 200-word product intro" }],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Errors mid-stream

The HTTP status is fixed once headers are sent, so a failure after the stream starts arrives as an error chunk instead:

json
data: {"type":"error","error":{"message":"upstream timed out","type":"upstream_error","code":"upstream_timeout","retryable":true}}
Important

Text already shown to the user cannot be taken back. Keep what was rendered, surface an “interrupted” state, and let the user decide whether to retry — silently resending the whole request bills you twice.

Gotchas

  • Reverse proxies (Nginx and friends) must have response buffering disabled, or chunks are batched.
  • Don't use EventSource in the browser — it is GET-only and cannot carry a body. Use fetch and read the ReadableStream.
  • Serverless platforms often cap responses at 30s; confirm yours supports streaming before shipping long answers.

Contact us

Something unclear, or need a human? Pick the channel that fits your question.