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

# Worked insights queries

> LLM-spend drill-downs, anomaly rollups, agent benchmarks, attribution chains, containment trends, and quality evals — each as a full send → envelope → drill-in chain.

## Worked insights queries

Every operation below is catalogued on this page, but the values you branch
on — a spend spike's driver, a containment trend, an anomaly scope — are
easiest to learn as reader chains. The chains below answer a real operator
question end to end and show the exact `{ data, meta }` envelope at each
step so you can slice the field path you actually need.

Scope of this overlay:

* The chains cover six questions against the `Insights` catalogue; each one
  starts from the broad read, then narrows with a follow-up call. Where a
  dashboard guide exists, the overlay links it rather than repeat it.
* All samples show cURL and TypeScript — the generated operations above show
  all six languages on the first 15 blocks, cURL and TypeScript on the rest.
* All reads are tenant-scoped, read-only analytic aggregates over your own
  data. No provider account or compliance scope is touched; the tenant
  controls every filter, window, and scope parameter.

All `Insights` envelope responses share one shape: `data` carries the
payload, `meta.request_id` and `meta.timestamp` identify the read. Chain on
`data`, log `meta.request_id` when you report a discrepancy to support.

### 1. Which model drove the LLM spend spike

Start from the period summary, drill into the breakdown by model, then
confirm against cost-economics so you see spend in the same window as your
other AI economics.

`GET /api/v1/insights/llm-spend/summary`

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/llm-spend/summary" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "window_days=7"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/llm-spend/summary",
  );
  url.searchParams.set("window_days", "7");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.total_cents);
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "total_cents": 41250,
    "currency": "USD",
    "window_days": 7,
    "by_model_top": "gpt-5-thinking",
    "by_feature_top": "support_agent"
  },
  "meta": { "request_id": "req_llm_01", "timestamp": "2026-09-09T12:00:00.000Z" }
}
```

Now drill into the driver. `GET /api/v1/insights/llm-spend/by-model` breaks
spend per model; `GET /api/v1/insights/llm-spend/by-feature` breaks it per
feature surface. Slice `data.models[]` (or `data.features[]`) for the rows
that moved.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/llm-spend/by-model" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "window_days=7"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/llm-spend/by-model",
  );
  url.searchParams.set("window_days", "7");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.models.map((m) => `${m.model}: ${m.cents}`));
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "models": [
      { "model": "gpt-5-thinking", "cents": 30112, "share_pct": 73.0 },
      { "model": "claude-opus", "cents": 7214, "share_pct": 17.5 },
      { "model": "gpt-5-mini", "cents": 3924, "share_pct": 9.5 }
    ],
    "window_days": 7
  },
  "meta": { "request_id": "req_llm_02", "timestamp": "2026-09-09T12:00:01.000Z" }
}
```

Put the spend in the same window as your AI economics:
`GET /api/v1/insights/cost-economics` returns the platform side (provider
and inference cost per conversation) so you can reconcile the spike against
what those conversations actually cost the whole platform, not only the
model tier.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/cost-economics" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "window_days=7"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/cost-economics",
  );
  url.searchParams.set("window_days", "7");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.avg_cost_per_conversation_cents);
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "avg_cost_per_conversation_cents": 3.7,
    "window_days": 7,
    "conversation_count": 11148
  },
  "meta": { "request_id": "req_llm_03", "timestamp": "2026-09-09T12:00:02.000Z" }
}
```

### 2. Compare anomaly scopes and page history rollups

The anomaly surface answers "where did the spike come from?" —
`GET /api/v1/insights/anomaly-insights/by-scope` ranks the affected scopes
(feature, model, agent, channel) so you slice against the right dimension
before paging the ledger.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/anomaly-insights/by-scope" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "window_days=30"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/anomaly-insights/by-scope",
  );
  url.searchParams.set("window_days", "30");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.scopes.map((s) => `${s.scope}: ${s.top_value}`));
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "scopes": [
      { "scope": "feature", "top_value": "support_agent", "open_count": 3 },
      { "scope": "model", "top_value": "gpt-5-thinking", "open_count": 3 }
    ],
    "window_days": 30
  },
  "meta": { "request_id": "req_an_01", "timestamp": "2026-09-09T12:00:03.000Z" }
}
```

Page the anomaly ledger — `GET /api/v1/insights/anomaly-insights/history`
returns a cursor-paged list. Pass the previous page's `next` token back as
`cursor` until it comes back `null`.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/anomaly-insights/history" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "limit=10" \
    --data-urlencode "cursor=an_219"
  ```

  ```typescript Node.js theme={null}
  const all = [];
  let cursor: string | undefined;
  do {
    const url = new URL(
      "https://api.orbit.devotel.io/api/v1/insights/anomaly-insights/history",
    );
    url.searchParams.set("limit", "10");
    if (cursor) url.searchParams.set("cursor", cursor);
    const res = await fetch(url, {
      headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
    });
    const body = await res.json();
    all.push(...body.data.items);
    cursor = body.data.next ?? undefined;
  } while (cursor);
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "items": [
      {
        "id": "an_219",
        "scope": "model",
        "value": "gpt-5-thinking",
        "metric": "cents",
        "severity": "high",
        "start_ts": "2026-09-02T14:00:00.000Z",
        "status": "resolved"
      }
    ],
    "next": null
  },
  "meta": { "request_id": "req_an_02", "timestamp": "2026-09-09T12:00:04.000Z" }
}
```

### 3. Benchmark and QA sample queries

Score before/after comparisons on a benchmark — `GET /api/v1/insights/
agent-benchmarks` returns a ranked list of quality/funnel scores so you
compare two AI agents, two model versions, or your agent against a human
queue.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/agent-benchmarks" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "metric=resolution_rate"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/agent-benchmarks",
  );
  url.searchParams.set("metric", "resolution_rate");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.benchmarks.map((b) => `${b.name}: ${b.score}`));
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "benchmarks": [
      { "name": "support_v2", "score": 87.4, "baseline": 84.1 },
      { "name": "support_v1", "score": 84.1, "baseline": 84.1 }
    ],
    "metric": "resolution_rate"
  },
  "meta": { "request_id": "req_qa_01", "timestamp": "2026-09-09T12:00:05.000Z" }
}
```

For QA follow-ups, the `GET /api/v1/insights/agent-quality/by-language`
endpoint breaks the same score down per conversation language, and
`GET /api/v1/insights/language-quality` ranks phrasing/coverage issues —
slice `data.rows[]` to the sample conversations you want to re-check.

### 4. Attribution: funnel steps → journey paths → conversion goal

Attribution chains answer "which step dropped the funnel?" —
`GET /api/v1/insights/call-attribution` attributes conversion credit to
call and message touches, `GET /api/v1/insights/automation-opportunities`
ranks the funnel steps where automation covers the drop, and
`GET /api/v1/insights/agent-roi/timeseries` trends goal conversion over
the window.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/call-attribution" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "goal=demo_booked" \
    --data-urlencode "window_days=30"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/call-attribution",
  );
  url.searchParams.set("goal", "demo_booked");
  url.searchParams.set("window_days", "30");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.touches.map((t) => `${t.step}: ${t.credit_pct}%`));
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "goal": "demo_booked",
    "touches": [
      { "step": "sms_reminder", "credit_pct": 41.2 },
      { "step": "call_back", "credit_pct": 33.9 },
      { "step": "ai_agent_followup", "credit_pct": 24.9 }
    ],
    "window_days": 30
  },
  "meta": { "request_id": "req_at_01", "timestamp": "2026-09-09T12:00:06.000Z" }
}
```

Drill into the step that dropped with `GET /api/v1/insights/automation-
opportunities` — it returns candidate funnel steps ranked by the recoverable
volume per step.

```json 200 theme={null}
{
  "data": {
    "opportunities": [
      {
        "step": "call_back",
        "recoverable_pct": 18.5,
        "note": "frequent drop after hold"
      }
    ]
  },
  "meta": { "request_id": "req_at_02", "timestamp": "2026-09-09T12:00:07.000Z" }
}
```

Trend the goal with `GET /api/v1/insights/agent-roi/timeseries` —
`data.points[]` carries the per-bucket conversion so you can chart the
recovery against the anomaly window you paged in chain 2.

### 5. Containment trend + talk ratio

Containment answers "how many conversations resolve without a human?" —
`GET /api/v1/insights/containment` returns the current rate, then
`GET /api/v1/insights/containment/timeseries` trends the same metric over
the window so you see whether a prompt or KB change moved it.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/containment" \
    -H "X-API-Key: dv_live_sk_your_key_here"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/containment",
  );
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.containment_pct);
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": { "containment_pct": 71.4, "conversation_count": 11148 },
  "meta": { "request_id": "req_ct_01", "timestamp": "2026-09-09T12:00:08.000Z" }
}
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/containment/timeseries" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "window_days=30" \
    --data-urlencode "bucket=day"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/containment/timeseries",
  );
  url.searchParams.set("window_days", "30");
  url.searchParams.set("bucket", "day");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.points.map((p) => `${p.bucket_date}: ${p.containment_pct}`));
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "points": [
      { "bucket_date": "2026-08-11", "containment_pct": 68.9 },
      { "bucket_date": "2026-08-12", "containment_pct": 69.7 },
      { "bucket_date": "2026-08-13", "containment_pct": 71.4 }
    ],
    "bucket": "day"
  },
  "meta": { "request_id": "req_ct_02", "timestamp": "2026-09-09T12:00:09.000Z" }
}
```

### 6. Quality eval scores

Voice and conversation quality evals answer "is the agent answering well?"
— `GET /api/v1/insights/sales-conversation-intelligence` returns the latest
scored conversations and their eval dimensions (rapport, coverage, objection
handling). Pair with `GET /api/v1/insights/containment` from chain 5 to see
whether a low eval score also pushed the transfer rate up.

<CodeGroup>
  ```bash cURL theme={null}
  curl -G "https://api.orbit.devotel.io/api/v1/insights/sales-conversation-intelligence" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    --data-urlencode "limit=5"
  ```

  ```typescript Node.js theme={null}
  const url = new URL(
    "https://api.orbit.devotel.io/api/v1/insights/sales-conversation-intelligence",
  );
  url.searchParams.set("limit", "5");
  const res = await fetch(url, {
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data.rows.map((r) => `${r.conversation_id}: ${r.score}`));
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "rows": [
      {
        "conversation_id": "conv_8a2f",
        "score": 83.5,
        "rapport": 88.1,
        "coverage": 81.2,
        "objection_handling": 80.1
      }
    ],
    "limit": 5
  },
  "meta": { "request_id": "req_ev_01", "timestamp": "2026-09-09T12:00:10.000Z" }
}
```

### Pagination and envelope rules

* **Cursor pages.** Ledger-style list endpoints return
  `data.items` + `data.next`. Pass `cursor=<next>` to fetch the following
  page; `null` terminates the sequence. Page size defaults are stated on
  each operation; keep the same filters across pages.
* **Slice fields.** Filter parameters are the tenant surface: `window_days`,
  `metric`, `scope`, `goal`, `bucket`. Chain 2 shows the cursor loop; every
  other chain shows the filter-slice.
* **The `{ data, meta }` envelope.** Branch on `data`; log
  `meta.request_id` when a value looks wrong — support can replay it.

> The dashboard views and per-surface readings live in
> [Insight dashboards](/guides/insights-dashboards),
> [Real-time analytics](/guides/insights-analytics-realtime),
> [Insight costs](/guides/insights-costs), and the
> [LLM spend guide](/guides/insights-llm-spend). This overlay
> is envelope-accurate: request, response, and the drill-in call — nothing
> else.

For the dashboard-side walkthrough of the surfaces these endpoints feed,
see the [Insights guides](/guides/insights-dashboards). Compliance notes:
every filter and scope on this page is a tenant-owned control — nothing
here touches provider account scope or sends traffic.
