Provider Routing
Choose, order and exclude the providers that serve a model, or let OhMyGPT pick.
Many models are served by more than one provider. zhipu/glm-5.3-flash, for example:
curl -s https://api.ohmygpt.com/v1/models/zhipu/glm-5.3-flash | jq -r '.providers[].provider'chatglm
tencentYou don't have to choose: by default OhMyGPT picks a provider for each request by weighing price against speed and reliability, and keeps a conversation with the provider that already holds its prompt cache. If that provider fails before answering, the request goes to the next one. When you do want a say, for example the cheapest provider or a fixed fallback order, add a top-level provider object on /v1/chat/completions or /v1/responses:
curl https://api.ohmygpt.com/v1/chat/completions \
-H "Authorization: Bearer $OHMYGPT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "zhipu/glm-5.3-flash",
"messages": [{"role": "user", "content": "Hi"}],
"provider": {"order": ["chatglm"]}
}'Fields
| Field | Type | Effect |
|---|---|---|
order | string[] | Try these providers first, in this order. The model's other providers stay available as fallbacks. |
only | string[] | Use only these providers. |
ignore | string[] | Never use these providers. |
allow_fallbacks | boolean | Defaults to true. With false, only the providers in order are used; without order, only the first-ranked provider is used. |
sort | string or object | Prefer providers by price (lowest cost for this request), latency (fastest time to first token) or throughput (most tokens per second). The object form {"by": "price"} works too. |
Use the slugs from the model's providers[].provider list; case doesn't matter. OpenRouter's provider slugs work too: amazon-bedrock, google-vertex, google-ai-studio, claude-on-aws, moonshotai, z-ai and seed mean bedrock, vertex, google, anthropic_aws, moonshot, chatglm and bytedance. Keep at least one of the model's providers in only, and don't ignore all of them: a request that leaves no provider is rejected with 400 invalid_parameter, naming provider.only or provider.ignore (or provider.order when allow_fallbacks is false). With both order and sort, the providers in order come first and sort ranks the rest.
To see which provider served a request, look it up by its X-Request-ID. The receipt's model.provider field names it.
From the OpenAI SDKs
Pass provider as an extra body field:
completion = client.chat.completions.create(
model="zhipu/glm-5.3-flash",
messages=[{"role": "user", "content": "Hi"}],
extra_body={"provider": {"order": ["chatglm"]}},
)Pin a provider in the model ID
Prefix the model ID with a provider slug: tencent:zhipu/glm-5.3-flash sends the request to Tencent only, like "only": ["tencent"]. The prefix works on every endpoint. On /v1/messages and the Gemini endpoint it is the way to choose a provider; leave the provider object out there.
Models routed by OhMyGPT
For models with managed_routing: true in the model list, OhMyGPT picks the provider for you. Call them by their plain ID, without a prefix or a provider object; if you send one, its choices are ignored. The charge on each response reflects the provider that served it.
Migrating from OpenRouter
| OpenRouter | OhMyGPT |
|---|---|
model: "x:floor" | "provider": {"sort": "price"} |
model: "x:nitro" | "provider": {"sort": "throughput"} |
"provider": {"order": [...]} | Same field, with OpenRouter's slugs |
"provider": {"only": [...]}, "ignore": [...] | Same fields, with OpenRouter's slugs |
"provider": {"allow_fallbacks": false} | Same field |
"provider": {"sort": {"by": "price"}} | Same field |
models: [...] fallback list | Pick one model; fallback across its providers is automatic |
Send model IDs exactly as listed, with no suffix. Leave out other provider fields such as zdr, data_collection, max_price and quantizations; requests that set them are rejected with 400 unsupported_parameter.
An invalid value names the field to fix:
{
"error": {
"param": "provider.sort",
"code": "invalid_parameter",
"message": "Invalid `provider.sort`: must be one of `price`, `latency`, `throughput`, not `speed`.",
"type": "invalid_request_error"
}
}