Preferred providers
Use exchange.candidates.providers.prefer to try providers in a specified order, then use the rest of the eligible market.
A preference changes the order of eligible offers. It does not exclude other providers.
Use exchange.candidates.providers.allow when only the specified providers can serve the request.
If you want fallback to other providers, replace that allowlist with a preference.
Send a request
- Choose a model from
GET /v1/models. - Get provider handles from the model's page on the exchange.
- Replace the example model and provider handles with your choices.
- Send the request with a
spendkey.
See API keys if you need a key.
curl https://router.inference.ai.exchange/v1/chat/completions \
-H "Authorization: Bearer $LIQUID_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-oss-120b",
"messages": [{ "role": "user", "content": "Say hello." }],
"max_tokens": 64,
"exchange": {
"candidates": { "providers": { "prefer": ["acme", "globex"] } },
"cap_usd": 0.05
}
}'
With the OpenAI Python SDK, put exchange in extra_body:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://router.inference.ai.exchange/v1",
api_key=os.environ["LIQUID_API_KEY"],
)
response = client.chat.completions.create(
model="gpt-oss-120b",
messages=[{"role": "user", "content": "Say hello."}],
max_tokens=64,
extra_body={
"exchange": {
"candidates": { "providers": { "prefer": ["acme", "globex"] } },
"cap_usd": 0.05,
}
},
)
print(response.choices[0].message.content)
How the exchange orders offers
For the example above, an eligible offer from acme ranks before an eligible offer from globex.
Other eligible offers follow. If neither preferred provider has an eligible offer, the rest of the market can serve the request.
- Each entry is a provider handle or a pattern with
*, such asacme-*. - The first entry that matches a provider sets its preferred position. Put specific handles before broader patterns.
- Offers at the same preferred position use the request's usual order, such as price or speed.
- A reservation leg ranks before a preferred provider.
A preferred provider can cost more than another provider. Keep a price cap and any required limits in the request. Every offer must pass the request's limits, the preset of the key, and the guardrails of the workspace. See Purchasing rules.
Fallback before output
If an award fails before any output, the exchange can try the next eligible offer. The next offer can come from another preferred provider or from the rest of the market. After output starts, the exchange does not switch providers for that response.
An allowlist still limits fallback. For example, this request permits only acme and globex, with globex first:
{
"exchange": {
"candidates": {
"providers": { "allow": ["acme", "globex"], "prefer": ["globex"] }
}
}
}
To permit fallback across the eligible market, remove the request's exchange.candidates.providers.allow limit.
The limits of the key and the workspace still apply.
OpenRouter requests
The exchange maps provider.order to exchange.candidates.providers.prefer on Chat Completions, Messages and Responses requests.
This object asks for the same provider order as the first example:
{
"provider": {
"order": ["acme", "globex"],
"allow_fallbacks": true
}
}
Use provider handles from the exchange. Do not assume that an OpenRouter provider name is the same handle.
With allow_fallbacks: false, only providers in order can compete.
The exchange can still try the next eligible provider in that list before any output.
If provider.only or exchange.candidates.providers.allow is also present, an offer must pass all these lists.
Send either provider.order or exchange.candidates.providers.prefer.
If you send both non-empty lists, they must contain the same entries in the same order.
Different lists return HTTP 400.
The exchange refuses allow_fallbacks: false without a non-empty order.
See Move from OpenRouter for the full migration guide.
Presets and Auto
A named preset can save preferred providers with a price or speed strategy. The request's list replaces the saved list. An empty request list clears the saved preference:
{ "exchange": { "candidates": { "providers": { "prefer": [] } } } }
A guardrail cannot hold provider preferences. A preset linked to an API key does not apply its preferences.
To apply saved preferences, send the preset's name as model.
Auto and smartest rank by score.
They refuse a non-empty preference list with 400 preferred_providers_with_auto.
This rule also applies to provider.order and preset saves.
Use a named model or a basket with a price or speed strategy.
Check the order without a purchase
POST /v1/exchange/dry-run shows eligible offers in award order. It buys nothing and holds no funds.
Send preferences in exchange, because this endpoint does not read provider:
curl https://router.inference.ai.exchange/v1/exchange/dry-run \
-H "Authorization: Bearer $LIQUID_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-oss-120b",
"exchange": {
"candidates": { "providers": { "prefer": ["acme", "globex"] } },
"cap_usd": 0.05
}
}'
If a provider limit excludes every offer, inspect error.binding_rule in the error response.
See Auction errors for the cause and the required change.