Pricing
How to price your circuit — FLAT, TOKEN, and TOKEN_TIERED billing types
Pricing
Every circuit declares a pricing array that tells ModelWorks how to bill each execution. You can mix multiple pricing entries in a single circuit (for example, a base flat fee plus a per-token charge). There are three pricing types:
| Type | Best For | How It Bills |
|---|---|---|
| FLAT | Fixed-cost services (API calls, video generation) | A single credit cost per run |
| TOKEN | LLM inference with per-token pricing | Per-token rates for input and output tokens |
| TOKEN_TIERED | LLM inference with volume-based pricing tiers | Same as TOKEN, but rates change based on total input length |
FLAT
A fixed credit cost charged per execution, regardless of input or output size.
{
"pricing": [
{ "type": "FLAT", "cost": 5 }
]
}| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be "FLAT". |
cost | number | Yes | Credits charged per run. |
Use FLAT when the underlying service charges a predictable, fixed amount — for example, a video generation API that costs 20 credits per call.
TOKEN
Charges based on the number of input and output tokens consumed during execution. This is the standard pricing type for LLM chat completion circuits.
Required Fields
| Field | Type | Description |
|---|---|---|
total_input_tokens_selector | string | Selector that resolves to the input token count from the provider's usage response. |
total_output_tokens_selector | string | Selector that resolves to the output token count. |
cost_per_input_token | number | Credits charged per input token. |
cost_per_output_token | number | Credits charged per output token. |
Optional Cache Fields
Many LLM providers (Novita AI, Z.ai, DeepSeek) support prompt caching — previously seen input tokens are served from a cache at a discounted rate instead of being re-processed. To take advantage of this:
| Field | Type | Description |
|---|---|---|
total_cached_input_tokens_selector | string | Selector for cached input tokens (cache reads). If omitted, all input tokens are charged at the full rate. |
cost_per_input_cache_token | number | Discounted rate for cached input tokens. Falls back to cost_per_input_token if not set. |
total_cache_write_tokens_selector | string | Selector for cache write tokens. If omitted, cache write tokens are treated as 0. |
cache_write_ttl | string | Which cache write TTL tier to bill: "5m", "30m", or "1h". |
cost_per_cache_write_5m_token | number | Rate for cache writes with a 5-minute TTL. |
cost_per_cache_write_30m_token | number | Rate for cache writes with a 30-minute TTL. |
cost_per_cache_write_1h_token | number | Rate for cache writes with a 1-hour TTL. |
How Billing Is Computed
non_cached_input = total_input_tokens - cached_input_tokens - cache_write_tokens
cost = (non_cached_input × cost_per_input_token)
+ (cached_input_tokens × cost_per_input_cache_token)
+ (cache_write_tokens × cost_per_cache_write_token)
+ (output_tokens × cost_per_output_token)- Non-cached input tokens are charged at the full
cost_per_input_tokenrate. - Cached input tokens (cache reads) are charged at the discounted
cost_per_input_cache_tokenrate (falls back tocost_per_input_tokenif not set). - Cache write tokens are charged at the rate matching the configured
cache_write_ttl. - Output tokens are charged at the
cost_per_output_tokenrate.
If you don't set any cache selectors, the circuit bills all input tokens at the full rate — the same as having no caching support. This keeps older circuits working without changes.
Example
{
"pricing": [
{
"type": "TOKEN",
"total_input_tokens_selector": "${{ chat_completion_response.output.stream_accumulators.usage_input_tokens }}",
"total_output_tokens_selector": "${{ chat_completion_response.output.stream_accumulators.usage_output_tokens }}",
"cost_per_input_token": 0.0000014,
"cost_per_output_token": 0.0000044,
"total_cached_input_tokens_selector": "${{ chat_completion_response.output.stream_accumulators.usage_cached_tokens }}",
"cost_per_input_cache_token": 0.00000026
}
]
}TOKEN_TIERED
Same as TOKEN, but rates are selected from a tiers array based on the total input token count. This is useful for providers that charge different rates depending on prompt length.
Tier Fields
Each entry in the tiers array defines a pricing band:
| Field | Type | Description |
|---|---|---|
min_input_tokens | integer | Minimum input tokens (inclusive) for this tier. Defaults to 0. |
max_input_tokens | integer | Maximum input tokens (inclusive) for this tier. Omit for the final tier (no upper limit). |
cost_per_input_token | number | Per-input-token rate for this tier. |
cost_per_output_token | number | Per-output-token rate for this tier. |
cost_per_input_cache_token | number | Discounted cache read rate. Falls back to cost_per_input_token if not set. |
cost_per_cache_write_5m_token | number | Cache write rate (5-minute TTL) for this tier. |
cost_per_cache_write_30m_token | number | Cache write rate (30-minute TTL) for this tier. |
cost_per_cache_write_1h_token | number | Cache write rate (1-hour TTL) for this tier. |
The cache_write_ttl is set once on the pricing entry (not per tier) and determines which cache write rate applies across all tiers.
Tier Matching
ModelWorks finds the tier where min_input_tokens <= total_input_tokens <= max_input_tokens and applies that tier's rates. Tiers must be non-empty, non-overlapping, and cover the full range with no gaps.
Example
{
"pricing": [
{
"type": "TOKEN_TIERED",
"total_input_tokens_selector": "${{ chat_completion_response.output.stream_accumulators.usage_input_tokens }}",
"total_output_tokens_selector": "${{ chat_completion_response.output.stream_accumulators.usage_output_tokens }}",
"cache_write_ttl": "5m",
"tiers": [
{
"min_input_tokens": 0,
"max_input_tokens": 524287,
"cost_per_input_token": 0.0000003,
"cost_per_output_token": 0.0000012,
"cost_per_input_cache_token": 0.00000006
},
{
"min_input_tokens": 524288,
"cost_per_input_token": 0.0000006,
"cost_per_output_token": 0.0000024,
"cost_per_input_cache_token": 0.00000012
}
]
}
]
}In this example, prompts under 524,288 tokens are billed at the lower tier, and longer prompts are billed at double the rate.
Mixing Pricing Types
You can include multiple pricing entries in a single circuit. Each entry generates a separate billing entry in the run result. For example, you might charge a flat fee for the infrastructure plus a per-token fee for the model:
{
"pricing": [
{ "type": "FLAT", "cost": 1 },
{
"type": "TOKEN",
"total_input_tokens_selector": "...",
"total_output_tokens_selector": "...",
"cost_per_input_token": 0.0000014,
"cost_per_output_token": 0.0000044
}
]
}The total cost of the run is the sum of all billing entries.