Speed
Every model has more than one route that can answer it. By default the cheapest one does. Ask for the fastest instead, or set a floor on tokens per second, per request or as a default on a key or a gateway.
The default is price
A request with no speed setting goes to the cheapest route that can serve the model, and falls to the next cheapest when that one fails. Nothing here changes it until you ask. The price you are billed is the price the route had when the request was matched, as on every other call; speed only changes the order the routes are tried in.
Sort: provider.sort
Put provider.sort in the body of a chat request, the way OpenRouter does. It takes one of three values:
price· lowest price first. The default.throughput· most tokens per second first.latency· shortest wait for the first token first.
curl https://api.opencheap.si/v1/chat/completions \
-H "Authorization: Bearer $OPENCHEAP_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "kimi-k3",
"provider": { "sort": "throughput" },
"messages": [{ "role": "user", "content": "Hi" }] }'OpenRouter's object form, { "by": "throughput" }, is accepted too. Routes are ranked on speeds we measure on real answers; a route we have no measurement for yet is ranked after the measured ones.
:nitro and :floor
A model id can carry the sort. :nitro sorts by throughput, the fastest first, and :floor sorts by price, the cheapest first, which is what a request does without either. They work on any chat model id.
kimi-k3:nitro fastest route
kimi-k3:floor cheapest route (the default)
kimi-k3:nitro:thinking other suffixes are left aloneA suffix beats the default on a key or a gateway. provider.sort beats the suffix when both are sent. An id that is itself listed with a suffix, such as a model we list as …:nitro, is that model.
A floor on speed: min_throughput and max_latency
Keep the sort and add a bar a route should clear. provider.min_throughput is tokens per second after the first byte; provider.max_latency is seconds to the first token. OpenRouter's percentile form ({ "p90": 40 }) is accepted: its number is used.
{ "model": "kimi-k3",
"provider": { "min_throughput": 40, "max_latency": 3 },
"messages": [{ "role": "user", "content": "Hi" }] }Best effort by default. Routes measured under the bar are skipped, and the cheapest of the rest answers. A route we have not measured yet is not skipped. When every route is under the bar, the fastest one answers rather than the request failing.
Strict with allow_fallbacks. Add "allow_fallbacks": false and only a route measured at or over the bar can answer; one we have no measurement for does not count. When none does, the request is refused with a 503 and billed nothing.
{ "error": { "type": "no_route_meets_speed", "code": "no_route_meets_speed",
"message": "no route for 'kimi-k3' is measured to meet a minimum throughput of 40 tokens/s (provider.min_throughput) right now. Lower the threshold, or set provider.allow_fallbacks to true to be served by the fastest available route",
"details": { "min_throughput": 40, "max_latency": null } } }Retry later, lower the bar, or send allow_fallbacks: true (or leave it out) to be served by the fastest route there is. See Errors.
Defaults on a key or a gateway
Set a speed once and every request under it uses it. In the console, a model key's speed is on API keys (the Speed column) and a gateway's is on its page under Gateway. From code it is a speed object on a key (POST /api/v1/keys, PATCH /api/v1/keys/{id}) and in a gateway's config; null clears it.
- CheapestThe lowest price. The default.
{ "sort": "price" } - BalancedThe lowest price among routes that reach 30 tokens/s, best effort.
{ "sort": "price", "minThroughput": 30 } - FastestThe most tokens per second, whatever the price.
{ "sort": "throughput" } - CustomYour own floor on tokens/s and/or ceiling on seconds to the first token.
{ "sort": "price", "minThroughput": 60, "maxLatencySecs": 2 }
curl -X PATCH https://app.opencheap.si/api/v1/keys/$KEY_ID \
-H "Authorization: Bearer $MANAGEMENT_KEY" -H "Content-Type: application/json" \
-d '{ "speed": { "sort": "price", "minThroughput": 30 } }'sort is price, throughput or latency and defaults to price. minThroughput is tokens per second and maxLatencySecs is seconds to the first token; each is a number above 0 or null for none. A floor or ceiling set on a key or a gateway is best effort. For a strict one, send it on the request with allow_fallbacks: false.
Which one wins. Field by field, in this order: the request's own provider values, then the model suffix (for the sort), then the gateway the request runs under, then the key. A field one level leaves empty falls to the next, so a gateway that sets only a floor leaves the sort to the key. A gateway saved as Cheapest keeps "sort": "price" and so puts the sort back to the cheapest over a faster key; a key set to Cheapest stores nothing, as that is what it does without a setting.
max_price still caps the price
Speed orders the routes; it never lifts a price limit. A route above the request's max_price (or the one on the gateway or key) is not a candidate however fast it is, and when nothing is under the limit the answer is the usual 422 no_offer_under_limit. See Prices and limits.
The speed floor for community sellers
Capacity that other accounts list is held to the same bar by default, whatever the sort. A community seller's route gets traffic only while its measured speed is at least half the model's median speed, the median over the model's other routes that have data. A route with no measurement yet is eligible, and starts counting after its first answers. Under the floor, a route is passed over until it speeds up; on Sell › Positions the seller sees the route's speed next to the model median, and a note when it is below the floor.