Model routing

Route Multiple AI Models Through One API: One Key, Any Model

Use a single OpenAI-compatible Base URL and API key to route Claude, Gemini, DeepSeek and other models. Setup, model switching, cost checks, and failure handling.

One key for every model

Routing multiple AI models through one API means your application keeps a single Base URL, a single API key, and a single request shape, while the model field decides which upstream provider handles the call. You do not store one credential per vendor, and you do not rewrite the client when a new model appears.

The practical benefit is operational: one billing balance, one place to rotate a leaked key, one set of logs, and one place to change a model. The trade-off is that the gateway now sits in the request path, so you must verify what it forwards and how it counts tokens. This guide shows the smallest useful setup, how to call different model families with the same key, and how to check the result against your bill.

What happens after you send a model name

A request usually carries four things that matter for routing: the model identifier, the message or prompt payload, the streaming flag, and optional feature fields such as tool definitions or cache controls. The gateway resolves the model identifier to an enabled channel and price group, converts the request into that provider's native protocol, and converts the response back into the format your SDK expects.

Two details are worth confirming before production. First, model names are versioned: a name that works in a playground may not exist on your key's group. Second, routing is not free abstraction — features such as prompt caching, tool calling, structured output, and reasoning tokens are only equivalent if the gateway forwards them. Test the specific features you depend on instead of assuming compatibility from a successful text response.

Fields that decide which route runs
FieldWhat it controls
modelWhich provider channel and price group handles the request
messages / inputContext sent upstream, and the main driver of input tokens
streamWhether the response is Server-Sent Events or one JSON body
tools, response_formatWhether the gateway must forward a provider-specific feature

Set up one key and send your first request

Create a key in API Access, then confirm the model you intend to use on the pricing page. Use the OpenAI-compatible endpoint for a first check even when the target model is not an OpenAI model: the gateway converts the request. Keep the first call small, with a low output limit and no tools or caching.

Set the key as an environment variable rather than hard-coding it. On macOS or Linux, export API_ROUTE_KEY=... applies to the current shell only; on Windows PowerShell, use $env:API_ROUTE_KEY="...". The example below sends a single chat completion and prints whatever the model returns.

export API_ROUTE_KEY="sk-your-key"
curl https://global.api-route.com/v1/chat/completions \
  -H "Authorization: Bearer $API_ROUTE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [{"role": "user", "content": "Name one trade-off of multi-model routing."}],
    "max_tokens": 80
  }'

A 200 response with a choices array means the request reached a provider and came back. It does not yet prove that streaming, tools, caching, or a second model family works. Add those checks one at a time, using the response body to confirm the model name and the usage object.

Switch model families without switching SDKs

The same key can call Claude, Gemini, DeepSeek, Qwen, and other model families because the gateway converts between protocols. For chat-shaped traffic, send every request to /v1/chat/completions and change only the model value. The request and response shapes stay the OpenAI-compatible ones your code already handles.

When you need Anthropic-specific behaviour such as prompt caching or a particular beta header, call /v1/messages with that model instead and use the Anthropic request format. Both endpoints share the same account balance, which is what makes a single-key setup practical. Cross-model API references: OpenAI Chat Completions and Anthropic Messages.

from openai import OpenAI

client = OpenAI(
    base_url="https://global.api-route.com/v1",
    api_key="sk-your-key",
)

for model in ["claude-sonnet-4-6", "gemini-3.8-flash", "deepseek-v4.1-flash"]:
    reply = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": "Reply in one sentence."}],
        max_tokens=60,
    )
    print(model, "->", reply.choices[0].message.content)
const models = ["claude-sonnet-4-6", "gemini-3.8-flash"];

for (const model of models) {
  const res = await fetch("https://global.api-route.com/v1/chat/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.API_ROUTE_KEY}`,
    },
    body: JSON.stringify({
      model,
      messages: [{ role: "user", content: "Reply in one sentence." }],
      max_tokens: 60,
    }),
  });
  const data = await res.json();
  console.log(model, "->", data.choices?.[0]?.message?.content ?? data.error?.message);
}

Two models in one loop is enough to prove the routing layer is doing what you expect. Log the returned model name and the usage object for each call; if a model silently falls back to another family, the text may still look plausible while quality and price change.

Choose a model per request, not per project

Once one key reaches every model, the interesting decision moves from "which vendor do we sign with" to "which model should handle this request". Classify your traffic first: short classification and extraction calls rarely need a frontier model, long-context analysis does, and code generation usually needs a different trade-off than chat. Route by task, then measure quality on your own evaluation set rather than on benchmark headlines.

Price groups matter as much as model names. A model can be listed at one rate for a default group and another for a discounted or enterprise group, and the group attached to your key determines what you actually pay. Check the group shown on the pricing page and in your call logs before you build a budget around a headline number.

A practical starting point for model routing
WorkloadWhat to optimiseTypical choice
Classification, extraction, taggingCost per thousand callsSmall fast model
Long-context analysis, RAG answersContext window and cache costMid-tier model with prompt caching
Complex coding and agent loopsCorrectness and tool useFrontier model, low temperature
Bulk generationOutput price and throughputMid-tier model with batching

Verify the route and the bill

Before scaling, confirm three things: the same key can list the models you plan to call, the response returns the model you asked for, and the logged charge matches the usage object. Listing models is the cheapest check and catches keys bound to a narrow group.

curl -s https://global.api-route.com/v1/models \
  -H "Authorization: Bearer $API_ROUTE_KEY" \
  | jq -r '.data[].id' | sort

Then compare a single response with the matching row in call logs. Check the model, the input and output token categories, and whether any cache fields are present. A cached request should report cache reads separately; if the gateway never reports them, treat the cache as unverified rather than as a discount. Keep one recorded request per model family as a reference sample so a future price or routing change is visible.

Common failures and what they mean

Most first-week problems are configuration, not model quality. The table below maps the errors worth checking first. When reporting an issue, include the request time, HTTP status, model name, and request ID, and never paste the key itself.

Routing errors and first checks
SymptomLikely causeFirst check
404 model not foundModel not enabled for your key groupList models with /v1/models, then compare with the pricing page
401 or 403Key missing, revoked, or sent in the wrong headerSend Authorization: Bearer, and rotate the key if it was exposed
400 on a schema fieldProvider rejects a keyword the gateway did not translateRemove the field and retest; report the exact parameter
Streaming stalls or arrives at onceProxy buffering or an unsupported stream flagRetest without stream, then with a short prompt
Costs higher than expectedDifferent price group, or cache writes instead of readsCompare usage with the log row and confirm the group

If the response is a 200 but behaves like a different model, compare outputs on a fixed prompt across a few requests and check the returned model name. Consistency problems usually point at routing or fallback policy, not at the prompt.

Production checklist

  1. Store the key in a secret manager or environment variable, and keep a second key ready for rotation.
  2. Pin explicit model identifiers instead of floating aliases, and record the version you tested.
  3. Send a fixed smoke request per model family after every configuration change.
  4. Alert on error rate and on cost per request, not only on total spend.
  5. Compare the first bill against the usage objects you logged before scaling traffic.

With those five checks in place, one key and one Base URL are enough to route traffic across model families without rebuilding your client. Start with a small balance, create an account, confirm the model list for your key, and follow the quickstart for the first request.