Chat & messages
Call chat completions, responses, and Anthropic messages through one gateway.
RouteMux speaks the protocols your SDK already uses. Point the base URL at the right family, pass a RouteMux model slug, and your existing client works unchanged.
| Family | Base URL | Endpoints |
|---|---|---|
| OpenAI-compatible | https://api.routemux.com/v1 | chat/completions, responses |
| Anthropic-compatible | https://api.routemux.com/anthropic | v1/messages |
| Google GenAI / Vertex | https://api.routemux.com/vertex-ai | models/{model}:generateContent |
The request and response bodies are passed through to the upstream provider.
RouteMux only reads model, stream, and a little usage metadata — it does not
rewrite your payload, so tool calls, system prompts, and message shapes behave
exactly as the provider documents them.
Chat completions (OpenAI)
curl https://api.routemux.com/v1/chat/completions \
-H "Authorization: Bearer $ROUTEMUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.5",
"messages": [{ "role": "user", "content": "Explain prepaid billing in one line." }]
}'import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.ROUTEMUX_API_KEY,
baseURL: "https://api.routemux.com/v1",
});
const completion = await client.chat.completions.create({
model: "openai/gpt-5.5",
messages: [{ role: "user", content: "Hello from RouteMux" }],
});Streaming
Set stream: true and read server-sent events as usual. RouteMux streams chunks
straight through without buffering the whole response, and bills the real usage
once the upstream finishes.
curl https://api.routemux.com/v1/chat/completions \
-H "Authorization: Bearer $ROUTEMUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.5",
"stream": true,
"messages": [{ "role": "user", "content": "Stream a haiku" }]
}'Disconnects abort upstream
If your client disconnects mid-stream, RouteMux aborts the upstream request. You are billed for usage the provider actually reported; otherwise the record is reconciled or marked failed.
Anthropic messages
The recommended Anthropic entry point is /anthropic/v1/messages. Use the
x-api-key header, just like the native Anthropic SDK.
curl https://api.routemux.com/anthropic/v1/messages \
-H "x-api-key: $ROUTEMUX_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-opus-4.8",
"max_tokens": 256,
"messages": [{ "role": "user", "content": "Hello from RouteMux" }]
}'Responses & Vertex
- Responses:
POST /v1/responses(or the short aliasPOST /responses) for clients built on the OpenAI Responses protocol. - Vertex / Gemini: point at
https://api.routemux.com/vertex-aiand call:generateContent/:streamGenerateContentwith the model in the path.
To see which protocols a given model supports, filter the catalog —
/v1/models?protocol=anthropic_messages. See Models & discovery
for the full filter list.
Image and video input
Image and video take different endpoints on RouteMux. This trips people up more often than model support does:
| Input | /v1/chat/completions (OpenAI-compatible) | /vertex-ai/v1beta/...:generateContent (native Gemini) |
|---|---|---|
| Image | Supported | Supported |
| Video | Not supported | Supported |
The limit is not the model — every Gemini model can read video. It is the
OpenAI request schema, which has no video part: content[] defines text,
image_url and input_audio, with nowhere to put a clip.
⚠️ One failure mode is worth knowing about: if you push a video into an OpenAI-shaped
request directly against a provider, it does not error. The video is dropped, the
model answers from your text alone, and you get a 200 with a plausible-looking answer.
RouteMux rejects those requests before billing and before touching the upstream,
returning 400 REQUEST_VIDEO_INPUT_ENDPOINT_UNSUPPORTED and naming the endpoint to use.
Send video to the native endpoint, with the clip in inline_data:
curl -X POST "https://api.routemux.com/vertex-ai/v1beta/models/google/gemini-3.5-flash:generateContent" \
-H "Authorization: Bearer $ROUTEMUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"role": "user",
"parts": [
{"inline_data": {"mime_type": "video/mp4", "data": "<base64>"}},
{"text": "Which colors appear in this video, in order?"}
]
}]
}'Metering follows Google: roughly 300 tokens per second of video at default resolution (258 per frame plus 32 per second of audio). Video tokens are priced the same as text — there is no separate video rate.
To find models that read video, look for the "Video input" capability on a model page,
or filter the catalog via /v1/models.