Get 2,500 events tracked for freeSign up now

All posts
Syed Raza5 min readAttribution, Cost per run

A provider bill has no agents on it

A billing API reports what an account spent, by model and by day. Agents are not a dimension it carries, so per-agent spend split out of it is an allocation.

A provider's billing API reports what an account spent, grouped by the dimensions the provider keeps: the account, the model, the billing period, and sometimes the credential. Agents, runs, sessions and customers are not among them. So a per-agent dollar figure derived from a bill is not read off it — it is an allocation of the account total, divided up against usage you measured somewhere else. The instrumentation you hoped the bill would replace is still the thing doing the attribution; the bill only supplies the total.

Pulling costs down from the bill, or recording them at the call

There are two directions to derive a cost figure from, and they fail differently.

A Show HN posted on 2026-10-20 for a self-hosted spend attribution tool is a clear statement of the first one, because its author describes the design plainly. Asked whether it prices tokens itself, they answered that it does not:

Nope, Costura doesnt calculate token prices. It pulls actual costs from each provider billing API, so price changes and new models are picked up automatically

That is top-down: take what the provider says was charged, then divide it. Bottom-up is the other direction — record each call as it happens together with the identity of whatever made it, then price the usage and add it up. Cost attribution in a multi-agent system is a question about the second direction, because every unit it asks about — this agent, that run, this customer — is a unit the provider never saw and therefore never grouped by.

When the credential dimension is missing too, the split becomes a model

The same comment continues into the case where even the coarse dimension is absent:

Anthropic is a bit tricky since costs arent reported per API key, so I split them based on token usage. Anything unmatched stays as 'unallocated' to keep totals accurate

That is the author's description of what their tool does, on 2026-10-20; we have not checked it against the provider's own documentation, and a reporting surface can change. What matters here is the mechanism rather than the vendor. Follow where each input comes from: the dollars come from the provider, and the proportions come from token counts collected on your side. The result is only as fine-grained as your own usage records, which means the instrumentation is carrying the attribution and the bill is carrying the magnitude.

It is also only as correct as the weighting. A split by total tokens treats a cache read, an uncached input token and an output token as equal slices of the same dollar, and they bill at different rates — the point argued in a model has no single price per token. An agent whose work is mostly long cached prefixes and an agent whose work is mostly generated output can report the same token count and have cost very different amounts.

Some spend never reaches the invoice you are splitting

A top-down split also inherits the invoice's boundary. Work done under a subscription or seat credential does not arrive on the per-token API statement at all, and which credential was in the environment decides which ledger the same work lands on. A commenter in a thread about a provider CLI on 2026-10-22 describes testing exactly that:

I basically unset any API env vars, ensured the cli credential was in place, and spawned agents and watched

Those agents ran, consumed capacity and produced output. None of it is in the API bill being divided, so every per-agent share computed from that bill is a share of a total that excludes them. This is the same substitution described in what a run costs depends on how the capacity was bought: the money moves to a different basis, and the work does not stop existing.

The unallocated bucket is the honest part

The most useful line in that Show HN comment is the one about the remainder: unmatched spend stays unallocated so the totals still add up. Keeping an explicit residual is the right move, and it is rarer than it should be. The alternative — distributing the leftover pro rata across the agents you did match — produces a report in which every figure is slightly wrong and nothing on the page says so.

A residual is also the only part of the exercise a third party can check. That is the argument made from the other side in a cost figure you computed is not a receipt: publish the difference rather than the match, because the difference is the error bar.

What the bill is genuinely better at

Two things, and both are real.

Rates change under you. A Hacker News submission on 2026-10-21 is titled "Alibaba hikes DeepSeek V4 Flash 0731 output prices by 230%". On the day a rate moves, a bottom-up figure stays wrong until somebody updates a price table; a figure pulled from the billing API is already right. That is the advantage the Show HN author claimed for the approach, and it holds.

And the account total is the number finance actually pays. A bottom-up system can be internally consistent and still drift from the statement, which is why the reconciliation only runs in one direction — your rows summed over the provider's billing window, compared against theirs.

A third option gets proposed whenever this comes up, and a Hacker News thread on 2026-10-19 puts it in its title: "If you don't run your own LLM proxy, how do you know whats going on?". A proxy writes the spend log at the point the request crosses it, which is a genuine answer to the grouping problem — and it groups by what crossed the wire: a key, a header, a tag someone attached. Which identities that can and cannot reach is covered in the identity a budget is keyed to.

What this means for how you build the figure

  1. Decide which half each number is. The account total is evidence. The division of it is a model, and a model has assumptions worth writing down.
  2. Weight a split by token class, not by token count, if you are splitting at all — and say which weighting was used on the report.
  3. Enumerate the credentials and plans in scope before trusting a total. Work billed to a subscription is absent, not zero.
  4. Keep a named residual. Unmatched spend is a quantity, and it belongs on the page rather than spread across the rows.

Where Capsera sits, and what it does not do

Capsera is bottom-up by construction. capsera.init() patches the provider clients — Anthropic messages, OpenAI chat completions, OpenAI embeddings and Google Gemini, sync and async — so every call in the process is captured, including calls a framework made rather than your code. @capsera.agent(name="planner") on a function you already have supplies the identity at the moment of the call through contextvars, so nested agents inherit it without per-request tags or a separate API key per agent. Budgets are scoped per agent, per team or globally and are checked before the provider call, so a blocking budget raises BudgetExceededError and no tokens are spent — which is only possible on this side of the line, since a bill arrives after the money is gone.

Two limits, stated. Capsera does not read provider billing APIs, so it does not inherit the automatic repricing described above: its dollar figures are computed from usage counts and a price table like everyone else's, and the account statement is still the thing to reconcile against. And the providers listed above are the patched ones — spend on a provider outside that list, or under a subscription credential your code never calls, is not in the picture at all.

If the grouping you need is per key, per team or per organisation across many providers, LiteLLM is MIT-licensed, free, covers 140+ providers and enforces hard budgets per key, team, organisation and model; that is the layer for it. If what you actually need is to see the prompts and traces behind a cost, Langfuse is open source, free and built for that, and Capsera stores hashes and token counts rather than content by design. Which layer answers which question is laid out in gateway vs observability vs governance.

Give every agent an identity, a budget, and hard limits.

One line of code. Anthropic, OpenAI, and Google Gemini.

See pricing