Ada AI

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:

FieldRequiredNotes
modelyesMust match a model ID from one of your enabled upstreams. See Models & routing. No silent substitution — a missing model is an error.
messagesyesOpenAI message array (system / user / assistant / tool).
max_tokensnoCap on output tokens.
temperature, top_pnoSampling.
streamnotrue returns SSE chunks.
tools, tool_choicenoOpenAI-style function calling.
stopnoStop 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 }
}

On this page