Skip to main content
A model on Kyma can usually be served more than one way. This page states which one is chosen, in what order, and what each costs you — because a gateway that does not say this is asking you to trust an average.

The rule, in one line

What you pay follows the route that actually completed your request — not a blended average across suppliers. When an upstream sends a bill we use it; when it does not, we price from our maintained rate table. Where the API returns a charge in the response body — today POST /v1/chat/completions and most /v1/audio/* routes — read usage.cost or billing.cost_usd. That figure is shown with up to eight decimal places in USD; the ledger settles at four decimal places, so sub-cent response figures can differ from what was ledgered. POST /v1/messages answers in Anthropic’s shape, which has no field for a price, so a non-streamed call reports the charge in the X-Kyma-Cost-USD response header. During a failover to our secondary runtime, which is rare, that header can be absent; the charge is in your usage log either way. A streamed call does not carry its price: the headers are sent before the first token, and the final amount — which depends on cached tokens and on what the upstream itself charged — is only settled after the last one. Read it from GET /v1/auth/usage/logs. The same applies to genmedia and realtime. Browser callers can read these headers directly: responses list them in Access-Control-Expose-Headers, including X-Kyma-Model, X-Kyma-Served-Model, X-Kyma-Cost-USD, X-Kyma-Routes-Tried and Retry-After. X-Kyma-Routes-Tried is sent on /v1/messages only today. Published prices on /v1/models and /v1/pricing are shelf quotes (the cheapest route we advertise), not a promise that every completed request matched that number.

Why a model has more than one price

The same model is often available from several operators, at different service tiers, in different regions. Those are genuinely different products with genuinely different costs, and the spread between the cheapest and dearest way to serve one model can be several-fold at identical context length. So “the price of a model” is not one number. What we publish is the cheapest route we have — the best price available for that model, not an average and not a maximum. That number is a floor, and the distinction matters: if the cheapest route is busy or down and a dearer one answers, that request costs more, and the charge on a billable response reflects the estimate; the ledgered 4 dp figure is authoritative (see above). Endpoints that do not yet return a cost field still write to your logs — check there after the request completes.
Published prices are recomputed daily from what serving actually costs us. The same job queues every change — up or down — for the changelog, which the daily changelog run publishes.

The order routes are tried

  1. The primary route, then its configured alternates.
  2. Within those, cheapest first. A route that costs more is tried later, not removed — it is what keeps the model answering when the cheap one is down.
  3. A route with no known rate sorts last. Unknown is not the same as cheap.
  4. Routes that would certainly fail this particular request are skipped entirely — for example a route without tool support when your request carries tools.
  5. Routes that are currently failing are demoted, not removed: healthy routes are tried first, then degraded ones, then ones marked down.
Requests that fail are not billed. You pay for the attempt that completed.

What you see when a route fails

  • The switch happens before the first byte. Once a stream has started, it stays on that route.
  • Failed attempts are not billed. A substitute is billed as the model that answered, never above the price of the model you asked for.
  • Compare x-kyma-served-model with the model you asked for if a substitute is not acceptable to you.

What a failover costs you

If the usual route is unavailable and a dearer one answers, that request costs more, and usage.cost says so. We used to cap the charge at the published price. It sounds generous and it was not: keeping that cap meant the router had to refuse the dearer routes, which left most multi-route models with a single supplier. A price ceiling that removes your failover is a worse deal than a request that occasionally costs more. If you would rather fail than pay above a limit, say so per request — see max_price below.

Guarding against a wrong number

A single request is never billed more than 3× the higher of the published price and the price of the dearest route we know for that model, whatever an upstream reports. It exists because a usage figure can arrive wrong — misreported upstream, or misread by us. Three times that price sits far above any real difference between routes and far below a decimal-point error, so it clips mistakes without clipping an expensive but genuine one. A request that hits that stop is charged less than it cost to serve, and the model is investigated the same day.

Choosing your own limit

max_price is in design and not yet accepted by the API. It is documented here because the routing rules above are what it will build on.
The intent: a per-request ceiling you set, and when no route can serve under it the request fails with a clear error rather than being served at a price you did not agree to. Cost-sensitive batch work sets it; latency-sensitive interactive work does not. The choice is yours per request rather than ours for everyone.

What we do not do

  • After a refusal, no other creator answers. If a route returns HTTP 403, Kyma keeps trying the model you asked for on its other routes; if it falls back further, it only considers models from the same creator. When nothing serves, you get 403 route_refused with error.suggested_models — up to three other model ids, same creator preferred. Your request is never completed by another creator’s model under the name you asked for.
  • We never hide the price. usage.cost is the amount charged, always.