Loading documentation

Access required

Your account doesn't have access to the documentation. Contact your administrator.

Sign out
Skip to main content

Credits and billing

Status: beta Category: reference Added: 2026-06-22 Last reviewed: 2026-06-22

Summary​

The API is metered in credits. Your account holds a prepaid credit balance, and every successful call spends a fixed number of credits for the route it hit. You see the cost of each call in the response headers, and when your balance — or a budget you set — runs out, the next call is refused with 402 PaymentRequired instead of doing any work.

Only requests that succeed are billed. A request that fails validation, authentication, or a rate-limit check costs nothing.

How billing works​

  • Credits are prepaid. Your balance is funded ahead of use and drawn down as you call the API. Manage the balance from the developer portal.
  • Most routes have a fixed credit cost. A given endpoint costs the same whole number of credits on every successful call, independent of payload size. Heavier endpoints (composite analytics, AI-backed clinical surfaces) cost more credits than light lookups. A small number of routes are variable-cost — their charge scales with the size of the call (see Variable-cost endpoints).
  • A unit price converts credits to dollars. One global dollars-per-credit rate turns the credit cost of a call into its dollar cost. Both the unit price and the per-call dollar cost are returned in the response headers.
  • Only successful calls are billed. A response in the 2xx–3xx range is billable; any 4xx or 5xx is not. This is the opposite of rate limits, where every request counts against your window regardless of outcome (see rate-limits.md).

What a call costs​

The credit cost is fixed per route for most endpoints (and variable for a few — see Variable-cost endpoints), and the exact amount a call spent is returned to you on the response itself in X-Credits-Used (credits) and X-Credits-Cost-USD (dollars). The developer portal also shows your per-route usage and spend.

There is no static price list to memorize or hard-code — read the cost from the headers of a real call, or from the portal. Treat the headers as the source of truth for what you were charged.

Budgets​

Beyond your funded balance, you can cap spend from the portal at two levels, the same way you cap rate limits:

LevelApplies to
Account-wide capAn optional ceiling across every key on your account.
Per-key allocationA budget carved out for a single key. A key with no allocation draws from the unallocated balance.

Budgets are entered in dollars in the portal and enforced in credits. A call is checked against your balance and against every budget that applies to it; the tightest one wins. When any of them is exhausted, the call is refused with 402 (see below) — even if the others still have room.

Credit headers​

Every billable response carries the X-Credits-* set, the billing sibling of the X-RateLimit-* headers:

HeaderMeaning
X-Billabletrue if this response was billed, false if not (any 4xx/5xx).
X-Credits-UsedCredits this call spent. 0 when not billable.
X-Credits-Cost-USDDollar cost of this call (credits × unit price).
X-Credit-Unit-USDCurrent dollars-per-credit unit price.
X-Credits-RemainingProjected balance after this call. Appears when your balance is known.

A successful call looks like this (header values are illustrative):

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Billable: true
X-Credits-Used: 41
X-Credit-Unit-USD: 0.0025
X-Credits-Cost-USD: 0.1025
X-Credits-Remaining: 99950

X-Credits-Remaining is a projection — your balance as read at the start of the call, minus this call's cost. It is meant for a quick "how much is left" read, not exact accounting: concurrent calls and the moment a charge settles mean it can lag slightly. For an authoritative balance, read the portal. The header is omitted when the balance could not be read; the response still succeeds.

On a non-billable response, X-Billable is false, X-Credits-Used and X-Credits-Cost-USD are 0, and no balance is projected.

When you run out — 402 PaymentRequired​

When a call cannot be funded, it is refused with 402 before the endpoint does any work, so an unfunded call never partially executes. The body is the standard error envelope (see errors.md):

{
"timestamp": "2026-06-22T19:04:20.118Z",
"error": "PaymentRequired",
"message": "Insufficient credits",
"request_id": "ce9ea793-1759-4cad-ab1b-fbc11475df3a"
}

The message tells you which limit you hit:

messageCondition
Insufficient creditsYour account balance is depleted.
Key credit allocation exhaustedThe calling key's per-key allocation is used up, even though the account balance is not.
Account credit allocation exhaustedYour account-wide cap is reached.

Branch on the error code (PaymentRequired), not the message text.

A 402 is not retriable — retrying the same call without changing your funding gets the same 402. Resolve it by funding the balance or raising the relevant budget in the portal, then retry. Because a 402 is a failed response, it is not billed.

Variable-cost endpoints​

Most routes are fixed-cost: the same whole number of credits every call. A small number are variable-cost — their charge scales with the size of the call rather than being a flat per-route number.

Four routes are variable-cost, and they are the ones that send text to a model and return what it wrote:

A short call costs less than a long one. All four price the same way:

in = input_tokens (or request bytes when usage is null — UTF-8 byte length)
out = output_tokens (or response bytes when usage is null)
credits = max(1, ceil(in × input_cost_factor + out × output_cost_factor))

The two per-unit prices — input_cost_factor and output_cost_factor — belong to the model that served the call, so two models price the same text differently, and a model can weight the tokens it writes differently from the ones it reads. On /api/ask/run you choose that model with ?model=; on the other three the engine chooses it (Assist lets you nudge it with tier), and the response tells you which one it was under model. The current factors are shown on the developer portal's pricing page.

On the pricing page these routes read "by model usage" rather than a number, because there is no single per-call figure to show. As with every call, the exact credits charged come back in X-Credits-Used — read that rather than predicting the cost yourself.

The same rules above still apply: a variable-cost call is only billed when it succeeds, it is checked against your balance and budgets before it runs, and a floor of one credit means no successful call is ever free.

Add-on charges​

An add-on is charged on top of an endpoint's own cost, when a call opts into a feature that carries a real per-use upstream fee. It is not a route and it does not appear in the per-endpoint price list; it sits under add-on charges on the developer portal's pricing page, and it is only ever charged to a call that asked for it.

There is one today:

Add-onCharged whenUnit
Web searchPOST /api/assist/chat is sent with "web_search": true and the turn actually searchesPer search

Two things to size for. It is per search, not per call — a single turn may search more than once, and web_searches on the response says how many it ran. And on a short call the add-on can dominate the bill many times over, because it covers a per-query fee rather than tokens; setting the flag on every turn is the expensive mistake. A turn that opts in and then does not need to search is charged nothing extra.

What is and isn't billed​

Billed:

  • Every successful (2xx/3xx) authenticated /api/* call.
  • Each established transcription session (flat per-session cost).

Not billed:

  • Any failed call — 400, 401, 404, 413, 415, 422, 429, and every 5xx. Fix the request and retry without spending credits.
  • A call refused with 402 for insufficient funds.
  • The unauthenticated GET /health liveness probe.
  1. Watch X-Credits-Remaining. Surface low balances to your own operators before they hit zero, rather than discovering it on a 402.
  2. Treat 402 as terminal, not retriable. Stop the call, alert, and resolve funding — do not loop. Looping on a 402 never clears it.
  3. Distinguish 402 from 429. A 429 clears when its window rolls over; honor Retry-After and retry. A 402 clears only when you add funds or raise a budget. Don't apply rate-limit backoff to a 402.
  4. Read cost from the headers. If you need to attribute spend, record X-Credits-Used / X-Credits-Cost-USD per call rather than assuming a fixed price per route.
  5. Don't burn credits on avoidable failures. Validation and de-identification errors are free, but they still consume rate-limit window — fix them client-side (see errors.md).
  • errors.md — the error envelope and the full error code taxonomy, including PaymentRequired.
  • rate-limits.md — the X-RateLimit-* headers and the contrasting "every request counts" rule.
  • authentication.md — keys and how to send them.
  • ask-run.md — the variable-cost model endpoint and its per-call credit formula.

Change history​

DateChange
2026-06-22Initial publication — credit metering, the X-Credits-* headers, 402 PaymentRequired, and per-key / account budgets.
2026-06-26Added the Variable-cost endpoints section for /api/ask/run; clarified that most (not all) routes are fixed-cost.
2026-06-26Variable-cost pricing split into per-model input_cost_factor / output_cost_factor (input and output units priced separately).