Reference · v0.44.0
Pricing
From the pinned CLI source. Read upstream.
Pricing and usage accounting
OpenTine records normalized consumption and estimates cost from a pinned, effective-dated catalog. A provider response is not a final invoice: taxes, credits, enterprise commitments, regional adjustments, rounding, and provider post-processing may differ.
Public records
Usage has exclusive input, output, cache_read, cache_write_5m,
cache_write_1h, and reasoning dimensions, an optional provider total, and
typed provider-specific extra dimensions. Exclusive buckets prevent cached or
reasoning tokens from being charged twice.
BillingResult reports one of complete, partial, unknown, or unmetered,
along with amount_usd, known_subtotal_usd, warnings, the calculation inputs,
catalog provenance, the applicable rate-card ID, and its effective date.
RateCard identifies one provider/model (plus aliases), effective range,
per-million-token rates, context thresholds, service modifiers or exact
service-specific rates, currency, source URLs, and verification date.
PricingCatalog performs deterministic provider + model + date resolution.
All arithmetic uses Decimal. The legacy numeric response field cost remains
the known USD subtotal for compatibility. For incomplete billing, cost can be
non-zero while billing.amount_usd is null.
Resolution and lifecycle
Resolution order is:
- an explicit adapter/run
rates=override, when the model check below allows it; - an explicitly selected catalog or
TINE_PRICING_CATALOG; - workspace
.tine/pricing.json, when signed or opted in withOPENTINE_TRUST_WORKSPACE_PRICING=1; - user
$XDG_CONFIG_HOME/opentine/pricing.json(a signed one only if no older than the bundled snapshot); - the bundled signed snapshot;
- an
unknownresult—never another provider's price.
A rates= override wins only when the model the provider reports resolves to the
same rate card as the model that was requested. If the provider echoes a
different model identifier, the override is discarded, the catalog card for the
reported model is used instead, and two warnings are appended: provider reported model 'X' for requested model 'Y' and explicit rates were ignored for the different model. When the catalog prices the reported model the status stays
complete, so a caller who encoded a negotiated rate is billed the list price
and learns of it only from billing.warnings—check them before trusting
amount_usd. When the catalog does not price it, the result is unknown; the
override is not reinstated either way. Equivalence is decided by resolved
rate-card ID, so a catalog alias, or Ollama's conventional :latest tag, still
counts as the same model. An unmetered adapter keeps its override
unconditionally.
Supplying base_url= to OpenAI, or setting OPENAI_BASE_URL, selects the
provider identity openai-compatible by default. Even if that endpoint exposes
a model named gpt-4o, OpenTine will report unknown pricing unless the caller
explicitly selects a provider or supplies a rates= override.
Later local layers win while effective dates remain deterministic. A local
catalog must have its own matching catalog_id hash; it may be unsigned so an
enterprise can express negotiated discounts or infrastructure costs without
altering the signed upstream snapshot.
Time-of-day pricing (peak / off-peak)
opentine-pricing/2 adds one optional field to a rate card, schedule: an
ordered list of windows, each naming the UTC hour ranges it covers, the days it
covers (all, weekday, or weekend), and the rates that replace the card's
base rates inside it. The first window covering a billing moment wins, ranges
are half-open (01:00–04:00 excludes 04:00), and a range whose start is later
than its end wraps past midnight. A window's rates override only the dimensions
they name.
"rates": {"input": "0.66", "cache_read": "0.022", "output": "1.98"},
"schedule": [
{
"id": "peak",
"days": "weekday",
"hours": [{"start": "01:00", "end": "04:00"}, {"start": "06:00", "end": "10:00"}],
"rates": {"input": "1.32", "cache_read": "0.044", "output": "3.96"}
}
]
The base rates are therefore the out-of-window price — for DeepSeek, the
off-peak one. Two defaults follow, and both are deliberate:
- A card with no
scheduleprices fromratesat every hour, which is what everyopentine-pricing/1card already meant. The field is additive by absence; no existing price moves. - A scheduled card priced from a date with no time of day also prices from base rates. A day is not an instant, so there is no moment to place in a window.
The billing moment splits in two: its date selects the rate card
(effective_from/effective_until), its time of day selects the window.
bill() and calculate() accept a datetime for effective_at, and native
capture passes the capture instant. tine price --at DATE pins the
card-selection date for the whole run — "what would this run cost under the
cards effective on DATE" — while each step's window still comes from that step's
own recorded timestamp, so a run spanning peak and off-peak is priced at both
rates rather than at one. Without --at, a step is carded on the day it was
recorded, falling back to today when a record carries no timestamp.
Both schemas load: the loader accepts opentine-pricing/1 and
opentine-pricing/2, and an unsigned /1 overlay still layers over the bundled
/2 snapshot.
Streamed calls and reported usage
Every price on this page is applied to usage the provider reports. An
OpenAI-compatible endpoint sends no usage chunk during a stream unless the
request carries stream_options={"include_usage": True}, so a rate card alone is
not enough to price a streamed call.
OpenTine adds that field by default for the providers openai,
openai-compatible, qwen, xai, glm, and glm-cn, and the Kimi,
DeepSeek, Groq, and OpenRouter adapters request it for themselves. The list
is an allowlist rather than a default because the field is not universally
accepted: Mistral answers it with HTTP 422 extra_forbidden, which fails the
whole call rather than losing a number. Together, Mistral, Ministral, and
Hermes therefore send nothing, as do OpenAICompatible and the local presets
that leave default_include_usage at False.
A streamed call to one of those adapters reports no usage at all, so the result
is status: "unknown", amount_usd: null, cost: 0.0, and the warning
provider did not report usage; cost is unknown—even though this document
advertises rate cards for Together, Mistral, and Ministral. On an unmetered
adapter the status stays unmetered and the warning reads provider did not report usage; API cost remains unmetered; the token counts are lost either way.
Non-streamed complete() calls are unaffected.
Pass include_usage=True to the adapter if your deployment does accept the
field, and confirm on a short streamed call that billing.status is not
unknown before relying on streamed cost. LocalAI and KoboldCpp request it
by default (both honour it). A Chat Completions stream emits one usage event,
the last, so a server that repeats cumulative usage on every chunk (vLLM
--enable-force-include-usage, continuous_usage_stats) cannot be counted
twice.
Re-pricing a recorded run (tine price)
tine price re-derives cost from what the run recorded. It prices every step
the capture itself billed as a model call — a model step, and also the done
step a tine run --model … --prompt run ends on, a think step beside tool
calls, or a refusal recorded as error — when the step carries usage, a
provider and a billing calculation; a harness's closing step carries no usage
and is not counted twice. The service tier recorded at capture
(billing.calculation.service_tier, or a harness step's service_tier) is
applied, so a Claude fast-mode call re-prices at its 2x modifier and a Priority,
Flex or US-geo call at its own. A call captured from a local provider (Ollama,
LM Studio, vLLM, local-anthropic-compatible, any local preset) re-prices as
unmetered, exactly as it was recorded — but only when the model carries no
:cloud / -cloud tag and the record carries positive evidence (the capture's
own unmetered verdict, or no billing inside a run the harness wrapper
captured: a billing-less step in any other run, such as one imported by 0.9.x
or through Recorder.import_events, prices unknown); an imported
trace or session log is never booked unmetered from its provider label (an
imported model call carries an explicit unknown record, every billing block
the source carried is dropped whatever its status, and a billing block with a
missing or unreadable status never counts as "no verdict"), so an imported local run prices unknown.
An imported step never keeps the source file's own cost either: the figure
moves to the opentine.source_reported_cost attribute and the step's cost comes
from the catalog (--price, or tine price later). Ollama Cloud calls are ollama-cloud
and re-price unknown until a card covers them. A run captured with explicit
Ollama compute or token rates re-prices as unmetered, because those override
rates are not part of the record.
Service tiers
A card's service_modifiers scale every dimension for a named tier. Tiers the
adapters and harnesses report: regional (OpenAI's regional-processing domains
for models released on or after 2026-03-05; Bedrock regional endpoints and
geographic inference-profile prefixes us. / eu. / jp. / au. / apac.;
Vertex multi-region and regional endpoints), us / eu (Anthropic
inference_geo, Foundry data zones, Fireworks' US host at 1.5x), fast /
fast_us, priority / priority_us / priority_eu, flex, batch /
batch_regional (on an OpenAI data-residency host a Priority or Flex call
bills priority_regional / flex_regional), and offpeak (Gemini's ON_DEMAND_OFFPEAK traffic type,
priced only where carded). A tier no card carries is reported unknown, never
priced at the standard rate.
Provider-reported cost
OpenRouter's usage.cost and xAI's cost_in_usd_ticks were already read as
the provider's own figure; DeepInfra's usage.estimated_cost now is too. A
Bedrock model id's routing prefix (global., us., eu., …) and openai.
are stripped before card lookup: global. prices at list, a geographic prefix
at the regional tier. Hosted vendors without a card (DeepInfra, Cerebras,
SambaNova, Upstage, Inception, NVIDIA, Hugging Face, Vercel, Cohere) record
unknown, never a guessed price.
Models newer than the bundled snapshot
The bundled snapshot is signed, so it can only gain cards when the release key
re-signs it — editing the file in place fails verification with catalog id/hash mismatch and takes billing down with it. Until the next signed release, price a
newly launched model with an unsigned overlay.
The repository carries a ready-made three-card overlay at
docs/pricing-overlay-claude-5.json, covering claude-opus-5,
claude-mythos-5 (Project Glasswing), and claude-haiku-4-5. It is present in a
source checkout and in the source distribution, but the wheel contains only the
opentine package, so pip install opentine does not put that file anywhere on
disk. A single-card overlay is reproduced here so the recipe works either way; it
carries that file's claude-opus-5 rates without its fast service modifier or
its metadata:
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/opentine"
cat > "${XDG_CONFIG_HOME:-$HOME/.config}/opentine/pricing.json" <<'JSON'
{
"schema": "opentine-pricing/1",
"generated_at": "2026-07-25T00:00:00Z",
"cards": [
{
"id": "anthropic:claude-opus-5:2026-06-24",
"provider": "anthropic",
"model": "claude-opus-5",
"effective_from": "2026-06-24",
"rates": {
"input": "5",
"output": "25",
"reasoning": "25",
"cache_read": "0.50",
"cache_write_5m": "6.25",
"cache_write_1h": "10"
},
"service_modifiers": {
"batch": "0.5",
"batch_us": "0.55",
"us": "1.1"
},
"source_urls": [
"https://platform.claude.com/docs/en/about-claude/pricing"
],
"verified_at": "2026-07-25"
}
],
"catalog_id": "sha256:affafa21b064e5f30592383bbc2cad164d6ce38c2d1dd8eb7df6e06511b7341a"
}
JSON
tine pricing show anthropic claude-opus-5
A workspace overlay at .tine/pricing.json takes the same content and outranks
the user one — but only when you opt in. It comes from the current directory, so
a cloned checkout can ship one, and an unsigned overlay could price any model at
$0 and disarm every max_cost budget. From 0.9.2 it is ignored (with a
note on stderr) unless it is validly signed by a trusted key or
OPENTINE_TRUST_WORKSPACE_PRICING=1 is set (1/true/yes/on).
A signed overlay older than the newest signed catalog already in use (bundled or
installed) is skipped with a notice too: every release catalog ever shipped still
verifies under the release key, so an old one checked into a project would
otherwise roll prices back. Two different catalogs signed with the same
generated_at cannot replace each other, at load or at tine pricing install.
A rate card's currency must be an ISO 4217 code (USD, three capitals).
An overlay carries its own catalog_id, so recompute it after any edit. The
stored value is the sha256:-prefixed digest, not the bare hex that
catalog_hash() returns — storing the bare hex fails every load with catalog id/hash mismatch, which takes all billing down rather than just the overlay:
from opentine.billing.catalog import catalog_hash
data.pop("catalog_id", None)
data["catalog_id"] = f"sha256:{catalog_hash(data)}" # note the prefix
Note that a merged catalog reports signed=false once any layer is unsigned; the
bundled layer's own signature is still verified and enforced on load.
Prices are never downloaded during inference. Catalog updates are explicit and
must verify their Ed25519 signature before installation, and a catalog older
(generated_at) than the bundled snapshot or the one it would replace is
refused, so an update can never roll prices back. A signed user catalog older
than the bundled one (say, left over from before an upgrade) is skipped at load:
tine pricing list
tine pricing show anthropic claude-sonnet-5 --at 2026-08-31
tine pricing check /path/to/catalog.json
tine pricing update https://trusted.example/pricing.json
The digest-covered run manifest pins the resolved catalog ID/hash, each underlying layer's ID/hash/signature metadata, the selected rate card, effective date, normalized usage, rates, context rule, currency conversion, and service modifier. Signed catalogs can therefore update independently of package releases without making an old run depend on today's catalog.
Frontier snapshot
The bundled snapshot generated on 2026-07-20 includes these required frontier cards (USD per million tokens):
| Family | Input | Cache read | Output | Other rules |
|---|---|---|---|---|
| GPT-6 Astra | 10.00 | 1.00 | 50.00 | cache writes 12.50; >272K input multipliers (whole request); batch/flex 0.5x; fast 2x |
GPT-5.6 Sol (gpt-5.6) | 5.00 | 0.50 | 30.00 | cache writes; >272K input multipliers; batch/flex/priority |
| GPT-5.6 Terra | 2.50 | 0.25 | 15.00 | same dimensions and threshold rules |
| GPT-5.6 Luna | 1.00 | 0.10 | 6.00 | same dimensions and threshold rules |
| Claude Fable 5.1 | 10.00 | 0.25 | 50.00 | 5m write 12.50; 1h write 20.00; US inference 1.1x; no fast mode |
| Claude Fable 5 | 10.00 | 1.00 | 50.00 | 5m write 12.50; 1h write 20.00; US inference 1.1x |
| Claude Opus 4.5–4.8 | 5.00 | 0.50 | 25.00 | exact model IDs; 5m write 6.25; 1h write 10.00; 4.6+ US inference 1.1x |
| Claude Sonnet 5 | 2.00 | 0.20 | 10.00 | launch price, now standard; US inference 1.1x |
Claude Sonnet 5's scheduled 2026-09-01 rise to $3/$15 was cancelled by Anthropic and never entered the catalog; the $2/$10 card runs from 2026-06-30 with no end.
Claude Fable 5.1 and Claude Mythos 5.1 are the only models whose cache hits cost
0.025x base input rather than the family-wide 0.1x. Every card states
cache_read outright and nothing derives it from input, so the published
$0.25/MTok is what bills; no family rule can override it. Fable 5.1 has no fast
mode (that tier covers Claude Opus 5 and Opus 4.8), so no fast modifier is
carded and a fast-tier request stays visibly unknown.
GPT-6 Astra's >272K threshold is request-scoped upstream — "priced at 2x input and
cache rates and 1.5x output for the full request" — and context_thresholds are
applied the same way: crossing the line replaces the base rates for every
dimension of the whole call, not just for the tokens above it. No priority-tier
price is published for Astra, so that tier is left uncarded rather than guessed.
The catalog also contains provider-scoped cards for current defaults and
frontier families from Kimi, DeepSeek, Google Gemini, Grok/xAI, GLM/Z.AI, Qwen,
Groq, Together, Mistral/Ministral, Meta (Muse), MiniMax, StepFun, Xiaomi MiMo
and Fireworks, and cloud namespaces bedrock (global endpoints at first-party
list, regional 1.1x), vertex (Claude; regional and multi-region 1.1x) and
foundry (Claude at Anthropic's rates with the US Data Zone at 1.1x; Azure
OpenAI GPT-6 with Data Zone US 1.1x and EU 1.2x). The 0.11.0 snapshot holds 224
signed cards, verified 2026-10-15. Use tine pricing list for the exact effective records rather than copying rates into code.
Direct Nous/Hermes rates are dynamic in the upstream service, so that card is
intentionally unknown until a local overlay supplies a price.
The current snapshot includes Kimi K3 ($3 input, $0.30 cache hit, and $15
output per MTok), Gemini 3.5 Flash, GLM-5.2, DeepSeek V4
Pro/Flash, and the current DeepSeek deepseek-chat/deepseek-reasoner aliases.
Gemini audio and cached-audio tokens remain separate dimensions, and exact
Batch/Flex/Priority rates are pinned where a scalar modifier would be wrong.
Grok 4.5 and 4.3 apply xAI's higher rate to every token dimension once total
prompt input exceeds 200K. Alibaba's proprietary qwen-plus is intentionally
not aliased to the distinct qwen3.6-27b card; it remains visibly unpriced until
its region-, context-, and thinking-mode-dependent rates are represented.
Qwen3.7-Max's pay-as-you-go promotion is effective-dated through 2026-07-23;
explicit 5-minute cache writes/hits and automatic implicit-cache hits retain
their distinct provider rates. Qwen3.8-Max, Qwen3.8-27B, and Qwen3.8-Flash carry
the same two-tier cache shape: the base cache_read is the automatic implicit
hit and the explicit_cache service tier carries the explicit hit rate (equal to
the implicit rate on Qwen3.8-Flash, which the vendor prices identically).
Alibaba publishes no availability date for the Qwen3.8-27B and Qwen3.8-Flash
hosted prices, so those cards begin on the day the price was confirmed rather
than being backdated over an unsourced window.
qwen3.8-flash-next is deliberately held — not carded and not aliased.
qwencloud.com/models/qwen3.8-flash-next returns HTTP 404 and the model is
open-weight only; the hosted, priced model is the distinct qwen3.8-flash
("Qwen3.8-Flash is the official version based on Qwen3.8-Flash-Next with more
production features"). Aliasing the two would attach a hosted price to a model
that has none, so a qwen3.8-flash-next run reports cost unknown until a local
overlay supplies a price.
The direct GLM adapter prices the Z.AI global endpoint; a China-region key uses
provider identity glm-cn and remains visibly unpriced unless a regional local
overlay is supplied. That miss now carries a warning naming the endpoint and the
overlay remedy, so it reads as a deliberate hold rather than a stale catalog; the
status stays unknown and no amount is invented, so completeness gates are
unaffected. Supplying an overlay or an explicit rate override silences it.
Anthropic's adapter sends an explicit inference_geo when configured and uses
the geography reported in response usage for billing. US-only inference on
supported current models applies the documented 1.1x multiplier across input,
output, cache writes, and cache reads; it composes with the Batch discount.
GPT-4o's May launch, August price cut, and October prompt-cache discount are
separate effective records, so historical runs do not receive backdated rates.
Mistral records use the provider's API IDs (mistral-large-2512,
mistral-small-2603, mistral-medium-3-5, and ministral-14b-2512) while the
documented *-latest names remain aliases.
Kimi Batch requests use the provider's exact per-dimension rates rather than a
rounded scalar discount. Groq Flex/on-demand tiers retain their documented
real-time prices, Llama Batch receives its 50% discount, and public-tier model
shutdown dates are recorded as lifecycle metadata. Cards remain priceable for
enterprise committed-spend customers, whom Groq explicitly exempts.
Release maintainers sign snapshots with
python -m scripts.sign_pricing_catalog ... --key /secure/private.pem --key-id ....
Private release keys must remain outside the source tree; old public keys stay
trusted after a public release unless they are explicitly revoked. The r3 key
is the first public OpenTine catalog trust anchor; unpublished pre-release keys
were retired before v0.3.0 because durable private-key custody could not be
demonstrated.
Primary rate sources are linked on every card, including the OpenAI model catalog, Anthropic pricing, Kimi models and pricing, DeepSeek pricing, Gemini pricing, xAI pricing, Z.AI pricing, and Alibaba Model Studio pricing.
Media, voice and omni models
A rate card prices token dimensions per million tokens, as before. Schema
opentine-pricing/3 adds two optional fields. units maps a dimension to its
unit — image, second, minute, character or request — and that
dimension's rate is per unit
({"rates": {"images:1024x1024:high": "0.17"}, "units": {"images:1024x1024:high": "image"}}).
same_rate_as names a dimension the vendor bills like another
({"input_video": "input"}); it is never inferred.
Media dimensions: per-modality tokens input_image, input_audio,
input_video, output_image, output_audio, output_video (split out of
input/output), and per-unit images[:variant], video_seconds[:variant],
audio_input_seconds, audio_output_seconds, audio_minutes,
tts_characters, realtime_minutes, requests. A dimension the card does not
price makes the result partial with a "missing rates" warning — media is
never billed at the text rate. A per-unit dimension (or its :variant) is
priced only in the unit the card states: a card that prices one without a
units entry is refused at load, and a /1 or /2 catalog carrying per-unit
rate names is refused. Older catalogs (/1, /2) cannot carry these
fields, and a 0.10 reader refuses a /3 catalog. Gemini image and video input
stay in the input bucket (they bill at the text rate on every model except
Live).
Local infrastructure rates
Ollama and other local adapters preserve usage while reporting unmetered API
cost by default, at capture and when tine price re-prices the run. Optional input/output token rates and compute-second rates let
a workspace estimate infrastructure cost. unmetered means “no metered API
price,” not “the hardware is free.”
Normal cost budgets warn and continue using the known subtotal. Set
Budget(strict_cost=True) to halt before the next model call once any hosted
price or observed usage dimension becomes indeterminate.