Final Router

AI cost attribution

One invoice, decomposed into causes

A blended AI bill is a number nobody owns. Label each request with the app, the customer and the run that caused it, and the same spend comes back split along all three - so you can price a feature, charge a customer, or find the one workload that doubled last week.

  • Four labels - app, end customer, session and tags - carried on the request and kept on the record
  • Cost lands on the response itself in cents, so your own logs can reproduce every figure in our analytics
  • Breakdowns are computed in the database over the whole window, never sampled - and the filtered view exports to CSV
One invoice, decomposed into causesON THE REQUESTX-Title: which appuser: which customerX-Session-Id: which runtags: your own axis$691this monthcheckout-assistant$412support-triage$188batch-tagger$91totals, not samples · exports to CSV
The same spend, split by the thing that caused it - because the request said which app, which customer and which run it belonged to.
Label it on the way in
POST /v1/chat/completions
X-Title: checkout-assistant          // which app
X-Session-Id: run_8f21c              // which run, with its own caps

{
  "model": "auto",
  "user": "acct_10023",              // which of YOUR customers
  "tags": ["tier:pro", "feature:summarise"],
  "messages": [ ... ]
}
Read the cost on the way out
"final_router": {
  "cost_cents": 0.84,
  "reason": "Chose claude-haiku-4-5 - lowest latency among healthy models."
}

// Four labels on the way in, one cost on the way out.
// Analytics then splits that cost by app, customer,
// session and model — computed over everything, not
// sampled from the first thousand rows.

What is AI cost attribution?

Cost attribution is the difference between knowing what you spent and knowing why. Provider invoices answer the first: one number per provider per month. The questions that actually come up - is this feature profitable, which customer is unprofitable, what changed on Tuesday - need the second, and no provider can answer them because the provider never knew which of your customers made the call.

The gateway does know, because you told it. Four optional labels ride along with each request, cost is computed per request at list price, and the two are stored together - so the month's spend decomposes along whichever axis you need to defend a number.

The four labels, and what each answers

All optional, all cheap to send, and each one turns a blended figure into an answerable question.

App - which product spent it

Send X-Title and every request is attributed to a named app. Analytics then shows cost, tokens and failures per app, which is the split most teams want before they want any other.

X-Title: checkout-assistant

Customer - who to charge

The user field names your own end customer. Cost per customer is the number behind usage-based pricing, and behind noticing that your heaviest account is your least profitable one.

body: { "user": "acct_10023" }

Session - which run

X-Session-Id groups an agent run into one story: every step, the total it cost, and where it went wrong. Sessions also carry their own spend and request ceilings, so a loop stops itself.

grouping and enforcement from one header

Tags - your own axis

Up to ten short tags per request for whatever your business actually splits on - a plan tier, a feature flag, an experiment arm. They are stored on the record and travel into the export.

10 tags, 40 characters each

AI cost attribution

Best practices - the order that works

  1. 01

    Send X-Title from day one

    It costs one header and it is the label you will miss most when a bill doubles. Unlabelled traffic cannot be attributed retroactively - the request is already gone.

  2. 02

    Use the customer field even before you bill for usage

    You do not need usage pricing to benefit from knowing which account costs what. You need it the first time someone asks whether the enterprise tier pays for itself.

  3. 03

    Tag anything agentic with a session id

    It is the only label that is also a control: a session carries spend and request ceilings, so labelling a run also bounds it.

  4. 04

    Keep tags low-cardinality

    A tag per plan tier is useful; a tag per request id is noise you will pay to store and never group by. If it is unique per call, it belongs in the customer field or nowhere.

  5. 05

    Reconcile once, then trust the number

    Export a month to CSV and check our cost figure against the provider invoice. Once they agree, stop doing it - the arithmetic is the same code that bills you.

Attributed at the gateway vs reconstructed later

Final RouterProvider invoices
Cost per requestOn the response, in cents, at request timeDerived from token counts afterwards
Per customerA field on the requestThe provider never knew your customers
Per app or featureA header on the requestOne number per provider
Per agent runSessions, which also carry spend ceilingsNot represented at all
Getting it into a spreadsheetCSV of exactly the filtered viewPDF invoices, one per provider
Totals vs samplesAggregated in the database over the whole windowWhatever the dashboard sampled

FAQ

Do I have to label everything?

No - every label is optional and unlabelled traffic still bills, logs and appears in totals. But attribution is only ever forward-looking: a request that arrived without a label cannot be attributed later, so the cheap move is to send X-Title from the first day and add the others when a question makes you want them.

Are the breakdowns totals or samples?

Totals. Every breakdown is aggregated in the database over the whole window you selected - by app, by end customer, by session, by model and by error reason. Nothing is computed from the first page of rows, which is the usual way a dashboard quietly lies about a long tail.

Can I get the raw rows out?

Yes. The log exports to CSV, and it exports exactly what the screen is showing - the same filters, read from the same query string - so an export can never contain more or fewer rows than the view you were looking at. It exists for reconciling against a provider invoice and for charging a customer their share.

Does labelling cost anything or slow requests down?

No. The labels are headers and two body fields; they are stored alongside the usage record that gets written anyway. There is no extra call and no extra charge.

Does this store my prompts?

No. Attribution is metadata - which app, which customer, what it cost, how it behaved. Prompt and completion text is only stored if you separately switch that on, and even then it is kept for a window you choose, up to thirty days.

Turn one number into an answer

Add X-Title to your next request and the following month's spend arrives already split by the thing that caused it.

Related: LLM observability, AI spend management, smart LLM routing, pricing.