Connect, make requests, and handle responses.
Create or use an existing API key, then set it in your server environment. Add credit in Billing when you need more.
export ISOQUANT_API_KEY="YOUR_ISOQUANT_API_KEY"https://api.isoquant.ai/v1glm-5.3-flashAuthorization: Bearer $ISOQUANT_API_KEYYou can also send the key in x-api-key. Messages requires anthropic-version: 2023-06-01.
/v1/chat/completionscurl -sS "https://api.isoquant.ai/v1/chat/completions" \
-H "Authorization: Bearer $ISOQUANT_API_KEY" \
-H "Isoquant-ZDR: required" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role":"user","content":"Hello!"}],
"max_tokens": 4096,
"reasoning_effort": "low"
}'Send JSON in the request body. Query parameters are not supported.
Require ZDR adds Isoquant-ZDR: required. It requires zero data retention for the request; turning it off omits the requirement. Usage and billing metadata are still recorded.
GLM reasoning is always on, with Low, High and Max effort levels. It shares the 4096-token example allowance with the final answer. Show reasoning controls the returned trace; hiding it does not disable reasoning or change token charges.
Accepts text and image input. Structured outputs: json_object, json_schema, regex, ebnf. Strict function tools are supported.
| Field | Type | Usage |
|---|---|---|
modelRequired | string | An available model ID from /v1/models. |
messagesRequired | array | Conversation messages, including prior assistant replies and tool results. |
max_tokensOptional | integer | Positive output-token limit. Set a limit to bound the credit reservation. |
streamOptional | boolean | Set true for server-sent events. Defaults to false. |
stream_optionsOptional | object | Set include_usage to true to receive the final usage-only streaming event. |
toolsOptional | array | Function tools with a name and parameters. Your application executes them. |
tool_choiceOptional | string | object | Use auto, required, none, or a named function. |
temperatureOptional | number | Sampling temperature. Omit it to use the model default. |
reasoning_effortOptional | string | Use low, high, or max; default max. GLM reasoning is always on. |
include_reasoningOptional | boolean | Set false to hide reasoning fields and stream events. Reasoning still counts toward output usage and the output allowance. |
parallel_tool_callsOptional | boolean | False allows at most one tool call; true allows multiple calls. |
response_formatOptional | object | Use json_object or json_schema. A schema applies to assistant text; strict tool schemas apply to tool arguments. |
regex / ebnfOptional | string | Constrain assistant text. grammar aliases ebnf; structured_outputs accepts regex, ebnf or grammar. Conflicting constraints are rejected. |
max_completion_tokens / max_output_tokensOptional | integer | Aliases of max_tokens. All spellings bound actual output, including reasoning. Conflicting limits are rejected. |
Read text from choices[].message.content and tool calls from choices[].message.tool_calls. Check finish_reason; length means the output limit was reached.
Keep the x-request-id response header when reporting a problem. Messages also returns request-id.
Use messages and client function tools. Supported fields follow the selected model; an OpenAI-compatible endpoint does not imply every OpenAI feature.
Choose your client and model below for setup instructions and connection settings.
model = "glm-5.3-flash"
model_provider = "isoquant"
model_reasoning_effort = "low"
model_reasoning_summary = "none"
web_search = "disabled"
[model_providers.isoquant]
name = "Isoquant"
base_url = "https://api.isoquant.ai/v1"
env_key = "ISOQUANT_API_KEY"
wire_api = "responses"
supports_websockets = false
http_headers = { "Isoquant-ZDR" = "required" }~/.codex/config.toml Setup guide
Public model discovery does not require a key. Include your API key to list the models available to your account. See Models for prices and context lengths.
/v1/modelscurl -sS "https://api.isoquant.ai/v1/models" \
-H "Authorization: Bearer $ISOQUANT_API_KEY"The response is {"object":"list","data":[…]}. Each entry includes id, object, created, and owned_by.
Set stream: true to receive server-sent events. With cURL, -N disables output buffering.
| API | Read until | Usage |
|---|---|---|
| Chat Completions | [DONE] | Set stream_options.include_usage: true for the final usage chunk. |
| Messages | message_stop | Read input usage in message_start and final output usage in message_delta. |
| Responses | response.completed, response.incomplete, or response.failed | Read usage and check response.status, including on response.completed. |
Check for errors and the expected terminal event. A closed connection or HTTP 200 alone does not mean generation completed.
curl -sS -N "https://api.isoquant.ai/v1/chat/completions" \
-H "Authorization: Bearer $ISOQUANT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [
{
"role": "user",
"content": "Hello!"
}
],
"max_tokens": 1024,
"stream": true,
"stream_options": {
"include_usage": true
}
}'Describe your functions in tools. Run returned calls in your application, then send the results with the original conversation and returned call IDs.
When streaming, assemble argument fragments before running a function. Preserve returned assistant content, including reasoning when present.
Set parallel_tool_calls: false for at most one call; true allows multiple calls. Strict tools enforce their argument schemas. A response schema constrains assistant text and can be combined with tools.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.isoquant.ai/v1",
api_key=os.environ["ISOQUANT_API_KEY"],
)
model = "glm-5.3-flash"
def lookup_order(name, arguments, call_id):
if not call_id or name != "lookup_order" or arguments != {"id": "A"}:
raise ValueError("Unexpected tool call")
return json.dumps({"id": "A", "status": "shipped"})
schema = {
"type": "object", "properties": {"id": {"type": "string"}},
"required": ["id"], "additionalProperties": False,
}
tools = [{"type": "function", "function": {
"name": "lookup_order", "parameters": schema,
}}]
messages = [{"role": "user", "content": "Look up order A."}]
response = client.chat.completions.create(
model=model, messages=messages, tools=tools, max_tokens=1024,
tool_choice={"type": "function", "function": {"name": "lookup_order"}},
)
assistant = response.choices[0].message
if response.choices[0].finish_reason != "tool_calls" or not assistant.tool_calls:
raise RuntimeError("No complete tool call returned")
messages.append(assistant.model_dump(exclude_none=True))
for call in assistant.tool_calls:
result = lookup_order(call.function.name, json.loads(call.function.arguments), call.id)
messages.append({"role": "tool", "tool_call_id": call.id, "content": result})
response = client.chat.completions.create(
model=model, messages=messages, tools=tools, max_tokens=1024,
tool_choice="none",
)
print(response.choices[0].message.content)Check the HTTP status and response body. Keep x-request-id to identify the request.
| Status | Meaning | What to do |
|---|---|---|
400 | Invalid request | Check the request fields, context length, and API compatibility notes. |
401 | Invalid API key | Use an active key from API keys. |
402 | Insufficient credit | Add credit or lower the requested output limit. |
403 | Access denied | Check that the exact model ID appears in GET /v1/models for your key. |
404 / 405 | Route or method | Use a listed endpoint with its exact HTTP method. |
413 / 415 | Request size or content | Reduce the body size; send uncompressed application/json. |
429 | Capacity limit | Honor Retry-After, then retry with bounded backoff. |
502 / 503 / 504 | Temporary failure | Retry with bounded backoff; keep the request ID if failures persist. |
Fix invalid requests before retrying. Retrying starts a new request.
{
"error": {
"message": "Valid Bearer or x-api-key authentication required",
"type": "gateway_error",
"code": "invalid_api_key"
}
}Messages uses error.type; gateway Chat and Responses errors also include error.code. Upstream errors may use a different shape.
Set max_tokens explicitly. The input and output must fit the model’s context window (1,048,576 tokens for GLM-5.3-Flash).
Repeated prompt prefixes can use the cache automatically. Reported hits receive the model’s cached input rate.