Ask a provider dashboard what your AI spend was last month and it answers immediately. Ask it what that spend was for and it goes quiet. That gap is what AI cost attribution closes.
AI cost attribution is the practice of tracing every unit of AI spend, model API calls, tokens, tool calls and compute, back to the agent, team, customer, feature or model that generated it. Done properly, the invoice stops being one number and becomes a set of answers: which agent cost the most, which customer is unprofitable, which feature is worth its token bill, and which deploy made the line move.
This post is the definition and the mechanics. If you already know what it is and want the implementation, how to track OpenAI costs by agent, customer and feature is the hands-on version.
Why the invoice cannot do it
Provider billing is organised around the things the provider can see: an API key, sometimes a project or workspace, and a model. Everything your business cares about lives one layer up, in your own code. Three consequences follow.
- Keys are shared. Most teams put several agents behind one key because rotating per-agent keys is operational friction nobody wants early. The moment two agents share a key, neither the provider nor you can separate them from the invoice.
- Your dimensions were never sent. The provider sees requests. It does not see
support-triage,acme-corporinbox-autoreply, because those are labels in your application. No export can recover a label that was never attached. - It arrives late and aggregated. Usage lands by day, invoices by month. A retry loop that starts at 09:00 is a bump in tomorrow's bucket and a shock on the first of next month.
The composite incident in anatomy of an £8,900 token bill is what the gap looks like in practice: one agent, a shared key, and 33 days between the bug shipping and anyone knowing which agent to look at.
The five dimensions
Attribution is only useful along the lines your business already thinks in. In practice there are five, and most teams need three of them on day one.
- Agent. The unit that goes wrong. Loops, runaway retries and context windows that doubled after a prompt change all show up first as one agent's line pulling away from the others. This is the dimension you alert on.
- Team. Who owns the agent and therefore the budget. The dimension finance asks for first, and the basis for any showback or chargeback.
- Customer. Cost to serve. The number that decides whether a flat-rate plan is profitable for everyone, or for everyone except four accounts.
- Feature. Whether a product surface is worth its token bill. A feature that costs £1,200 a month and drives retention is a bargain; the same £1,200 on a feature nobody opens is waste, and the invoice cannot tell them apart.
- Model. What a provider swap or a mid-month upgrade did to unit cost. A model that is cheaper per token can still be more expensive per completed task if it needs more turns.
Agent, customer and feature are set by the code that runs the agent. Team usually maps from agent. Model comes free with every call.
Two places you can attribute
Attribution can happen at two layers, and the difference matters more than any tool choice.
Infrastructure side
Give every agent, team or environment its own API key, project or workspace, and let the provider's own reporting split the bill. On AWS Bedrock the equivalent is inference profiles and cost allocation tags; behind a gateway it is per-route accounting.
This works for as long as your dimensions line up with keys. It stops the moment you want cost per customer, because you are not going to issue a key per customer, and it says nothing about features. It is a reasonable first step and a poor final answer.
Application side
Tag the run. At the point your code starts an agent run it knows the agent, usually the customer, and often the feature. Record those with the token counts on one event per run, and price it afterwards.
{
"run_id": "run_018f4c2a...",
"agent_id": "support-triage",
"customer_id": "cus_8821",
"feature": "inbox-autoreply",
"model": "gpt-4o",
"input_tokens": 2480,
"cached_tokens": 1900,
"output_tokens": 514,
"parent_run_id": null,
"status": "success"
}
Every breakdown in the previous section is now a GROUP BY on this record. The provider still bills you by key, and you reconcile against it, but you no longer depend on it for answers.
What a working setup needs
A tagged event is the floor. Five more things turn it into attribution you can trust.
- A rate card, applied at ingest. The event carries facts, tokens and a model name; the price lives in a maintained table per provider and model. Pricing server-side keeps the number consistent, survives provider price changes, and lets you backfill. The rate card is a first-class object, not a spreadsheet.
- Cache-aware pricing. Anthropic prompt-cache reads and OpenAI
cached_tokenscost a fraction of fresh input. Attribution that prices them as fresh input overstates every cached agent and hides the saving you are trying to measure. Prompt caching covers the mechanics. - Parent runs. When one agent calls another, the spend lands on the callee while the reason lives in the caller. Record the parent run so cost rolls up the tree and a customer request has one total. When one agent calls another, whose budget is it? is the long version.
- Cost per successful run as the headline. Total spend rises with volume and hides failure. Cost-per-successful-run isolates efficiency: an agent whose total is flat but whose cost per success is climbing is failing more often, and only this metric shows it.
- A baseline, not just a budget. A budget tells you the month is over after the damage. A rolling per-agent baseline tells you this morning that
research-agentis spending three times what it spent yesterday. You want both; only the baseline catches a loop on day one.
Showback, chargeback and what to do with the numbers
Once spend is attributed, the FinOps vocabulary applies. Showback is making the AI cost of each team visible to that team with no money moving. Chargeback is billing it to their budget. Most companies start with showback, because the first thing attributed cost reveals is usually a surprise, and surprises are better discussed than invoiced.
Three uses justify the work on their own.
- Margin protection. Per-customer cost against per-customer revenue, so the four power users on a £99 plan who cost £140 a month each stop being invisible.
- Investment decisions. Per-feature cost against usage, so the LLM line on the P&L becomes a set of per-feature bets you can cut or double.
- Incident response. Per-agent cost against its own baseline, so a bad deploy is a page at 10:00 rather than a question from finance on the first of the month.
How Agent Ping does it
Agent Ping is built around the cost-tagged run described above. The SDK wraps an agent run, records every model and tool call inside it with token counts, and carries customer_id, feature and the parent run. Cost is priced on our servers from a maintained rate card, cache-aware, and rolls up by agent, customer, feature and model in the dashboard. Every agent gets a rolling baseline and an optional budget, and runs that arrive without tags are flagged rather than silently lumped in. The Spend page has the details and the Spend docs go one level deeper.
The short version
AI cost attribution is tracing spend to its cause. The provider invoice cannot do it because the causes live in your code, so the tagging has to happen there: one event per run, priced from a rate card you control. Agent, customer and feature are the three tags that matter first. Cost per successful run is the number to put in front of finance, and a per-agent baseline is the alert that catches the loop before the invoice does.
If you are running more than one agent on a shared key with no per-run cost data, the absence of attribution is already the bug. Start with one agent; the free plan covers two.