Skip to main content

LLM spend attribution

The insights rollup model page explains how the Insights family computes its numbers — read-time derivations over existing stores. It deliberately does not answer the two attribution questions finance and operations ask about AI spend:
  1. Which feature spent the money? (agent-assist, voice transcription, summarisation, KB retrieval — the channel axis)
  2. Which model spent the money? (per-model cost, billed amount, and margin)
This page names the model behind those answers: a single LLM cost ledger, three attribution axes over it, and two daily reconciliation workers that keep the ledger honest against the provider’s bill. It also covers the third axis — the conversation — and how conversation P&L composes the LLM leg with telephony and human-time legs into one cost-to-serve number.

Attribution vocabulary

Every AI call your organization makes lands as one spend row in the LLM cost ledger. Each row can be cut along three axes: The feature and model axes read the org-scoped cost ledger directly. The conversation axis joins to the tenant-scoped conversation store, because your conversations live in your tenant schema under tenant isolation. Money convention. Every monetary figure on these surfaces is integer cents in your organization’s wallet currency, rounding once at the aggregation boundary — the same convention as the wallets and credits model. Sub-cent token rates are carried at higher precision inside the aggregation and rounded at render, so a channel mix dominated by cheap calls still reports a truthful unit cost. The API never FX-converts; formatting to dollars is the client’s job. Actual vs billed. The ledger records two money values per call: what the model provider charges (actual cost) and what your organization is charged (billed cost). The by-model surface reports both, plus the margin between them — so a loss-making model mix is surfaced faithfully, not clamped.

Where the rows come from

Per-turn token usage is recorded by the agent runtime as it executes. The LLM-spend endpoints — overview, summary, timeseries, top-conversations, by-feature, by-model — are read-aggregates over those rows, not a second ledger. There is no separate insights write path, no stored rollup to backfill, and no drift between “what was recorded” and “what is shown” beyond read-replica lag. That placement is the deliberate design described in insights rollup model: the LLM cost ledger is the family’s one public-scope store, kept in public scope precisely so the daily reconciler (below) can compare it against the provider’s bill in a single query instead of fanning out across every tenant schema. Org scoping inside public scope means your reads still only ever return your own organization’s rows.

The reconciliation workers

Two daily workers keep the ledger and the pricing catalog honest:
  • Cost reconciler. Once a day (the worker gates itself to the first run after 02:00 UTC, targeting the settled prior day), the reconciler pulls the previous day’s spend from the model provider’s usage-report API sliced by workspace, and compares it against the ledger’s sums for the same day. “Reconciled” means the ledger and the provider’s bill were compared and the drift, if any, was measured. Drift under the tolerance threshold is logged and tolerated; drift over it raises an alert for finance to investigate. The reconciler deliberately does not auto-correct internal accounting — an auto-correcting loop against an external bill risks runaway adjustments, so correction is a human-in-the-loop step. While a correction is pending you can see a row whose cost looks zero or negative relative to what you expect: that is the signature of a pending reconciliation, not a metering gap.
  • Model-catalog sync. A second daily worker polls the provider’s model index and warns when any model the platform’s intent map references has been deprecated or scheduled for sunset. It never auto-rewires the intent map — per-model pricing stays resolvable because someone is told before a model id disappears, and model promotion remains an intentional release decision.
Both workers follow the bounded re-run pattern shared with the scheduler fleet model: a single-flight tick with an idempotency stamp, so a re-run within the same day is a no-op and a failed tick retries on the next hour until it succeeds.

How conversation P&L composes

The third axis — the conversation — is where the spend stops being an AI-only number. Conversation P&L joins up to four legs per window: The surface reports the composed totals — cost-to-serve, then cost-per-conversation, cost-per-resolution, and cost-per-conversion. Any ratio with a zero denominator returns null, not 0; branch on null in integrations rather than coercing it. P&L composes from the same recorded charges the rest of the money surfaces read, so it reconciles: the telco leg totals match the Channel-costs totals on the cost-intelligence dashboards, and every debited amount is the same money the wallet ledger carries. A P&L cost-to-serve is by design larger than the LLM line on your bill, because it blends in telco and human time; it never contradicts the wallet ledger, it extends it.

Freshness and staleness

  • The insights reads go to a read replica, so they lag the primary by a few seconds — a just-finished conversation may be absent from the last sliver of the window.
  • Budget windows (daily cap, monthly cap) resolve in your organization’s billing timezone, so a cap-breach row flips at your local day boundary, not at UTC midnight. The day-bucketed timeseries aligns with the same zone, so the chart and the cap ring agree on what “today” means.
  • The month-end projection on the overview is a forecast (recent daily average × remaining days), not a stored ledger row — treat it as guidance and reconcile only the month-to-date figure.
  • The reconciler targets the settled prior day, so yesterday’s ledger totals are provisional until the morning reconciliation run confirms or flags them.
This is deliberately different from the analytics pipeline: the pipeline pre-aggregates hour/day buckets in the background, while these money surfaces derive at read time. Expect an analytics time-series to be the same count served from a stored bucket, and an insights surface to resolve a narrow window slightly fresher.

What this is NOT

Reading guide: auditing one conversation

A full audit of one conversation’s AI spend takes four steps:
  1. Pick the conversation. List the most expensive threads in the window:
  1. Read its P&L legs. Pull the blended cost-to-serve and check which leg — telco, LLM, or human time — dominates:
  1. Match token spend to the by-model totals. Group spend by model over the same window and confirm the conversation’s model rows sum into the aggregate:
  1. Verify reconciliation. For any day older than yesterday, the cost reconciler has already compared the ledger against the provider’s bill. If a figure looks off and the day is current, treat it as provisional until the next 02:00 UTC run; for settled days, drift over the tolerance threshold is alerted rather than silently corrected, so a flagged day is the thing to investigate — not the dashboard.

Where to go next