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

# The insights rollup model: read-time derivations over existing events

> What the Insights page family actually is — read-time rollup queries over the event, cost, and call stores you already own, with no new tables and no write-path changes; which surfaces read public-scope versus tenant-scope data; and how to reconcile insights numbers against the billing ledger.

# The insights rollup model

The Insights pages — LLM spend, call attribution, conversation P\&L,
containment and ROI, no-match mining, anomaly insights, language
quality — look like ten different dashboards, but they share one
design: every one of them is a **read-time rollup over stores the
platform already maintains**. This page is the mental model behind
the family: where the numbers come from, and why they come from
public scope in one case and tenant scope in the rest.

## No new tables, ever

Each insights surface is only a query. The call-attribution header
states the rule for the whole family: **"no new table, no migration,
and NO change to the write path."** The write paths stay exactly the
write paths the product already has — the voice SIP webhook and call
ledger, the message ledger, the LLM cost ledger, the agent runtime —
and insights reads aggregate them after the fact.

That design has three consequences worth knowing:

* **History is free.** A new insights surface answers questions about
  events that happened before the surface existed, because it reads
  the same stores the product already wrote to.
* **The write path never waits for analytics.** Nothing on the
  insights side inserts, updates, or blocks a send, a call, or an
  agent turn — the [read-replica separation
  invariant](/concepts/analytics-pipeline) holds here exactly as it
  does for the Analytics API.
* **Config is the only mutation.** The few writable knobs (budget
  caps, ROI rubric values, labour rates) live in your organization's
  settings, not in a new schema object.

This is deliberately distinct from the
[analytics pipeline](/concepts/analytics-pipeline) event spine: the
pipeline pre-aggregates delivery/cost series in the background into
hour/day buckets for time-series charts. The insights family
**derives** its aggregates at read time over the raw event and cost
stores — it adds no background producers and no stored roll-up rows
of its own.

## The public-scope vs tenant-scope split

There is exactly one public-scope store in the family: the LLM cost
ledger.

LLM spend is vendor cost — what Devotel pays the model provider and
what your organization is billed per call. That ledger records every
call with its model, token counts, channel ("voice", "sms", "inbox",
"kb", and so on), actual cost, and billed cost, and it records them
**indexed by organization, in public scope**. The rationale is
operational: the daily reconciler that compares the ledger against
the provider's billing can stay a single query instead of fanning out
across every tenant schema. The ledger is org-scoped inside public
scope — your reads still only ever return your own organization's
rows.

Everything else in the family reads **tenant-scoped** stores: the
per-tenant conversation, message, and call tables under [tenant
isolation](/concepts/tenant-isolation). Containment, ROI,
conversation P\&L, call attribution, no-match mining, and language
quality all aggregate the tenant schema — because those surfaces read
*your* conversations and calls, and your conversations and calls live
in your tenant schema, full stop.

## The surface map

| Surface                                                                  | Answers                                                                                                         | Reads                                                                                          | Config lives at                                                                                                                              |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **LLM spend by feature, model, and channel**                             | Which AI feature (agent-assist, transcription, summarisation, KB) and which model is driving cost               | The org-scoped LLM cost ledger (public scope)                                                  | Budget caps under `ai_budget` (monthly cap, daily cap, per-channel thresholds, alert percent, downshift model) in your organization settings |
| **Call attribution**                                                     | Which marketing source and campaign drove inbound calls to your tracking numbers                                | Tenant-scoped inbound call logs, joined at read time to the tracking-DID → source map          | The tracking number pools you already configure per DID                                                                                      |
| **Conversation P\&L**                                                    | Blended cost-to-serve: telco + LLM + human handle-time per conversation, per resolution, per conversion         | Tenant-scoped call, message, conversation, and queue-time tables                               | The human-agent hourly rate in your organization settings (defaults to \$30/hr)                                                              |
| **Containment & agent ROI**                                              | Resolution without a human handoff (containment), and spend versus attributed revenue versus margin per agent   | Tenant-scoped conversation statuses + rubric outcomes                                          | Per-rubric revenue values in your organization settings                                                                                      |
| **No-match mining**                                                      | Contact reasons your AI has no coverage for, and suggested KB articles or exemplars                             | Tenant-scoped conversations cross-referenced with topic intelligence                           | Suggestion-only config in your organization settings — the miner never auto-writes knowledge                                                 |
| **Anomaly insights**                                                     | A time-stamped ledger of spend/fraud anomalies, split into wallet-velocity versus inbound/webhook signal scopes | The platform's anomaly review records                                                          | Detector thresholds you already set in billing/compliance settings                                                                           |
| **Language quality**                                                     | Whether containment, resolution, sentiment, and CSAT hold per customer language                                 | Tenant-scoped conversations, segmented by the conversation's language tag or detected language | None — derived entirely from existing conversation metadata and the                                                                          |
| [conversation intelligence](/concepts/conversation-intelligence) signals |                                                                                                                 |                                                                                                |                                                                                                                                              |

Every monetary figure in the family is integer cents end to end, with
one rounding boundary at the render layer — the same convention the
[wallets and credits](/concepts/wallets-credits-and-charges) model uses.

## Worked example: one tracking-DID call rolling up to a campaign

You assign the tracking number `+1-415-555-0132` to a pool labelled
"Paid search — Q3", bound to source `google`, medium `cpc`, and
campaign `q3-brand`. A customer sees the ad, dials the number, talks
for 6 minutes, and hangs up answered.

At read time, call attribution:

1. Loads your tracking pools and builds the map
   `+1-415-555-0132 → { source: "google", medium: "cpc", campaign: "q3-brand" }`.
2. Aggregates inbound call logs whose dialled number is one of your
   tracking DIDs, per DID, over the window.
3. Rolls the per-DID rows up by source + campaign.

The row the attribution dashboard then shows for that campaign:

| Field                                             | Value                                                                       |
| ------------------------------------------------- | --------------------------------------------------------------------------- |
| `source` / `campaign` / `medium`                  | `google` / `q3-brand` / `cpc`                                               |
| `tracked_numbers`                                 | `1`                                                                         |
| `calls` / `answered` / `missed`                   | `27` / `19` / `8`                                                           |
| `answer_rate`                                     | `70.4` (answered ÷ calls × 100, one decimal; null when calls is zero)       |
| `total_duration_seconds` / `avg_duration_seconds` | `9,477` / `351`                                                             |
| `unique_callers`                                  | Upper bound — a caller who dialled two DIDs of the same source counts twice |

Cost stays out of this surface on purpose: call attribution is a
volume-and-outcome view. Revenue attribution lives with the CDP
revenue-attribution analytics, so the two surfaces' numbers line up
by window, not by ledger.

## What integrators branch on

**Read-time derivations versus stored rollups.** The insights family
derives at read time, as described above — there is no stored
insights aggregate to drift out of sync and no backfill to run. When
you compare an insights figure against an
[analytics pipeline](/concepts/analytics-pipeline) figure, expect the
pipeline's number to be the *same count* served from a pre-aggregated
bucket for the chart-friendly hour/day widths; a live-read insights
surface may resolve the last minute slightly fresher at a narrow
window.

**Reconciling against the billing ledger.** The insights numbers are
*attribution and unit-economics* numbers; the billing ledger is
*what you were charged*. They deliberately disagree in two places:

* **LLM spend versus billing.** The ledger records both actual cost
  (what the provider charges) and billed cost (what you're charged)
  per call. Insights reads the ledger the same way billing does, but
  P\&L and ROI *blend* that cost with telco and human handle-time —
  a P\&L "cost to serve" is by design larger than the LLM line on
  your bill.
* **Projections.** The month-end projection on LLM spend is a
  forecast (last-7-day average × days left), not a stored ledger
  row — treat it as guidance, reconcile only the month-to-date.

**Rates and windows.** Ratios — containment, resolution, answer rate,
margin — recompute over your chosen window, and a window with zero
conversations returns `null`, not `0`. Branch on null in your
integrations rather than coercing it.

## Where to go next

* [Analytics pipeline](/concepts/analytics-pipeline) — the event
  spine and background roll-up producers behind the time-series
  analytics endpoints.
* [Conversation intelligence](/concepts/conversation-intelligence) —
  the per-conversation sentiment, topic, and quality signals several
  insights surfaces consume.
* [Tenant isolation](/concepts/tenant-isolation) — why conversation
  rollups stay tenant-scoped.
* [Insights API reference](/api-reference/insights) — endpoint shapes
  for every surface.
* Guides: [LLM spend dashboard](/guides/insights-llm-spend),
  [Insights dashboards](/guides/insights-dashboards),
  [Dashboard builder](/guides/insights-dashboard-builder),
  [Topic intelligence](/guides/insights-topic-intelligence).
