Pricing & billing
How inference is billed, a prepaid balance, per-token metering with distinct input, cached-input, and output rates, and the usage and cost on every response.
Inference is prepaid and metered per token. You fund your organization's balance, and each request draws down from it based on the tokens it used.
Prepaid balance
Your organization holds a balance that pays for usage. Top it up in the
dashboard. When the available balance falls below
the spending floor, new inference requests are refused with
402 Payment Required until you add funds:
{
"error": {
"message": "insufficient balance; add funds to continue",
"type": "insufficient_quota",
"code": "insufficient_balance"
}
}Discovery is free: GET /v1/models is not balance-gated. Only billable
requests like POST /v1/chat/completions require a funded balance.
Per-token metering
Usage is metered across token dimensions, each with its own rate:
| Dimension | What it counts |
|---|---|
| Input | Fresh prompt tokens sent to the model. |
| Cached input | Prompt tokens served from a prompt cache (billed at a reduced rate). |
| Cache write | Messages-only: tokens written into the prompt cache (cache_creation_input_tokens). Not reported on Chat Completions. |
| Output | Tokens the model generates, including any reasoning tokens. |
Rates are per token and vary by model. Cached-input tokens are billed at a lower rate than fresh input tokens. The total cost of a request is the sum of each dimension's token count multiplied by that dimension's rate.
Inference tiers
The same model is sold at three rates, depending on how fast you need the answer. Each tier is a multiplier on the model's Sync rate:
| Tier | How it runs | Multiplier | Applies to |
|---|---|---|---|
| Sync | Real time: chat completions, messages, embeddings, and decisions calls answered on the request. | 1x | Every dimension |
| Async | Queued, results delivered later. Coming soon, early access only. | 0.8x (20% off) | Input, cached input, and output |
Batch, standard priority | A JSONL job through the Batch API, completed within 24 hours. | 0.5x (50% off) | Every dimension |
Batch, expedited priority | Same as standard, but asks for the next free capacity slot. | 1x | Every dimension |
Worked example for openrelay/gemma-4-31b, which the Batch API runs, per 1M tokens:
| Tier | Input | Cached input | Output |
|---|---|---|---|
| Sync | $0.99 | $0.99 | $1.49 |
| Async | $0.792 | $0.792 | $1.192 |
Batch (standard) | $0.495 | $0.495 | $0.745 |
Batch runs only on batch-eligible models; the others have Sync and Async rates only.
Async
Async is for work that does not need an answer on the open connection. You submit a request, it waits in a queue for capacity, and the result is delivered later rather than returned on the request. Async is billed at 80% of the Sync rate on input, cached input, and output.
Async is coming soon and is available as early access only. There is no public Async API yet. To request access, email sales@openrelay.inc. If you need discounted asynchronous work today, use the Batch API.
DeepSeek V4.1-Flash-1017
The Sync rates for openrelay/deepseek-v4.1-flash-1017-heretic are:
| Input, per 1M tokens | Cached input, per 1M tokens | Output, per 1M tokens |
|---|---|---|
| $0.30 | $0.006 | $1.20 |
Cached-input pricing applies to prompt tokens the engine reports as cache hits
in usage.prompt_tokens_details.cached_tokens. Other prompt tokens use the
fresh-input rate. Reasoning tokens use the output rate.
Input-only models
Embeddings and Decisions
generate no tokens, so their models have an input rate and no output line. Their
usage carries prompt_tokens and total_tokens only, with no
completion_tokens, and you are billed on prompt_tokens.
| Model | API family | Input, per 1M tokens |
|---|---|---|
openrelay/bge-m3 | Embeddings | $0.013 |
openrelay/laya | Decisions | $0.020 |
Current rates
Per-model, per-dimension rates for Sync, Async, and Batch are published on the inference pricing page and in the dashboard. Always treat those as the source of truth for current prices.
Usage on every response
Every completion reports the token counts it was billed on in its usage
object, so you can reconcile spend yourself. This section covers the Chat
Completions usage shape; Messages uses
Anthropic's field names and a different cache-accounting rule, covered on
that page.
{
"usage": {
"prompt_tokens": 1024,
"completion_tokens": 256,
"total_tokens": 1280,
"prompt_tokens_details": { "cached_tokens": 768 }
}
}These fields map onto the billing dimensions as follows:
usage field | Billing dimension |
|---|---|
prompt_tokens − prompt_tokens_details.cached_tokens | Input (fresh) |
prompt_tokens_details.cached_tokens | Cached input |
completion_tokens | Output |
For streaming requests, the same usage object is
delivered on the final chunk: usage is always reported, so streaming requests
are billed exactly like unary ones.
Cost on every response
Every Sync response also says what the request costs, in an openrelay
object beside its usage:
{
"usage": {
"prompt_tokens": 1024,
"completion_tokens": 256,
"total_tokens": 1280,
"prompt_tokens_details": { "cached_tokens": 768 }
},
"openrelay": { "cost_nano_usd": 203520, "priced_at": "online" }
}| Field | Meaning |
|---|---|
cost_nano_usd | What the request is billed, in nanoUSD (1 USD = 1,000,000,000 nanoUSD): the price of its usage at the model's rates, and the same amount added to your organization's usage. An integer. |
priced_at | online: priced at the model's Sync rates. |
The example is 256 fresh input tokens, 768 cached and 256 output on a model priced at $0.15, $0.015 and $0.60 per 1M tokens, so it costs 256 × 150 + 768 × 15 + 256 × 600, which is 203,520 nanoUSD (about $0.0002).
- Unary responses also send the figure as an
OpenRelay-Cost-Nano-USDheader, for a client that reads headers only. - Streams carry the object on each chunk that carries usage, with the cost of
the usage reported so far: for a stream read to its end, the last one is the
bill. Streams send no header, because headers go out before any usage exists.
Read the cost from the last chunk or event that carries it, not from a
message an SDK assembles: the OpenAI Python SDK's
chat.completions.stream()helper keeps whatever the first chunk carried, and the message the Anthropic Python SDK assembles carries none. See Streaming and Messages. - Batch results do not carry it. Batch work is priced when the batch
finalizes, at the batch rate for its priority; the batch's
usageobject has its cost.
The figure is the bill for a completed response. A stream that is cut off, or ends with an error, after a chunk with a cost was sent is not billed, so the figure it sent never became a charge.
Batch requests
Requests run through the Batch API are metered per token exactly like Sync requests, in exchange for asynchronous, within-24-hour completion. The price depends on the batch's priority:
standard(the default) bills 50% of the Sync rate. The halving is applied to each dimension's line (tokens times the Sync rate), so a line can round down by at most half a nanoUSD.expeditedbills the Sync rate. The batch discount does not apply.
A batch's rolled-up token counts and cost are exposed on its usage object,
and each result line carries its own per-request usage.
What is and isn't charged
- Failed requests are not charged. A non-2xx result, or a streamed response that is interrupted before it completes, is not billed.
- Account holds. If your account is paused because its available balance
dropped below $0.50, or is under review, billable requests are refused with
403. See Errors.