Skip to main content

Chat completions

POST https://api.entrim.ai/v1/chat/completions

Generates the next assistant message for a conversation. Requests and responses use the OpenAI chat completions format, so the official OpenAI SDKs and most OpenAI-compatible libraries work once you set the base URL to https://api.entrim.ai/v1.

Headers​

HeaderValue
AuthorizationBearer <your-api-key>
Content-Typeapplication/json

Request body​

ParameterTypeRequiredDescription
modelstringYesThe model ID, for example zai-org/GLM-5.3-Flash. See List models.
messagesarrayYesThe conversation so far, oldest message first. See Messages.
max_tokensintegerNoThe most tokens to generate. On reasoning models this includes the reasoning.
max_completion_tokensintegerNoSame as max_tokens, under the newer OpenAI name.
temperaturenumberNoSampling temperature between 0 and 2. Higher values give more varied output.
top_pnumberNoNucleus sampling: only tokens within this cumulative probability are considered.
stopstring or arrayNoOne or more sequences that end the response when generated.
seedintegerNoMakes sampling repeatable on a best-effort basis.
presence_penaltynumberNoBetween -2.0 and 2.0. Positive values push the model toward new topics.
frequency_penaltynumberNoBetween -2.0 and 2.0. Positive values reduce repetition.
reasoning_effortstringNolow, medium or high. How much a reasoning model thinks before it answers. See Reasoning models.
response_formatobjectNoAsk for JSON output. See Structured output.
toolsarrayNoFunctions the model may call. See Tool calling.
tool_choicestringNoauto (the default when tools is set), none or required.
streambooleanNoSend the response as server-sent events while it's generated. See Streaming.
stream_optionsobjectNo{"include_usage": true} adds a final chunk with token usage to the stream.
logprobsbooleanNoReturn the log probability of each output token.
top_logprobsintegerNoHow many of the most likely alternatives to return for each token. Requires logprobs.

Messages​

Each item in messages is an object with a role and content:

FieldTypeDescription
rolestringsystem, user, assistant or tool
contentstring or arrayThe message text. User messages can also be an array of content parts, to mix text and images.
tool_callsarrayAssistant messages only: the tool calls from an earlier response, sent back unchanged
tool_call_idstringTool messages only: the id of the tool call this message answers
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is the capital of Slovenia?"},
{"role": "assistant", "content": "Ljubljana."},
{"role": "user", "content": "How many people live there?"}
]

Example request​

curl https://api.entrim.ai/v1/chat/completions \
-H "Authorization: Bearer $ENTRIM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "zai-org/GLM-5.3-Flash",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a haiku about the Julian Alps."}
]
}'

Example response​

{
"id": "97bc062ce4f84e6c8e682b24ce4948dd",
"object": "chat.completion",
"created": 1790160983,
"model": "zai-org/GLM-5.3-Flash",
"choices": [
{
"index": 0,
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": "Triglav wears her snow,\nthe Soča runs emerald\nthrough stone and silence.",
"reasoning_content": "The user wants a haiku about the Julian Alps. A haiku is a traditional Japanese poem with..."
}
}
],
"usage": {
"prompt_tokens": 28,
"completion_tokens": 841,
"total_tokens": 869,
"completion_tokens_details": {
"reasoning_tokens": 820,
"text_tokens": 21
}
}
}

The reasoning is shortened here. Notice that most of the completion tokens went to reasoning, which is typical for reasoning models.

FieldDescription
choices[].message.contentThe answer
choices[].message.reasoning_contentThe model's reasoning, on reasoning models
choices[].message.tool_callsTool calls the model wants you to run, when you sent tools
choices[].finish_reasonstop when the model finished, length when it hit max_tokens, tool_calls when it's waiting for tool results
usageToken counts for the request. completion_tokens includes the tokens in completion_tokens_details.reasoning_tokens.

Streaming​

With "stream": true, the response arrives as server-sent events. Each event is a data: line with a chat.completion.chunk object, and the stream ends with data: [DONE]. Text arrives in choices[0].delta.content, and on reasoning models the reasoning streams first in choices[0].delta.reasoning_content.

data: {"id":"6d1a18cc...","object":"chat.completion.chunk","model":"zai-org/GLM-5.3-Flash","choices":[{"index":0,"delta":{"reasoning_content":"The user"}}]}

data: {"id":"6d1a18cc...","object":"chat.completion.chunk","model":"zai-org/GLM-5.3-Flash","choices":[{"index":0,"delta":{"content":"1, 2, 3"}}]}

data: {"id":"6d1a18cc...","object":"chat.completion.chunk","model":"zai-org/GLM-5.3-Flash","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"6d1a18cc...","object":"chat.completion.chunk","model":"zai-org/GLM-5.3-Flash","choices":[{"index":0,"delta":{}}],"usage":{"prompt_tokens":23,"completion_tokens":85,"total_tokens":108}}

data: [DONE]

The chunk with usage is only sent when you set "stream_options": {"include_usage": true}.

curl -sN https://api.entrim.ai/v1/chat/completions \
-H "Authorization: Bearer $ENTRIM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "zai-org/GLM-5.3-Flash",
"messages": [{"role": "user", "content": "Write a haiku about the Julian Alps."}],
"stream": true,
"stream_options": {"include_usage": true}
}'

Tool calling​

Tool calling lets the model ask your code to run a function. Describe each function with a JSON Schema in tools:

{
"model": "zai-org/GLM-5.3-Flash",
"messages": [{"role": "user", "content": "What is the weather in Ljubljana right now?"}],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}
]
}

When the model decides to use a tool, the response has finish_reason set to tool_calls, and the message lists the calls. arguments is a JSON-encoded string:

"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_4f81571db0a24b629241aa97",
"type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\": \"Ljubljana\"}"}
}
]
}

Run the function, then send the conversation back with the assistant message and one tool message per call. Keep the same tools in the request:

"messages": [
{"role": "user", "content": "What is the weather in Ljubljana right now?"},
{
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_4f81571db0a24b629241aa97",
"type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\": \"Ljubljana\"}"}
}
]
},
{
"role": "tool",
"tool_call_id": "call_4f81571db0a24b629241aa97",
"content": "{\"temperature_c\": 18, \"conditions\": \"partly cloudy\"}"
}
]

The model then answers using the result, for example: "It's partly cloudy in Ljubljana at 18 °C."

Set tool_choice to required to make the model call a tool, or to none to stop it from calling one.

Images​

Models that accept images take them as content parts in a user message, next to the text. Pass an https:// URL that the API can download, or embed the image as a base64 data URL:

"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "What does this image show?"},
{"type": "image_url", "image_url": {"url": "https://entrim.ai/apple-touch-icon.png"}}
]
}
]
{"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."}}

Images count toward the prompt tokens. The model library shows which models accept images.

Structured output​

To get JSON back, set response_format. json_object asks for any valid JSON object, so describe the shape you want in the prompt:

"response_format": {"type": "json_object"}

json_schema constrains the output to a schema:

"response_format": {
"type": "json_schema",
"json_schema": {
"name": "city",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"country": {"type": "string"}
},
"required": ["name", "country"],
"additionalProperties": false
}
}
}

The JSON arrives as a string in message.content, so parse it in your code.

Errors​

Errors return an HTTP status code and an error object:

{
"error": {
"message": "Authentication Error, No api key passed in.",
"type": "auth_error",
"param": "None",
"code": "401"
}
}
StatusMeaningWhat to do
400The request is invalid, for example an unknown model IDCheck the message, fix the request and don't retry it unchanged
401The API key is missing or invalidCheck the Authorization header and the key in the dashboard
429Too many requestsWait and retry with exponential backoff
5xxSomething went wrong on our sideRetry with exponential backoff