> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# LLM spend attribution: feature × model × conversation, and the reconciliation behind it

> The money-attribution model behind the LLM-spend and conversation P&L surfaces — the three attribution axes (feature, model, conversation), the public-scope cost ledger the dashboards read, the daily Anthropic reconciliation workers that keep the ledger honest, and how conversation P&L composes spend, telephony, and revenue into one cost-to-serve view.

# LLM spend attribution

The [insights rollup model](/concepts/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:

| Axis             | One row answers                                                                                         | Source field it groups by                                |
| ---------------- | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| **Feature**      | Which AI capability (voice, SMS, inbox, KB, …) burned the budget                                        | The row's recorded `channel`                             |
| **Model**        | Which model id ran the call, what it cost Devotel, what you were billed, and the margin between the two | The row's recorded `model`                               |
| **Conversation** | Which single thread (and which agent ran it) was expensive, so outliers surface                         | The tenant-scoped conversation row the spend attaches to |

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](/concepts/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](/concepts/wallets-credits-and-charges) 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](/concepts/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](/concepts/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:

| Leg         | What it prices                                                                        | Source                                      |
| ----------- | ------------------------------------------------------------------------------------- | ------------------------------------------- |
| **Telco**   | Voice minutes and SMS/MMS on the conversation's calls and messages                    | Your tenant-scoped call and message ledgers |
| **LLM**     | The token spend the conversation's AI turns consumed                                  | The LLM cost ledger                         |
| **Human**   | Human-agent handle time, priced at an hourly rate you configure (defaults to \$30/hr) | Tenant-scoped queue handle-time totals      |
| **Outcome** | Resolutions and conversions, as denominators                                          | Conversation outcome records                |

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](/guides/cost-intelligence), and every debited amount is
the same money the [wallet ledger](/concepts/wallets-credits-and-charges)
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](/concepts/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

| Surface                                                                                                           | What it owns                                             | What this page is not                                                                         |
| ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [Usage records](/concepts/usage-records-model)                                                                    | Per-record metering of messages and calls — the CDR feed | The usage-records feed meters telco and messaging units; LLM token rows are a different store |
| [Insights rollup model](/concepts/insights-rollup-model)                                                          | The read-time-derivation design of the whole family      | This page names the attribution taxonomy the family description skips                         |
| [Billing and wallet](/concepts/billing-and-wallet) / [wallets and credits](/concepts/wallets-credits-and-charges) | The ledger of what you were charged                      | LLM-spend figures are attribution numbers; the wallet ledger is the charge                    |
| [Spend anomaly and alert model](/concepts/spend-anomaly-and-alert-model)                                          | Wallet-velocity and fraud anomaly detection              | Budget-breach flags here are threshold arithmetic, not anomaly detection                      |

## 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:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/insights/llm-spend/top-conversations?limit=10" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

2. **Read its P\&L legs.** Pull the blended cost-to-serve and check
   which leg — telco, LLM, or human time — dominates:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/insights/conversation-pnl" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

3. **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:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/insights/llm-spend/summary?groupBy=model" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

4. **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

* [Insights rollup model](/concepts/insights-rollup-model) — the
  read-time derivation design behind the whole Insights family.
* [Usage records](/concepts/usage-records-model) — the per-record
  telco/messaging metering feed.
* [Wallets, credits, and charges](/concepts/wallets-credits-and-charges)
  — the ledger these attribution surfaces never replace.
* [Scheduler fleet model](/concepts/scheduler-fleet-model) — the
  bounded tick pattern the reconciliation workers share.
* Guides: [Read the LLM spend dashboard](/guides/insights-llm-spend),
  [Read the cost-intelligence dashboards](/guides/cost-intelligence).
* [Insights API reference](/api-reference/insights) — endpoint shapes
  for every surface mentioned here.
