Provider selection
Use the provider object to control which provider and endpoint serve a single request. Its fields are compatible with OpenRouter's provider object, so most settings carry over unchanged; differences are listed at the end.
How to send it
- OpenAI protocol: in the
providerfield of the request body. - All three protocols: the
X-ModelPortal-Provider-Preferencesheader, whose value is a JSON object with the same fields asprovider, at most 4096 bytes. The official Anthropic and Gemini SDKs make extra body fields awkward, so the header is the easy route there. - If both the body and the header carry preferences, you get 400
invalid_request; the platform does not merge them. provideris for the platform only: it is removed before the request goes to a provider, and the header is never forwarded.
curl https://modelportal.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_ID",
"messages": [{"role": "user", "content": "Hello"}],
"provider": {"order": ["PROVIDER_ID"], "data_collection": "deny"}
}'
curl https://modelportal.ai/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-H 'X-ModelPortal-Provider-Preferences: {"only": ["PROVIDER_ID"]}' \
-d '{"model": "MODEL_ID", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hello"}]}'
Fields
| Field | Type | Meaning |
|---|---|---|
order |
string array | Provider or endpoint identifiers to try first, in order; other endpoints follow by the default rules. For a provider identifier, its endpoints are still ordered by the default rules |
only |
string array | Allow only these providers or endpoints |
ignore |
string array | Exclude these providers or endpoints |
allow_fallbacks |
boolean | Whether to switch between endpoints of the same model; defaults to false. See Fallbacks |
sort |
string | price (comparison price ascending), latency (median time to first token over the last hour, ascending), throughput (median throughput over the last hour, descending) |
data_collection |
string | allow (default) or deny; see Data policy |
quantizations |
string array | Allowed quantizations: int4, int8, fp4, fp6, fp8, fp16, bf16, fp32, unknown (not disclosed) |
max_price |
object | Price caps with prompt and completion (USD per million tokens), request (USD per request) and image (USD per image); endpoints above any cap are excluded |
data_regions |
string array | Use only endpoints whose data processing region is listed; two-letter uppercase country or region codes such as US or SG |
exclude_regions |
string array | Exclude endpoints whose data processing region is listed |
require_parameters |
boolean | Only true is accepted. The platform always requires an endpoint to support every parameter in the request |
Fields set to null count as unset. Accounts and keys can store default preferences too (the account's live on the Routing preferences page of the console, linked from the Keys page). When several layers set a field, request beats key beats account; restrictive settings only tighten: ignore and exclude_regions are unioned, data_regions is intersected, and data_collection: deny anywhere wins.
Locking to one endpoint
order, only and ignore accept provider identifiers as well as endpoint identifiers, which start with route_. To have exactly one endpoint serve the request, put only that one in only:
{"provider": {"only": ["route_xxxxxxxx"]}}
Endpoint identifiers are listed on the model page and in offerings[].offering_id from GET /api/v1/models/<model ID>. If the locked endpoint is paused, under maintenance or fails another constraint, you get 422 no_eligible_endpoint with a reason code in excluded; see Common errors.
Validation
Fields are checked before routing. These cases return 400 invalid_request with a message naming provider.<field> and the reason, and no request reaches any provider:
- Unknown fields, or OpenRouter fields this platform does not implement, such as
zdr(usedata_collection: denyinstead). require_parameters: false.- Provider or endpoint identifiers in
order,onlyorignorethat do not exist on the platform. - Wrong types or values, for example
onlygiven as a string.
Differences from OpenRouter
allow_fallbacksdefaults tofalse: when the first endpoint fails you get the error, and the request does not move on.- Unsupported model parameters are errors: if no candidate endpoint supports a parameter in the request, you get 400
unsupported_parameterinstead of the parameter being dropped. - Unknown fields, unimplemented fields and nonexistent identifiers in
providerall return 400 instead of being ignored.