Read cost and usage

Export usage

Export recorded calls and charges for reporting and chargeback.

For: tenant administrators and cost owners.

Export recorded calls and charges for reporting and chargeback.

Usage export

usage export writes a tenant's usage for a period as CSV or JSON lines, in a schema that stays the same from one release to the next, for a finance tool, a data warehouse or your own reports:

Terminal
oz0 usage export --from 2026-10-01 --to 2026-11-01 --format csv --out october.csv
oz0 usage export --from 2026-10-01 --to 2026-10-02 --format jsonl
oz0 usage export --all-tenants --from 2026-10-01 --to 2026-11-01 --format jsonl --out all.jsonl

--from is the first UTC day and --to the day after the last, at most 400 days apart. The tenant's admins may export; --all-tenants needs a cluster admin. Each export is audited (usage.export, with who, the tenant and the period). --out writes the file with mode 0600, and only once the whole export has arrived: an export that fails leaves no file. A long export streams for as long as it needs, up to --timeout (an hour unless you say otherwise; 0 for no limit). The admin API's ExportUsage streams the same rows.

There is one row per model call or plugin report and unit kind, and per day of outside spend:

ColumnWhat it holds
schema_version1, on every row
row_idThe same in every export of the row: <usage id>:<unit kind>, or outside:<hash>:<unit kind>
charge_periodThe UTC day it was metered on, YYYY-MM-DD
sourcegateway (a model call), plugin:<name> (a plugin's report) or outside:<plugin> (outside spend; outside alone for teams works-council mode hides)
tenant, teamThe tenant, and the team the job was charged to; empty for none
tagsThe job's tags when the call was made, a JSON array
job, agentThe job (a child job's own ID) and the agent
provider, model, regionThe provider record, the model, and the region the record named at the time of the call; for a plugin's report, the service it paid and its unit
unit_kindinput_tokens, output_tokens, cache_read_tokens, cache_write_tokens, web_searches, compute_seconds, plugin_units, or charge
unit, quantityThe unit (tokens, searches, seconds, a plugin's own unit, call or day) and how many
list_costWhat it costs at the provider's published list price
effective_costWhat it cost the tenant: the price it was metered at, the record's own price where it has one, cache prices included
currencyUSD for everything Orchestrator Zero metered; outside spend keeps the provider's currency
attributes_recordedfalse when the row's team and tags are not known: rows written before the export's columns were recorded, and calls whose job could not be read at the time
memberThe member of a pooled provider record that served the call, such as sweden; empty for other records and for rows written before pools
pluginThe plugin whose tool asked for the model call: its MCP sampling request, its call's gateway token or a uses_model key, such as notes; empty for an agent's own calls, for plugins' reports and for rows written before the column

Costs and missing prices

Costs are decimals with six places, exact to the micro-dollar; empty in CSV and null in JSON when not known. The effective costs of a call's rows add up to the call's cost. A cost the price source gives only as a whole, such as a provider's own reported cost, goes on a charge row (quantity 1), and that call's token rows have no cost of their own. A list cost is known when the public price list knows the model: a node's local model, a plugin's report and outside spend have none.

Recording dates and stable attributes

A period is the days the calls were recorded in, by the database's clock when management took the row: a call an edge held while management was away, or one made just before midnight, is in the day it arrived, with its charge_period still the day it was made. So exporting a period that has passed again gives the same rows (until the retention of usage rows deletes them).

Region, team, tags, the list cost and the split by kind are recorded when the call is made, so exporting a period again gives the same rows (until the retention of usage rows deletes them). Rows written before they were recorded keep them empty, with attributes_recorded false and their cost on a charge row; they are never filled in from today's records.

A call whose job could not be read when it was made, such as while management was away from an edge, keeps its region and costs but has attributes_recorded false: its team and tags are unknown, not none.

A job's team and tags are its root job's: a child job is charged where its parent is, and a job ID started again by someone else is theirs from its first call.

Erasure

A person's erasure empties the tags on the usage rows of the erased jobs, since a tag can name a person. The rows stay, with their IDs, team and costs, so the next export shows them without tags.

Pooled calls

A call to a pooled provider record is one row per unit kind however many members it tried: a member that answered 429 before any output is not charged, and the row names the member that served it, at that member's price (its own --price where it has one). Budgets, quotas and chargeback count the call once.

Team visibility

Nothing names a person. There is no column for who started a job. Under works-council mode a team appears only where its figures may be shown to you, and the row is otherwise the tenant's, with an empty team.

Schema and spreadsheet compatibility

A later release may add columns at the end of a row; removing or renaming a column, or changing what one holds, makes a new schema_version. CSV cells that start with =, +, - or @ get a leading ', so a spreadsheet does not read them as formulas.

Copyright © 2026