Datacenter in the EU · EU jurisdiction · OpenAI-compatible API
GRUNDEN.AI
GLM 5.3 Flash

Chat

General text-in / text-out. Streaming + tool-calling.

§ 01

Chat completions

POST /v1/chat/completions — OpenAI-compatible endpoint. Streaming via SSE is supported when stream: true.

bash
curl https://api.grunden.ai/v1/chat/completions \
  -H "Authorization: Bearer $GRUNDEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-5.3-flash",
    "messages": [{"role": "user", "content": "Hej!"}]
  }'
§ 02

Streaming

With stream: true, Server-Sent Events are returned in the OpenAI format — the same delta structure you're used to.

js
const stream = await client.chat.completions.create({
  model: "glm-5.3-flash",
  stream: true,
  messages: [{ role: "user", content: "Skriv en haiku om regn" }],
});

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

Tool calling (function calling)

Define tools the model can call via tools. GLM 5.3 Flash responds with tool_calls in the assistant message; you run the function yourself and send the result back with role: "tool".

json
{
  "model": "glm-5.3-flash",
  "messages": [{"role": "user", "content": "Vad väger en blåval?"}],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_web",
        "parameters": {"type": "object", "properties": {"q": {"type": "string"}}}
      }
    }
  ]
}
§ 04

Reasoning levels

The models reason before they answer, and you control the depth per request with the reasoning_effort parameter in the request body. The levels are per model and published as reasoning_levels and default_reasoning_level in GET /v1/models. GLM 5.3 has low, high and max; omitting the parameter means max. Gemma 4 can only turn thinking off or on: none or high, and omitting the parameter means none. The full OpenAI vocabulary is accepted and mapped to the model's nearest level — on GLM, none and minimal become low and medium becomes high; on Gemma, anything but none turns thinking on. Other values are rejected with 400.

json
{
  "model": "glm-5.3-flash",
  "messages": [{"role": "user", "content": "Hur många r finns i strawberry?"}],
  "reasoning_effort": "low"
}

The reasoning is delivered separately in the reasoning_content field of the response (as delta.reasoning_content when streaming) — content contains only the answer itself.

Measured on the same question (temperature 0, same correct answer all three times): low produced 1 reasoning token out of 48 completion tokens in total, high 9 out of 59 and max 158 out of 210. For simple questions a lower level can give the same answer at a fraction of the output tokens — and output is billed per token.

In the web chat the selector shows the chosen model's levels. The default is high for GLM and off for Gemma; switching to a model of the other kind resets the level to its default.

§ 05

Dimension your costs

Need to know which of your customers, departments or projects consumed what? Send the user field in the request with your own cost dimension — a tag you choose yourself. It is stored on the usage record and summed per dimension. The field works on every endpoint, not just chat.

json
{
  "model": "glm-5.3-flash",
  "messages": [{"role": "user", "content": "Hej!"}],
  "user": "kund-4711"
}

The tag is trimmed and may be at most 128 characters. Control characters and invisible formatting characters are rejected with 400 — the value is never truncated, because two dimensions sharing the start of their tag would then be silently merged and summed incorrectly. Send an opaque identifier, not personal data. Omit the field and the call lands under "Not dimensioned".

Fetch the report with GET /v1/usage/allocation. The period is [from, to) — from inclusive, to exclusive — so two consecutive months never count the same second twice. Group by api_key, end_user and/or model, and fetch as JSON or CSV for import into your business system.