Streaming

Stream OpenAI-compatible chat completion chunks over Server-Sent Events.

Set stream to true to receive text and tool-call deltas as Server-Sent Events.

POST/chat/completions

Use the standard endpoint with stream: true.

cURL

curl --no-buffer https://glm5.app/api/v1/chat/completions \
  -H "Authorization: Bearer $GLM5_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-5.2",
    "messages": [
      {"role": "user", "content": "Write a four-line release announcement."}
    ],
    "max_completion_tokens": 500,
    "stream": true
  }'

Python

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["GLM5_API_KEY"],
    base_url="https://glm5.app/api/v1",
)

stream = client.chat.completions.create(
    model="glm-5.2",
    messages=[
        {"role": "user", "content": "Write a four-line release announcement."}
    ],
    max_completion_tokens=500,
    stream=True,
)

for chunk in stream:
    content = chunk.choices[0].delta.content
    if content:
        print(content, end="", flush=True)

Event format

Each event starts with data: and contains a chat.completion.chunk object:

data: {"id":"chatcmpl_01...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}

data: {"id":"chatcmpl_01...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Ship"},"finish_reason":null}]}

data: {"id":"chatcmpl_01...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

Tool arguments can also arrive incrementally in delta.tool_calls.

Chunk fields

FieldMeaning
idCompletion ID shared by chunks from the same call.
objectchat.completion.chunk.
createdUnix timestamp in seconds.
modelPublic GLM 5 model ID.
choices[].indexChoice index. GLM 5 currently emits one choice.
choices[].delta.roleUsually appears at the start as assistant.
choices[].delta.contentText fragment to append to your response buffer.
choices[].delta.tool_callsFunction-call deltas to accumulate by index.
choices[].finish_reasonstop, tool_calls, or null while still running.

If you are migrating an OpenRouter or OpenAI-compatible client, keep the same basic parser shape:

  • Read each Server-Sent Event line that starts with data:.
  • Treat data: [DONE] as the end of the stream.
  • Append choices[0].delta.content when it is present.
  • Accumulate choices[0].delta.tool_calls when using function calling.
  • Stop reading when finish_reason is stop or tool_calls.

Stream errors

An error after the stream has started is sent as an SSE error object and then the connection closes:

data: {"error":{"message":"Internal server error.","type":"server_error","code":"internal_error","param":null}}

Handle both non-2xx HTTP responses before streaming and error events after the stream begins.

Streaming changes latency, not input cost

Streaming lets your application render output sooner. It does not reduce the tokens in the request's messages array.