Spend (FinOps)
See spend in Admin and stop spend at admission, export and alerts included; not a full BI warehouse.
Configure USD (pricebook)
Tokens show up automatically from the model response. Dollars do not, you must map each model id string the runner reports in
finops.pricebook (or use a gateway that inlines
usage.cost / cost_usd).
{`{
"finops": {
"pricebook": {
"gemini-2.0-flash": { "input_per_1k": 0.0001, "output_per_1k": 0.0004 }
},
"budgets": {
"tenants": { "default": { "max_usd_per_day": 25, "soft": true } }
}
}
}`}
If Admin Spend shows tokens but $0 and an
usage_unpriced alert, the model id in the alert attrs is
missing from the pricebook, add that exact string, restart the control
plane, and new runs will price. Full field list:
docs/configuration.md.
What ships now
-
Optional
finopsinlanggraph.json: UTC-day budgets,alerts.soft_pct,reservationholds (optionalhold_ttl(keep longer than longest run), per-agentagentsoverrides), androuting.aliasescheaper-agent rewrite near soft threshold. Optionalon_hard_breach: cancel_inflightcancels pending/running runs when a hard day cap is already breached. -
Terminal
Output.usage→ SQLusage_events(LangGraph Python/TS; CrewAI/LlamaIndex/LangChain/AutoGen adapters when metrics exist). A HITL pause or a mid-run cancel still meters whatever tokens ran before the pause/cancel, it does not wait for a terminalsuccessto record them. Webhook eventbudget_alert+ Admin alerts strip (approach alerts deduped once per UTC day per process). -
Admin
/admin/spendlabels dollars Estimated USD, not "Cost": tokens are exact (from the model response), dollars are tokens × yourfinops.pricebookrate, unless the runner is talking to an LLM gateway that reports cost inline with usage (OpenRouter'susage.cost, and OpenAI-compatible gateways following the same convention), in which case that reported figure is used instead and the pricebook is skipped for that run. With a non-empty pricebook, a terminal run with real tokens, no reported cost, and a model id missing from the book raises ausage_unpricedalert instead of silently looking free (empty pricebook = tokens-only, no alert; a present$0-rate row is intentional free tier). If a run's reply carries no token data in any shape the runner recognizes at all (a brand-new provider, or an integration that has not adopted LangChain's standardizedusage_metadatafields), that raises ausage_unmeteredalert instead, the one failure mode worse than under-pricing a run is making it invisible. APIs:/admin-api/usage/{summary,alerts,holds,export}. -
Live editing from Admin, no redeploy. The
finopsblock inlanggraph.jsonis only the bootstrap baseline, open Admin → Spend and use the Live FinOps config panel to add pricebook rows or change a tenant/agent day budget directly, no file edit or control-plane restart required. The change is live on that replica the moment you save, and every other replica picks it up within about 15 seconds (same fingerprint-poll mechanism as durable policy grants). The panel shows file baseline and effective (live) side by side so an overridden value is never a surprise, and Clear overlay reverts everything back to whatever the file says. Writes are validated server-side (no negative rates or budgets, a same-magnitude-swapped input/output rate is flagged, and a genuinely-intentional$0free-tier rate is confirmed on save rather than silently rejected). API:GET|PUT|DELETE /admin-api/finops.
What is not shipped yet
- Streaming mid-run token metering (kill of inflight is opt-in via
on_hard_breach: cancel_inflight, not continuous spend tracking), usage is still only recorded once a run reaches a terminal or interrupted status. - Reconciling against a provider's account-level billing API (OpenAI/Anthropic Costs/Usage endpoints) after the fact; multi-currency / warehouse BI.
- Reading cost from gateways that report it out-of-band instead of inline on the response (Portkey response headers, Helicone's async dashboard), routing calls through one works today (it's a plain client
base_urlchange, nothing Runkite-specific), but its cost won't reach Runkite unless it inlines cost the way OpenRouter does; those runs price from tokens × pricebook like any direct-provider run. - Automatic model-catalog shopping (routing only uses configured
routing.aliases). - Frameworks with no token metrics still report empty
Output.usage(best-effort only). - Connector payload shrink does not write
usage_events. Admin Spend moves only if the runner reports fewer tokens.
Practical stance
Cost caps and metering sit next to kill, grants, and HITL. Wire
finops in config, watch /admin/spend, and hard-deny
when a day budget is gone.
usage_events.Related: Security · Kill & break-glass · Limitations · docs/configuration.md