OpenRouter compatibility

Which OpenRouter conventions BigModel.io supports. provider/model names, routing suffixes, the models fallback array, HTTP-Referer and X-Title, and what is ignored.

On this page
  1. How model names are resolved
  2. Fallback with the models array
  3. App attribution headers
  4. What is not supported
  5. Verify the setup
  6. Troubleshooting
  7. Related

BigModel.io understands the main OpenRouter request conventions on /v1/chat/completions, /v1/messages and /v1/responses. This page is the exact reference; for a step-by-step switch, see Migrate from OpenRouter.

OpenRouter feature On BigModel.io
provider/model IDs, e.g. z-ai/glm-5.3 Supported: resolved to a model your group serves
Routing suffixes :nitro, :floor, :exacto Removed if the exact name is not served
:free suffix Kept; never removed
models fallback array Supported, up to 5 models per request
HTTP-Referer, X-Title, X-OpenRouter-Title Recorded for app attribution
provider object, transforms, route Not supported

#How model names are resolved

Plain names without / or : (such as glm-5.3) are used as they are. For other names, the gateway checks whether your key's group explicitly serves the name, then tries these variants in order and uses the first one served:

  1. The exact name: z-ai/glm-5.3:nitro
  2. Without the routing suffix: z-ai/glm-5.3
  3. Without the provider/ prefix as well: glm-5.3
  4. Step 2 with dots replaced by dashes: z-ai/glm-5-3
  5. Step 3 with dots replaced by dashes: glm-5-3

Details:

  • Only :nitro, :floor and :exacto are removed, case-insensitively. A :free request is never served by a paid model.
  • Only a single provider/ prefix is removed. A name with two slashes keeps its prefix.
  • "Served" means the group lists the model or has a price for it.
  • If nothing matches, the original name is sent on, and you get the normal unknown-model error: 503 api_error "No available accounts". See Model IDs.

#Fallback with the models array

models is an ordered list of models to try if model fails.

cURL
curl https://bigmodel.io/v1/chat/completions \
  -H "Authorization: Bearer $BIGMODEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k3",
    "models": ["glm-5.3", "deepseek-v4-pro"],
    "messages": [{"role": "user", "content": "Summarize this diff."}]
  }'
Python
import os
from openai import OpenAI

client = OpenAI(base_url="https://bigmodel.io/v1", api_key=os.environ["BIGMODEL_API_KEY"])

completion = client.chat.completions.create(
    model="kimi-k3",
    messages=[{"role": "user", "content": "Summarize this diff."}],
    extra_body={"models": ["glm-5.3", "deepseek-v4-pro"]},
)
print(completion.model, completion.choices[0].message.content)
Node.js
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://bigmodel.io/v1", apiKey: process.env.BIGMODEL_API_KEY });

const completion = await client.chat.completions.create({
  model: "kimi-k3",
  models: ["glm-5.3", "deepseek-v4-pro"],
  messages: [{ role: "user", content: "Summarize this diff." }],
});
console.log(completion.model, completion.choices[0].message.content);

The rules:

  • Candidates. model first, then models in order. Duplicates are skipped, non-string entries are ignored, and at most 5 candidates are tried in total; the rest are dropped. Each candidate is name-resolved as above.
  • When the next model is tried. Only when an attempt fails with 404, 408, 429 or any 5xx before any response bytes are sent.
  • When it is not. 400, 401, 402, 403 and 413 are returned right away, because they would fail for every model. Once any byte has been sent, including an SSE keep-alive ping, the response is committed and no other model is tried.
  • If every candidate fails. You get the last candidate's error.
  • Forwarding. The models field is removed before the request goes upstream.
  • Billing. You are charged only for the attempt that succeeds.

#App attribution headers

Send HTTP-Referer (your app's URL) and X-Title (its name) as on OpenRouter. X-OpenRouter-Title is accepted when X-Title is absent. They do not change routing or price. What is recorded: App attribution.

#What is not supported

  • provider object (order, allow_fallbacks, only, ignore, sort, price limits and so on). Not interpreted. Your key's group decides which upstream serves the model.
  • transforms (for example middle-out). Not interpreted; long prompts are not compressed for you.
  • route (for example "fallback"). Not interpreted; use the models array.

Remove these fields. On GLM and DeepSeek groups the request body is forwarded unchanged apart from model, so a provider may reject unknown fields.

Other OpenRouter-only features, such as its credits endpoints or generation lookups, do not exist on BigModel.io. Use GET /v1/usage for key usage and the Usage page for per-request records.

#Verify the setup

Send the fallback example with a deliberately wrong first model, for example "model": "kimi-k3-typo". The request should still succeed, and in Usage the request should show glm-5.3 (the first fallback) as its model, with only the successful attempt charged.

#Troubleshooting

503 "No available accounts" with a provider/model name. None of the variants is served by your key's group. Use the plain ID from the catalog.

Fallback does not happen. The first model failed with a code that does not trigger fallback (400, 401, 402, 403, 413), or the stream had already started. Check the status code.

Only some fallback models are tried. At most 5 candidates are used, counting model. Shorten the list.

400 mentioning provider, transforms or route. The upstream rejected a field BigModel.io does not interpret. Remove it.

A :free model is not found. :free is never stripped. Use an ID that exists in the catalog.

Updated · View as Markdown