Cost Tracking
USD cost reporting, model pricing, and node attribution.
The Costs page answers one narrow question: what did we spend? Quotas, budgets, or blocking on overage are out of scope — this is visibility only.
#Where prices come from
Price rows come from two places: rows the admin enters by hand (`source='manual'`) and a sync of the models.dev catalog (`source='models_dev'`). The sync never touches manually entered rows — a hand-entered price for a model always wins.
Resolving a price for a request narrows from provider-specific to provider-agnostic: it looks up `(provider, model)` first, then falls back to `('', model)` — a manually entered row with no provider_key. If the model name still isn't found, it also checks for a manually entered row under any provider, since the admin may have entered it under a different provider key.
#Billing mode
| Mode | Meaning |
|---|---|
| usage | Per-token billing; computed from the input/output price per 1M tokens. |
| flat | A subscription/flat-fee node (e.g. Antigravity, Cursor). No extra per-request charge. |
| local | A node running on your own hardware (e.g. Ollama, vLLM). No API fee. |
#Node attribution
A request usually carries `served_base_url`, saying which node served it. But the agent loop makes its own model calls as a SEPARATE self-call, and which upstream that inner request hit never makes it back into the outer activity row. In that case, attribution only happens if exactly one node serves that model — if several nodes serve the same model, which one actually answered is unknowable, so no attribution is made at all (leaving it blank beats guessing wrong). The judge's own model call is attributed by that same single-node rule too, but the result feeds somewhere this page never sees: not the outer activity row, but the pricing on its own `verdict` row — and that separate path has its own caching/staleness behavior. Judge spend is a separate ledger and is not part of this page's totals at all — see Platform & Admin → Judge Policies (Cost & Activity) for the details, including that attribution's caching behavior.
#What the panel shows
Cost/requests/tokens broken down by model, group, node and user; a daily spend chart.
Cost avoided on cache hits (`cost_saved_usd`); a hit row's own `cost_usd` is written as 0, so the total never inflates.
Scans all models on active nodes — including ones that have never been requested — for how many resolve to a price.
Recently used models that spent tokens but have no price to compute a cost from — the list the admin fills in by hand.
Add/edit/delete price rows by hand, or trigger a models.dev sync.