API
Chat Completions
POST /v1/chat/completions takes OpenAI's request body and returns OpenAI's response shape.
POST /v1/chat/completions takes the same body as OpenAI's Chat Completions API and returns the same shape. Every text model on sale answers on this route.
Request body
| Parameter | Type | Description | |
|---|---|---|---|
model | string | required | A slug from the model list, for example qwen/qwen3.8-flash. |
messages | array | required | The conversation so far, as OpenAI { role, content } objects. |
max_tokens | integer | Upper bound on output tokens, reasoning included. | |
temperature | number | Sampling temperature. | |
tools | array | Functions the model may call, in OpenAI's function tool format. | |
tool_choice | string or object | auto lets the model decide. Forcing a call with required or a named function depends on the model: qwen/qwen3.8-flash refuses both with 400 while it reasons. | |
response_format | object | Ask for JSON output, as in OpenAI's API. | |
stream | boolean | Send the reply as server-sent events. See Streaming. |
Only function tools are accepted. Server-side tools that cost extra, such as web search, are refused with 400 unsupported_paid_feature.
Example
curl https://api.azrouter.dev/v1/chat/completions \
-H "Authorization: Bearer $AZROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen/qwen3.8-flash",
"messages": [{"role": "user", "content": "Reply with exactly: Hello from AZRouter"}],
"max_tokens": 200
}'Response (abridged):
{
"object": "chat.completion",
"model": "qwen/qwen3.8-flash",
"choices": [
{
"index": 0,
"finish_reason": "stop",
"message": {"role": "assistant", "content": "Hello from AZRouter"}
}
],
"usage": {
"prompt_tokens": 69,
"completion_tokens": 34,
"total_tokens": 103,
"prompt_tokens_details": {"cached_tokens": 0},
"completion_tokens_details": {"reasoning_tokens": 27}
}
}Reasoning models also return the model's thinking in message.reasoning. The response can carry other fields that OpenAI's doesn't; ignore any you don't use.
Tool calls
Describe your functions in tools. When the model wants one, the reply has finish_reason: "tool_calls" and the call in message.tool_calls.
curl https://api.azrouter.dev/v1/chat/completions \
-H "Authorization: Bearer $AZROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen/qwen3.8-flash",
"messages": [{"role": "user", "content": "What is the weather in Bangkok?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}],
"max_tokens": 300
}'Response (abridged):
{
"finish_reason": "tool_calls",
"message": {
"role": "assistant",
"tool_calls": [
{
"type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\": \"Bangkok\"}"}
}
]
}
}Run the function yourself, then send its result back as a {"role": "tool", "tool_call_id": ..., "content": ...} message in the next request.