AIWave API

Streaming Responses

Set stream: true and the AIWave API returns server-sent events in the same chunk format as the OpenAI Chat Completions API. Streaming parsers written against OpenAI work unchanged, which matters because time-to-first-token dominates perceived latency in chat interfaces.

Step 1: Enable streaming

from openai import OpenAI

client = OpenAI(api_key="sk-YOUR_KEY", base_url="https://aiwave.live/v1")

stream = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "Write a short poem about latency."}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Step 2: Understand the wire format

Each event is a data: line holding one JSON chunk. The final event is the literal sentinel data: [DONE], which is not JSON — parsers must special-case it.

data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{"content":"Hel"}}]}

data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{"content":"lo"}}]}

data: [DONE]

Step 3: Handle it in TypeScript

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AIWAVE_API_KEY,
  baseURL: "https://aiwave.live/v1",
});

const stream = await client.chat.completions.create({
  model: "glm-5",
  messages: [{ role: "user", content: "Explain SSE in one paragraph." }],
  stream: true,
});

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

Step 4: Parse the raw stream yourself

If you are not using an SDK, read the body line by line rather than buffering it. Buffering defeats the entire point of streaming.

import httpx, json

with httpx.stream(
    "POST",
    "https://aiwave.live/v1/chat/completions",
    headers={"Authorization": "Bearer sk-YOUR_KEY"},
    json={"model": "deepseek-v4-flash",
          "messages": [{"role": "user", "content": "Hi"}],
          "stream": True},
    timeout=60,
) as r:
    for line in r.iter_lines():
        if not line.startswith("data: "):
            continue
        payload = line[len("data: "):]
        if payload == "[DONE]":
            break
        chunk = json.loads(payload)
        piece = chunk["choices"][0]["delta"].get("content")
        if piece:
            print(piece, end="", flush=True)

Step 5: Account for tokens

Streaming responses do not carry a usage object on every chunk. If you need exact token counts for billing, either issue the same request without streaming for measurement, or count on the client side and reconcile against the console usage view.

Practical notes

Related documentation

Get an API key →All docs →