Lyber
Request access
DocsStreaming

Capabilities

Markdown

Streaming

Receive tokens as they are generated, as server-sent events.

Set stream: true on a chat completion. The response is a stream of server-sent events: each data: line carries a JSON chunk, and the stream ends with data: [DONE]. The OpenAI SDKs parse it for you.

main.py
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://lyber-paid-acceptance-gateway-production.up.railway.app/v1",
    api_key=os.environ["LYBER_API_KEY"],
)

stream = client.chat.completions.create(
    model="minimax-m3.1-flash-abliterated",
    messages=[{"role": "user", "content": "Write a haiku about open weights."}],
    max_tokens=1024,
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
    if chunk.usage:
        print("\n", chunk.usage)

Usage in streams

Streams report token usage only when you ask: set stream_options: {"include_usage": true} and the last chunk before [DONE] carries usage, with an empty choices array. Without it, Lyber still bills the request; the usage just isn't sent to you.

stream.txt
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"minimax-m3.1-flash-abliterated","choices":[{"index":0,"delta":{"content":"Open"}}]}

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"minimax-m3.1-flash-abliterated","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"minimax-m3.1-flash-abliterated","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":41,"total_tokens":59}}

data: [DONE]

Reasoning and tool calls

  • Reasoning arrives in delta.reasoning_content before the answer's delta.content. See Thinking.
  • Tool calls arrive in pieces: append each delta.tool_calls[i].function.arguments fragment by index until a chunk reports finish_reason: "tool_calls".
  • Lines starting with : are keep-alive comments. SDKs ignore them; a hand-written parser should too.

Errors during a stream

Errors before the first token come back as a normal HTTP error. If the model fails after streaming has started, the status is already 200, so Lyber sends an error event and then [DONE]:

stream.txt
data: {"error":{"message":"Stream interrupted","code":"upstream_error"}}

data: [DONE]

A stream that hits the request timeout ends without [DONE]. Treat a stream that ends early as incomplete. Lyber never retries a request on your behalf.