Skip to contentBase Eleven
Sign inStart free
Guide

Streaming

Set stream to true and the reply arrives as server-sent events, token by token.

How it works

Add "stream": true to the body. The response is text/event-stream, sent with Cache-Control: no-cache and X-Accel-Buffering: no so nothing buffers it. Each event is an event: line, a data: line with JSON, and a blank line. This call streams Eleven Max with a system text and a stop sequence; -N makes curl print events as they arrive.

curl, streaming
curl -N https://api.baseeleven.dev/v1/messages \
  -H "x-api-key: $B11_API_KEY" \
  -H "content-type: application/json" \
  -d '{
  "model": "eleven-max",
  "max_tokens": 512,
  "stream": true,
  "system": "Answer in plain English, in at most two paragraphs.",
  "temperature": 0.5,
  "stop_sequences": [
    "###"
  ],
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Explain what a throughput tier is and how a workspace moves up."
        }
      ]
    }
  ]
}'

A streamed reply takes the same simulated time as a whole one: the first token after about 600 ms on Eleven Max, then 40 tokens a second. Without stream you wait for the whole reply and get one JSON body.

The four events

Every event the stream can carry, in order
EventDataWhen
message_start{id, model, usage: {input_tokens}}First, at once. The input count is final.
text_delta{text}One per chunk of text, as the model produces it.
message_end{stop_reason, usage: {input_tokens, output_tokens}}Last, when the reply finished. The usage is what the call is charged.
errorthe error body: {type, error: {type, message, b11_code}, request_id}Last, instead of message_end, if the model failed after the stream began.

Read until message_end or error. A client that stops reading early loses the final usage; see below for what it is charged.

A sample stream

The simulator’s reply to a three-token prompt on Eleven Lite, cut at 16 output tokens by max_tokens. This is the gateway’s golden file, byte for byte:

text/event-stream
event: message_start
data: {"id":"msg_01M3VNBWG00M2GA1850M2GA185","model":"eleven-lite","usage":{"input_tokens":3}}

event: text_delta
data: {"text":"Simu"}

event: text_delta
data: {"text":"lated reply: placeholder"}

event: text_delta
data: {"text":" text, not written by an"}

event: text_delta
data: {"text":"y model.\n\nRi"}

event: message_end
data: {"stop_reason":"max_tokens","usage":{"input_tokens":3,"output_tokens":16}}

Folded into one object, the same call without stream gives:

200 OK
{
  "id": "msg_01M3VNBWG00M2GA1850M2GA185",
  "type": "message",
  "model": "eleven-lite",
  "content": [
    {
      "type": "text",
      "text": "Simulated reply: placeholder text, not written by any model.\n\nRi"
    }
  ],
  "stop_reason": "max_tokens",
  "usage": {
    "input_tokens": 3,
    "output_tokens": 16
  }
}

When the model fails

If the model fails before any output, there is no stream: the call answers 502 with the backend_error body, and nothing is charged. If it fails after the stream began, the stream ends with an error event instead of message_end. Its b11_code is backend_error and its message is one of two fixed sentences:

  • "The model failed during the reply. Only the output already sent is charged."
  • "The model failed before it produced any output. Nothing was charged."

A stream that fails is charged its output only: the text deltas you received, at the output rate. Its input is not charged. The failure is not a refusal, so it does not count against anything but the tokens sent.

502 Bad Gateway, before any output
{
  "type": "error",
  "error": {
    "type": "api_error",
    "message": "The model failed, so there is no reply. Nothing was charged.",
    "b11_code": "backend_error"
  },
  "request_id": "req_01M3VNBWG00W3GE1R70W3GE1R7"
}

If you hang up

When a client disconnects mid-stream the gateway stops the model within a tick and settles what was produced: you pay for the tokens sent so far, at the output rate, plus the input. Nothing else is charged, and the worst-case reservation made before the call is released.

At most one chunk, the one in flight as you left, may be charged without being delivered. Chunks are 50 ms apart, so that is a handful of tokens.

Usage for a dropped call is reported with outcome: client_disconnected, and shows on the usage page like any other call.

Next: Errors