Blog

AI cost allocation: how to attribute LLM spend to people and teams

Providers report cost by workspace, not by person. A practical method for allocating LLM spend to the people and teams behind it, and the rules that keep it honest.

Sep 7, 2026 · 5 min read

Cost allocation is an old finance discipline with a new problem. The old version splits a shared cost, like rent or a data center, across the departments that benefit from it, using a driver like headcount or square footage. The new version has a shared cost that changes every hour, a driver that the provider measures precisely, and identifiers that are not departments or people but strings.

This is a method for doing it well, written for the person who has to defend the result.

What the provider gives you, and what it withholds

Start with what is actually reported, because the method has to fit the data rather than the other way around.

Anthropic's admin API reports token usage per day by API key, workspace, model and service tier. It reports cost per day by workspace and by token type. It does not report cost by key. OpenAI's admin API reports usage by project, key, user and model, and cost by project and line item. Again, not by key.

So on the API surface, tokens are known at the key level and dollars are known one level up. That gap is the whole allocation problem. On the seat surface it does not exist: Claude Enterprise and ChatGPT Enterprise report usage and cost per named user, because the person was signed in. Those figures need no allocation at all, and the method below should never touch them.

The method: token-share allocation

For each day, and for each cost bucket the provider reports, split the bucket across the keys that used tokens of that kind in that bucket, in proportion to their tokens.

Concretely, a bucket is one day, one workspace, one model, one service tier and one token type: uncached input, cached input, cache writes, output. The provider prices each token type differently, which is why the split has to happen per type rather than on a total. A key that did nothing but read from cache should get a small share of the cache-read bucket and no share of the output bucket.

The arithmetic is a proportion. If three keys used 60 percent, 30 percent and 10 percent of a bucket's output tokens, they get 60, 30 and 10 percent of that bucket's output dollars. Do the split in whole micro-dollars with largest-remainder rounding, so the shares add back to the bucket to the last digit. A day's allocated total should equal the provider's reported total, exactly, every time. If it does not, the reconciliation will fail at month end and the whole exercise loses credibility.

Four rules that keep it honest

Never allocate what has no driver. Some cost has no token type behind it: web search calls, code execution, tool use. It is real money and there is no principled way to attribute it to a key by tokens. Keep it as a reported total, show it as unallocated, and do not guess it onto anyone.

Never mix reported and allocated in one column without saying so. A seat figure is reported by the provider for a named person. An API figure is your allocation. Both are legitimate, but a finance team will ask which is which, and the answer has to be on the row.

Never spread unattributed spend. A key with no owner is a decision waiting to be made, not a rounding error. Spreading it across everyone makes every number slightly wrong and makes the missing decision invisible.

Re-attribute the past when a mapping changes. When someone finally identifies who owns a key, every historical row for that key should move to that person. Attribution is retroactive by design. A system that only applies mappings forward will show a person's spend starting on the day someone got around to the mapping, which is not when it started.

From keys to teams

Once dollars sit on keys and keys resolve to people, teams are a sum. Two things complicate the sum and both should be handled openly.

Shared keys. A key that a whole team uses is attributable to the team, not to any one person. Map it to the team directly, and count it against the team's figure and the team's budget. If you do not, budgets become trivially avoidable by routing through a shared key, and the team total is no longer the sum of its people, which the page should say.

Infrastructure keys. A key that runs a production service is not a person and not a team in the chargeback sense; it is the cost of a product feature. Mark it as infrastructure and keep it out of the people view entirely, while keeping it in the ledger.

Resolving keys to people

The mapping is the hard part, and there is no arithmetic that does it for you. What helps:

  • Providers sometimes name the user who created a key. When they do, the key resolves to that person automatically. Use it.
  • A directory of people with emails, from the CRM or the identity provider, means that every account the provider names by email becomes a person without anyone typing.
  • What is left goes in a queue, sorted by spend. The person doing the mapping should see the biggest unknown first, with the key's name and its usage pattern, and be able to resolve it to a person, a team or infrastructure in one choice.
  • Every mapping is an audited change. Attribution moves money between people; someone will ask who moved it.

What the result is for

A per-person allocation is not a chargeback invoice, or not only that. Its real use is that it lets spend sit next to output. Once a sales rep's AI cost is a number, so is their AI cost per closed-won dollar, and once that ratio exists for every rep, the conversation changes from "we spend too much on AI" to "these people spend more and produce more, and these do not". That is the conversation worth having, and the allocation is the price of admission.

Arbitir implements this method as described: token-share allocation per bucket with largest-remainder rounding, reported seat figures kept separate, unallocated cost kept visible, an unmatched queue sorted by spend, retroactive re-attribution, and an audit row for every mapping.