Total cost per agent
An agent spends through Burnbound, but often also outside it: a wallet Burnbound does not manage, a Stripe Issuing card that is not linked to an agent, the model tokens it burns. This page explains how Burnbound puts all of it next to each agent: managed and observed spend, token cost from Anthropic and OpenAI, cost centers and the monthly accounting export.
What does an agent's total cost include?
Three parts, always shown apart and then added:
| Part | What it is | Counts for caps, rules, mandates and the plan |
|---|---|---|
| Through Burnbound (managed) | What Burnbound authorized: x402 and MPP payments, card authorizations, and actions (refunds and credits) | Yes |
| Observed | Outgoing transfers of wallets Burnbound does not manage, and captures of Issuing cards not linked to an agent | No |
| Tokens | What your Anthropic and OpenAI organizations spent, read by your action gateway | No |
Observed spend and token cost are visibility only. They never count for a cap, a rule, a mandate or the plan, they never become a payment intent and Burnbound never blocks them. Adding observed spend never changes an authorize decision. Managed spend is explained in Concepts.
The API gives the three parts for a UTC month: GET /v1/agents/:agentId/total-cost?month=YYYY-MM, for any signed-in person of the organization. It returns managed, observed (by source) and tokens (by provider and model), each with testSpendUsd, the part that is test money, and totalUsd, their sum (test money included). If your plan's retention cuts the month, visibleFrom says from when it counts.
What is observed spend?
Spend Burnbound did not authorize but can read. It comes from sources:
| Source | Where it comes from |
|---|---|
onchain |
Outgoing transfers of an address you registered, read by Burnbound |
stripe_issuing |
Captures of Issuing cards not linked to Burnbound, sent by your action gateway |
llm_anthropic |
Anthropic token cost, sent by your action gateway (see below) |
llm_openai |
OpenAI token cost, sent by your action gateway (see below) |
Each movement is stored once per organization, with the agent it belongs to (or none) and that agent's cost center at the moment it is stored. Removing a source keeps the spend already stored. Any role of the organization can read it: GET /v1/observed-connectors lists the sources and GET /v1/observed-spend the movements, newest first (filters agentId, source, from and to as YYYY-MM-DD, limit from 1 to 500, 100 by default; the next page with before set to next).
Which wallets can Burnbound observe?
Any public address on the networks Burnbound knows: Base, Tempo, Base Sepolia and Moderato (Tempo's test network). Burnbound only reads it. There is no key, nothing is signed and nothing is ever asked of you.
- What it reads. Outgoing transfers of the network's asset: USDC on Base, USDC.e on Tempo. A transfer to the address, to itself or of zero is not spend. On Tempo, the fee paid to the fee manager is not counted.
- No history. Burnbound starts at the first block its scan had not read when it first sees the address, and reads from there on. Transfers made before you registered the address never show.
- One address, one source. The same address twice on the same network is
connector_exists(409). The address of a wallet your organization already manages in Burnbound isaddress_already_managed(409): its payments are already managed spend. - Test networks. Transfers on Base Sepolia and Moderato are test money and show apart.
- Errors. If the network's RPC fails, the sources of that network show
Errorwith a code, never a message, and the next pass resumes where the scan stopped.
Owners and admins add and remove addresses in Organization → Observed spend, with an optional agent. Each change is audited (observed_connector.created, observed_connector.deleted).
How do I observe Issuing cards?
Your action gateway sends them. It runs with your Stripe key, so Burnbound never reads Stripe itself. Set GATEWAY_SYNC_ISSUING=1 and give the gateway's restricted key two more permissions: Issuing Transactions: Read and Issuing Cards: Read. The sync never writes to Stripe. How to run the gateway is in Run the action gateway in 5 minutes.
- Which cards. A card with
burnbound_agent_idin its metadata is linked to Burnbound: its authorizations already go through the card webhook and its captures are never sent. Every other card's captures are observed spend. - Which agent. Put
burnbound_observe_agent_idin a card's metadata to name the agent its spend belongs to. Without it, or with an id that is not one of your organization's agents, the captures are kept with no agent. - What is sent. Captures only. Issuing refunds are not sent. A capture in a currency Burnbound has no rate for is left out and logged.
- When. Every
GATEWAY_SYNC_INTERVAL_SECONDS(300 by default, from 60 to 86400). The first pass reads the last 7 days; then each pass starts at the newest capture read. A pass reads at most 5000 captures, and a longer window is finished by the next passes. Burnbound keeps each capture once, so a restart that reads again is harmless.
The source shows as Action gateway (Issuing) under Organization → Observed spend.
How do I send my own spend?
With an organization key, POST /v1/observed-spend/batch stores spend you track yourself. A batch holds up to 500 rows and 1 MB. It is all or nothing: one bad row refuses the whole batch and stores nothing. It is idempotent by source and externalId: a row sent again counts as a duplicate and does not change, except a token row (llm_anthropic, llm_openai) with other values, which replaces the stored one.
{
"rows": [
{
"source": "stripe_issuing",
"externalId": "ipi_…",
"occurredAt": "2026-11-03T10:00:00Z",
"amountMinor": 1299,
"currency": "EUR",
"agentId": "…",
"counterparty": "Example merchant",
"description": "Team lunch",
"test": false
}
]
}
| Field | What it takes |
|---|---|
source |
stripe_issuing, llm_anthropic or llm_openai. onchain is only Burnbound's own scan. |
externalId |
Your id of the movement: 1 to 200 letters, digits or . _ : / @ -. |
occurredAt |
ISO 8601 with a zone, from 400 days ago to 5 minutes ahead of the API's clock. |
amountMinor |
Whole minor units, as Stripe counts them (1299 is 12.99 EUR, 500 is 500 JPY), or atomic units of an asset. |
currency |
ISO-4217 (EUR, USD) or an asset symbol (USDC, USDC.e). |
amountDecimals |
Optional, USD only, 2 to 6: amountMinor is then in units of 10^-n dollars, for amounts under a cent. |
agentId |
Optional. One of your organization's agents. |
counterparty, description |
Optional. One line, up to 200 characters each. |
test |
Optional. true for test money (a test key, a test network). Default false. |
meta |
Optional. Up to 10 snake_case keys with plain values. Never put a secret here. |
Amounts are converted to USD with the same rates Burnbound uses for cards and refunds, rounding up. A currency without a rate is refused, never estimated.
The answer is 200 with inserted, duplicates, replaced (token rows a provider corrected) and connectorId. The refusals are:
| Status | error |
Why |
|---|---|---|
| 400 | invalid_request |
The body is not { "rows": [...] } with 1 to 500 rows. |
| 400 | invalid_row |
One row is wrong. index is the row and field the field (currency, occurredAt, …). |
| 403 | org_key_required |
A session or an agent key. Only an org key or your action gateway can send. |
| 403 | gateway_not_trusted |
A gateway signature that is not one of your organization's gateways. |
| 403 | plan_limit_reached |
Your plan has no observed spend (limit: "observed_spend"). |
| 404 | agent_not_found |
A row names an agent that is not yours. index is the first such row. |
| 413 | payload_too_large |
The body is over 1 MB. |
Which plans include it?
Observed spend and token cost are on Team and Business. On Free, adding an address, storing a batch and adding or moving key mappings answer 403 plan_limit_reached with limit: "observed_spend".
The limit only closes writes. What is already stored stays readable on every plan, and what already exists keeps working: an address registered before moving to Free is still read. The action gateway's Issuing and token syncs do not: their batches are writes and get 403 plan_limit_reached. Cost centers are on every plan; the reports that break spend down by them need reports (Team and Business).
How does Burnbound read token cost?
Your action gateway reads it with your provider's admin key and sends it to Burnbound as observed spend. The admin keys stay in the gateway and are only ever sent to their provider. Burnbound gets amounts by day, key, workspace or project and model: never a key and never a prompt.
GATEWAY_SYNC_LLM=anthropic,openai
ANTHROPIC_ADMIN_KEY_FILE=/run/secrets/anthropic_admin_key
OPENAI_ADMIN_KEY_FILE=/run/secrets/openai_admin_key
- Keys. For Anthropic, an Admin API key (
sk-ant-admin…), which an org admin creates in the Claude Console. For OpenAI, an admin key (sk-admin-…), which an owner creates in the organization settings. An ordinary API key cannot read cost and is refused at start.ANTHROPIC_ADMIN_KEYandOPENAI_ADMIN_KEYalso work, with a warning: a secret file keeps the key out of the process listing and the platform's logs. - Keep them safe. An admin key can do more than read cost in its provider. Keep it only in the gateway and rotate it if the gateway's secrets leak.
- What it reads. The cost of each closed UTC day, by API key, Anthropic workspace or OpenAI project, and model: one row per day, group and model. Amounts under a cent are kept to the micro-dollar.
- Tokens. OpenAI's cost comes with input and output tokens. Anthropic's cost does not, so its rows carry the amount and the model, with 0 tokens.
- No Stripe key needed. A gateway may run only this sync.
Token cost is visibility only. Burnbound does not proxy, limit or block model calls.
How do I map a key to an agent?
In Organization → Token cost, choose the provider, what you map and its id, and the agent:
| Provider | What you can map |
|---|---|
| Anthropic | An API key (api_key_id) or a workspace (workspace_id) |
| OpenAI | An API key (api_key_id) or a project (project_id) |
Write the id the provider shows in its console (apikey_…, wrkspc_…, key_…, proj_…), never the secret key. A value that looks like a key (sk-…) is refused with invalid_llm_mapping and never stored.
- Which agent a row gets. First the mapping of its key, then the mapping of its workspace or project. With neither, the cost belongs to the organization, with no agent.
- Who. Owners and admins add, move and remove mappings; anyone signed in to the organization reads them, viewers included. Up to 500 per organization. Each change is audited (
llm_cost_mapping.created,llm_cost_mapping.updated,llm_cost_mapping.deleted). - When it applies. The gateway reads the mappings, signed, at the start of each pass. The next read files that id's cost under the agent.
The same mappings are on the API at /v1/observed-spend/llm-mappings (GET, POST, PATCH and DELETE).
What happens when a provider corrects a day?
Providers revise their cost after the fact, so the gateway reads days again:
- First pass: the last 7 days. Each pass then reads at most 14 new days, plus the ones it reads again.
- Every pass: the last 2 days it sent.
- Every 6 hours: every day the provider may still revise: the current month and, until the 8th, the month before, never before the first day the gateway read.
- Anthropic: a day Anthropic has not finished counting is read later.
A corrected amount replaces its row in Burnbound. Only token rows are replaced; Issuing and on-chain rows are insert-only. The replaced row gets its cost center stamped again, and the audit records observed_spend.corrected with the amount and the agent it had before. A row the provider stops returning is not deleted.
Moving or removing a mapping uses the same rereads. Within a few hours, this month's cost filed under that mapping moves to the new agent (until the 8th, last month's too). If you removed it, the cost goes to the agent of its workspace or project, if one is mapped, or to the organization. Older cost keeps the agent it had.
What if the token sync fails?
Each provider's read shows as its own source under Organization → Observed spend, Action gateway (Anthropic tokens) or Action gateway (OpenAI tokens), with its status and last read. An error is a code, never the provider's message:
| Code | What to do |
|---|---|
provider_unauthorized |
The provider rejected the admin key (401). Check or rotate the key file on your gateway. |
provider_forbidden |
The key cannot read usage and cost (403). Give it that permission, or use an admin key. |
provider_rate_limited |
The provider is limiting requests (429). The gateway tries again; nothing to do unless it lasts. |
provider_unavailable |
The provider did not answer. The gateway tries again on its next read. |
provider_invalid_response |
The provider answered in a shape the gateway does not know. Update the gateway to the latest image. |
burnbound_refused |
Burnbound refused the rows the gateway sent. The reason is in the gateway's log. |
An error with one provider never stops the other one or the refunds. The gateway waits out a 429 (its retry-after, at most a minute, three times) before it reports it.
What is a cost center?
A label on each agent that says whose budget its spend belongs to, such as Marketing or CC-1001. There is no list to set up: it is free text per organization, 1 to 64 characters, starting with a letter or a digit, then letters (A–Z, no accents), digits, spaces or . _ / -. Spaces at the ends are trimmed; clearing it in the panel (or null on the API) removes it.
- Who changes it. Owners and admins, in the agent's panel, with the centers already in use as suggestions. Everyone else sees it read-only. Each change is audited (
agent.cost_center_changed). - It is stamped. Each payment keeps the cost center its agent had when it was reserved, cards and refunds included. Changing it never moves past payments. Observed and token rows keep the center the agent had when they were stored.
- In the monthly report. By cost center splits spend by the center stamped on each payment. Blocks and approvals, which only know the agent, go to the agent's current center.
payments.csvhas a lastcost_centercolumn.
On the API: PUT /v1/agents/:agentId/cost-center (a signed-in owner or admin; any API key gets 403) and GET /v1/org/cost-centers (the centers in use, for any signed-in role).
What is in the accounting export?
What settled in a UTC calendar month, by cost center, rail and currency, with a total per center: the file finance takes to its books. Download it from Accounting export in the monthly report, or from the API: GET /v1/reports/accounting.csv?month=YYYY-MM and GET /v1/reports/accounting?month=YYYY-MM (JSON).
- The settlement date counts. Only payments in
settled, by their settlement time (UTC), not when they were reserved. A payment reserved on the 31st at 23:50 and settled after midnight belongs to the next month. - Managed spend only. Observed spend and token cost are not in it.
- Test money apart. Test rows (
test=true) come after the real ones and never add to a total.
| Column | What it holds |
|---|---|
month |
YYYY-MM. |
cost_center |
The center stamped on the payments. Empty: no cost center. |
rail |
x402, mpp, card or action. total on a center's total row. |
asset |
The ISO currency for Stripe, or the asset symbol (USDC, USDC.e). |
amount_original |
The sum in asset, with its own decimals (500 JPY, 1.234 KWD). Empty for an asset Burnbound does not know, never estimated. |
amount_usd |
What the caps counted. For MPP it includes the fee the buyer may pay. |
payments |
The number of payments. |
refunds_executed |
The refunds the agents executed through the action gateway. |
test |
true for test money. |
In the CSV, each center's rows come first and then its total row (asset and amount_original empty). The file is named burnbound-accounting-YYYY-MM.csv and starts with a byte order mark, unless you add bom=0. The JSON gives rows (each with test) and totals (real money only). Without month you get the current month; a month that has not started is 400 invalid_month. Both are cut to what your plan shows.
Where do I see it?
| Where | What you see |
|---|---|
| Organization → Observed spend | Every source (addresses, Issuing, each token provider) with its agent, status, last error and last read. Owners and admins add and remove addresses. |
| Organization → Token cost | The key, workspace and project mappings to agents. |
| The agent's panel | Total cost this month: through Burnbound, observed by source, tokens by provider and model (with input and output tokens when the provider gives them), and the total. Also its cost center. |
Monthly report (/app/informe) |
By cost center, the accounting export, an Observed spend block (by source and agent, and the total cost with Burnbound) and a Token cost block (by provider, model and agent). |
Wherever observed spend and token cost appear, they are marked visibility only and stay out of Burnbound's own totals.