Capabilities
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.
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.
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_contentbefore the answer'sdelta.content. See Thinking. - Tool calls arrive in pieces: append each
delta.tool_calls[i].function.argumentsfragment byindexuntil a chunk reportsfinish_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]:
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.