Provider selection

Updated

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 provider field of the request body.
  • All three protocols: the X-ModelPortal-Provider-Preferences header, whose value is a JSON object with the same fields as provider, 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.
  • provider is 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 (use data_collection: deny instead).
  • require_parameters: false.
  • Provider or endpoint identifiers in order, only or ignore that do not exist on the platform.
  • Wrong types or values, for example only given as a string.

Differences from OpenRouter

  1. allow_fallbacks defaults to false: when the first endpoint fails you get the error, and the request does not move on.
  2. Unsupported model parameters are errors: if no candidate endpoint supports a parameter in the request, you get 400 unsupported_parameter instead of the parameter being dropped.
  3. Unknown fields, unimplemented fields and nonexistent identifiers in provider all return 400 instead of being ignored.