Chat Completions API
The /v1/chat/completions endpoint is a drop-in replacement for OpenAI's chat API. Use any OpenAI-compatible SDK against any provider's model.
POST /v1/chat/completions accepts the OpenAI chat-completions request shape and
forwards it to one of your enabled upstreams. Use it as a drop-in replacement:
point your base_url at https://api.ada.ai/v1 and use your proxy key
(sk-rc-…) as the API key.
Authentication
Send the proxy key in the Authorization header (or X-API-Key):
Authorization: Bearer sk-rc-...Never use a Stytch session JWT or an admin token on /v1/*. See
API keys.
Request
curl https://api.ada.ai/v1/chat/completions \
-H "Authorization: Bearer sk-rc-..." \
-H "Content-Type: application/json" \
-d '{
"model": "swiss-ai/Apertus-70B-Instruct-2509",
"messages": [
{ "role": "system", "content": "You are a concise assistant." },
{ "role": "user", "content": "Explain routing in one sentence." }
],
"max_tokens": 200
}'The body follows OpenAI's schema. The fields that matter:
| Field | Required | Notes |
|---|---|---|
model | yes | Must match a model ID from one of your enabled upstreams. See Models & routing. No silent substitution — a missing model is an error. |
messages | yes | OpenAI message array (system / user / assistant / tool). |
max_tokens | no | Cap on output tokens. |
temperature, top_p | no | Sampling. |
stream | no | true returns SSE chunks. |
tools, tool_choice | no | OpenAI-style function calling. |
stop | no | Stop sequences. |
Response
A standard OpenAI chat-completion object:
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "swiss-ai/Apertus-70B-Instruct-2509",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Ada AI tries the highest-priority upstream that serves a model, failing over on 5xx." },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 24, "completion_tokens": 19, "total_tokens": 43 }
}Streaming
Set "stream": true to receive Server-Sent Events in OpenAI's format
(data: {chunk} lines, terminated by data: [DONE]):
curl https://api.ada.ai/v1/chat/completions \
-H "Authorization: Bearer sk-rc-..." \
-H "Content-Type: application/json" \
-d '{
"model": "glm-4.7",
"stream": true,
"messages": [{"role": "user", "content": "Count to five."}]
}'data: {"choices":[{"delta":{"content":"1"}, ...}]}
data: {"choices":[{"delta":{"content":"2"}, ...}]}
...
data: [DONE]Tool calls
OpenAI-style function calling is passed through. The proxy does not invent or modify tool definitions.
curl https://api.ada.ai/v1/chat/completions \
-H "Authorization: Bearer sk-rc-..." \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen3.6-35B-A3B-FP8",
"messages": [{"role": "user", "content": "What is the weather in Zurich?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"parameters": { "type": "object", "properties": { "city": { "type": "string" } } }
}
}]
}'Which model do I send?
The model value must exactly match an ID your key's owner has enabled. To see
what's available:
curl https://api.ada.ai/v1/models \
-H "Authorization: Bearer sk-rc-..."See Models & routing for how the proxy chooses among upstreams that expose the same model, Errors for the full status-code reference, and Coding agents to drive Pi and OpenCode against this endpoint.
Using reasoning models
Some models on Ada AI (for example Qwen/Qwen3.6-35B-A3B-FP8 and the
*-thinking variants) return a reasoning_content field alongside content.
To turn thinking off for Qwen-family models, send
chat_template_kwargs: { "enable_thinking": false } — this makes responses
faster and cheaper when you don't need the chain of thought:
{
"model": "Qwen/Qwen3.6-35B-A3B-FP8",
"messages": [{"role": "user", "content": "Hi"}],
"chat_template_kwargs": { "enable_thinking": false }
}Coding agents
Point coding agents like Pi, OpenCode, and Codex at Ada AI so every request flows through your proxy key, your upstreams, and your routing rules.
Anthropic Messages API
Use /v1/messages to call any model with the Anthropic SDK. The proxy translates requests to OpenAI chat-completions and back.