Compatibility matrix
Which base URL a client needs, and which protocols each model family is served on.
Two things account for almost every failed first request: the shape of the base URL and whether the model is served on the protocol the client speaks. This page is the short version of both.
Why base URLs disagree between clients
The gateway accepts Anthropic Messages at three paths, all equivalent:
/v1/messages
/anthropic/v1/messages
/v1/v1/messages ← tolerated, for clients configured with a trailing /v1So the base URL you enter is not a fixed string — it depends on what your client appends to it. Work backwards from the final path:
| Your client appends | Base URL to enter |
|---|---|
/v1/messages (official Anthropic SDK — Claude Code, Pi, OpenClaw) | https://api.routemux.com |
/messages (Vercel AI SDK's Anthropic provider — OpenCode) | https://api.routemux.com/v1 |
/chat/completions or /responses (OpenAI clients) | https://api.routemux.com/v1 |
| the full path, nothing appended | https://api.routemux.com/v1/chat/completions |
| Gemini / Vertex operations | https://api.routemux.com/vertex-ai |
The single most common mistake
Putting /v1 on an Anthropic base URL that already appends /v1/messages. It produces
/v1/v1/messages, which we route correctly anyway — so this one usually works and is not
what breaks people. The reverse — omitting /v1 where the client appends only an
operation name — produces a 404 on every request.
Protocol availability by model family
A model is reachable only on the protocols it is actually served on. GET /v1/models is
authoritative for your key; the family-level picture is:
| Model family | OpenAI Chat | OpenAI Responses | Anthropic Messages | Vertex |
|---|---|---|---|---|
anthropic/claude-* | — | — | ✅ | — |
openai/gpt-5.*, gpt-6-* | ✅ | ✅ | ✅ | — |
deepseek/* | ✅ | ✅ | ✅ | — |
minimax/minimax-m* | ✅ | ✅ | ✅ | — |
zhipu/glm-* | ✅ | ✅ | ✅ | — |
google/gemini-* (text) | ✅ | — | — | ✅ |
google/gemini-* (image) | — | — | — | ✅ |
xai/grok-4.5 | ✅ | — | — | — |
xai/grok-4.6 | ✅ | ✅ | — | — |
Two consequences worth pulling out:
- Gemini text models are on two protocols. You can call them from a plain OpenAI client or from a Gemini/Vertex client. Gemini image models are Vertex-only.
- No Grok model is on Anthropic Messages. A Claude-Code-shaped client cannot reach Grok here, whatever the base URL says.
Image, video and music models are not on the three text protocols at all — they have their own endpoints, and Sora/Hailuo/music go through the video and music paths.
Calling a model on a protocol it is not served on returns
400 MODEL_PROTOCOL_UNSUPPORTED. The two combinations that
actually occur in practice:
- A Claude slug on
/v1/chat/completions. Most often an editor or chat client configured with its generic "OpenAI Compatible" provider. Use the client's Anthropic provider instead. - A Gemini slug on
/v1/messagesor/v1/responses. Gemini text models are served on OpenAI Chat here.
Per-client summary
Only clients with a guide on this site are listed; each page carries the exact config keys.
| Client | Protocol it sends | Base URL | Notes |
|---|---|---|---|
| Claude Code | Anthropic Messages | bare origin | ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN |
| Codex CLI | OpenAI Responses only | + /v1 | Custom provider in ~/.codex/config.toml; no Chat Completions mode |
| OpenCode | either, per provider block | + /v1 both ways | The npm field selects the protocol |
| Pi | all four, per provider | bare origin for Anthropic, + /v1 for OpenAI | The api field picks the protocol |
| OpenClaw | all four, per provider | same as Pi | Config lives under models.providers |
| Hermes Agent | three, per provider | + /v1 for all of them | Normalises a trailing /v1; api_mode picks the protocol |
| Cline | either, per provider type | bare origin for Anthropic, + /v1 for OpenAI | Claude models need the Anthropic provider |
| Cursor | OpenAI Chat | + /v1 | Chat models only; requests leave from Cursor's servers |
| Gemini CLI | Vertex | + /vertex-ai | Uses a Google-style base URL variable |
| CC Switch | fixed per target app | written for you | Protocol is hardcoded per app in the importer |
Model ids
GET /v1/models returns exactly what your key can call. Dialects that resolve:
- bare name ↔
anthropic/openai/google/prefixed form - dashed ↔ dotted version numbers (
claude-sonnet-4-6andclaude-sonnet-4.6) - a trailing
-YYYYMMDDdate snapshot is ignored - a trailing
[1m]context marker is ignored
What does not resolve, and shows up regularly in real traffic: a trailing space from a
shell variable, an unexpanded variable name sent literally, a URL-encoded slash (%2F), a
promotional label pasted in along with the model name, and a model version we do not carry.
Auth headers
Authorization: Bearer, x-api-key and x-goog-api-key are all accepted. Sending the same
key in two of them is fine — they are de-duplicated by value. Sending two different values
returns 400 AUTH_AMBIGUOUS_API_KEY; clear whichever field you
are not using.
Timeouts
- Streaming requests have no total time limit.
- There is an idle watchdog: 180 s for text, longer for image and video. No new chunk within that window aborts the request and records a timeout.
- The budget for the upstream's first response header scales with request body size, so very large conversations get more grace than small ones.