Read cost and usage

Understand recorded charges

Read the accounting rules for plugin costs, incomplete calls and the platform's own runs.

For: tenant administrators and cost owners.

Read the accounting rules for plugin costs, incomplete calls and the platform's own runs.

Costs that plugins report

A plugin that calls a paid service of its own reports what each call cost in its tool's result (see Tools). Those costs are part of the branch's COST and of the job's total, count toward its budget, and are listed under the table:

Reported by plugins:
  helper-11acc939 (helper): greetings, 1 greeting, $0.0005, by team
job job-62986020-404d-44c7-84e9-db653ec8c5af completed: 4 calls, 772 input and 89 output tokens, $0.0024 ($0.0005 of it reported by plugins)

They are not model calls: CALLS and the token counts leave them out. usage shows them as rows of their own, and the console's job page and Cost page mark them as reported by the plugin.

A report counts only for the job that made the call: the edge takes the job, the plugin and the step from the call's binding, which the node's runtime sends with it, and refuses a report that names another job, so no node can charge a job it does not run, its owner's quota or its team's.

A node whose runtime predates call bindings sends reports without one; the edge takes them only from that node and only for the very job whose task it handed that node in the last 30 minutes (not another job of its tree), never from a node that once showed bindings, and refuses them all under --call-binding required.

A plugin server's report outside any job must name a tool the node runs.

The same holds for a node's local models: their tokens are charged to the job of the call's binding, and a report of more tokens than any call has (over 10^8 of a kind) is refused.

Tools' model use

A plugin's tools reach models only through the platform (Tools that need a model): the runtime answers their MCP sampling requests, or they call the gateway with their call's own token. Each such call is a model call of the job that called the tool, and names the plugin:

  • the job's cost counts it with the agent's own model calls, and its trace has it on the tool call's step;
  • the audit trail's run.model_call entry has plugin in its detail;
  • the usage export has a plugin column: sum a period's rows by it to see what each plugin's tools spent on models, per job, agent and model. No column names a person.

A tool call's sampling request is reserved and budgeted like the job's other calls: a spent budget refuses it with the refusal's numbers, and the tool, or the agent when the tool's call ends, hears why.

Outside spend

Outside spend is what the company spends on AI that never went through Orchestrator Zero: teams with their own keys, a provider's console, products built on a workspace nobody connected to the gateway. A plugin that declares provides: [outside-spend] imports it, once a tenant admin granted that at install (oz0 plugin install ... --accept-provides outside-spend); the verified ai.oz0/ai-spend reads Anthropic's and OpenAI's admin cost reports on your own nodes. Each row is a day, a provider, a model or cost line, a team (or none) and an amount in the provider's currency, never converted.

Terminal
oz0 usage outside                     # the last three months, by provider, model and team
oz0 usage outside --months 12 --by team
oz0 usage outside --json

The second table puts each month's outside spend beside the tenant's own metered spend, so a CFO reads the whole bill and a CISO sees where AI is used outside the platform. The console's Cost page shows the same as Outside spend: month over month, then one month by team, provider or model.

  • Outside spend belongs to no job: it never counts toward a job's, a routine's or the tenant's budget, or a quota.
  • Under works-council mode a team of fewer people than the threshold is summed into one row that names none of the hidden teams; the totals count them. Spend no rule maps to a team is shown as unassigned, the tenant's. Nothing is shown per person or per API key.
  • An import that adds or changes rows is audited (outside_spend.imported, with the plugin and the counts). The same day imported again changes nothing; a provider's correction changes the row.
  • Outside spend follows the tenant's retention of usage rows.

Incomplete calls

A model call whose outcome the gateway cannot know is charged at least what it reserved, never refunded: a call that timed out, a stream that broke off before its end, a node lost mid-call, or a gateway error between the edge and the model (502, 504). The provider may have billed it in full, and the platform does not guess that it did not.

A chat-completions or Responses stream, whose usage only comes at its end, used to record nothing when it broke off; under a budget it now costs at least its reservation too.

A provider's own error answer (a 500, a 503, Anthropic's 529 overloaded) is its whole answer, metered as before, and a call whose request never reached the provider whole costs nothing: one whose connection was never made, whose target the edge's proxy may not be sent to, or whose node gave up before it went out.

Once the edge has handed the whole request to the connection, or while it is still handing it over, the call counts as sent, and its outcome is unknown if no answer comes.

Only a call under a budget (its tree's, the tenant's month, or its owner's or team's quota) reserves, so only such a call has a reservation to be charged: a call of unknown outcome with no budget is still marked incomplete and counted, at what was metered, which for a cut chat-completions or Responses stream is nothing. Read a day's cost without budgets as a floor when it shows incomplete calls.

usage counts them per row, and its total shows what calls still running hold at their worst case:

JOB          AGENT   NODE        MODEL                                        CALLS  INPUT  CACHED  OUTPUT  COST
job-7f3a     lead    node-91378  anthropic/claude-sonnet-5-5 (1 incomplete)  6      4210   0       980     $0.0712

Total: 6 calls, $0.0712; $0.0614 more held by calls still running, at their worst case

An incomplete call's cost is its reservation (or what was metered, when that is more), with the part no token count explains in the usage export's charge row. When an edge stops mid-call, the call is settled once its attempt is over in the job's history, at its reservation, with the refusal "the edge stopped before the call's usage was known". oz0 evidence verify re-derives every such charge from the gateway's own record of the call (Run receipts).

The platform's own runs

Some jobs are the platform's about your agents rather than your agents' work: a rollout's shadow runs (shadow-…), eval routines' cases and kept cases' reproductions (evs.…, kp.…), and comparisons' runs (cmp.…). They spend on your keys and count toward your budgets, and oz0 usage lists them like any job, then sums them apart under the table (shadowUsd, evalUsd and compareUsd in its JSON):

Total: 64 calls, $0.0441
Of it, the platform's own runs: comparisons $0.0441, eval cases $0.0000, shadow runs $0.0000

The Overview's cost, the spend forecast and the KPIs leave them out, so they show what your agents' work cost; the Measured savings page shows the last 30 days of them.

Governance replay's continuations (rpl.…) are the platform's too: oz0 usage sums them apart as well (replayUsd).

Agents with a model cascade

An agent with a model cascade pays for two kinds of job: those its first model answers, and those whose first answer failed its check and that paid for the next model's round as well. Its cost per job therefore has two humps rather than one, and an average hides both.

The job's trace shows each round's calls on their own steps, and the finding model_cascade marks the jobs that restarted. The budget forecast works from the agent's own finished runs as before, so it sees both kinds. A cascade is not a saving until a comparison against the larger model alone, on the same cases with the same pass rule, has measured one.

Copyright © 2026