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

# Read the Channel costs page

> Operator guide to the /insights/costs dashboard: the total-spend, billed-messages, and average cost-per-message KPI tiles, the daily spend trend, the per-channel breakdown table, and driving the same numbers over GET /api/v1/analytics/costs.

# Read the Channel costs page

The **Channel costs** page
([/insights/costs](https://orbit.devotel.io/en/insights/costs)) is the
cross-channel spend rollup: one date window applied to every outbound
channel at once, so you can compare what SMS, WhatsApp, email, voice,
and the rest each cost you — in total, per message, and per day — on
one screen.

Access restricts to the **owner, admin, developer, and billing** roles;
the page does not appear in the sidebar for other roles.

## 1. What the page answers

Three unit-economics questions, answered across all channels in the
selected window (24 hours, 7, 30, or 90 days, 12 months, or a custom
range from the date filter at the top of the page):

* **Spend** — how much you were charged per channel.
* **Volume** — how many messages were actually billed per channel.
  Failed sends, free-tier traffic, and any row priced at zero are
  excluded, so volumes stay honest.
* **Average cost per message** — the blended unit cost, spend ÷ billed
  messages, computed at sub-cent precision.

## 2. Read the KPI tiles

Three headline tiles sit at the top of the page, each with a short
definition under the number:

| Tile                 | Meaning                                                                                                                          |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **Total spend**      | Sum of all charges billed from your credit balance in the selected period, across every channel.                                 |
| **Billed messages**  | Messages that incurred a charge in the period. Zero-priced rows (failures, free-tier sends) do not count.                        |
| **Avg cost/message** | Total spend ÷ billed messages across all channels. When the window has no billed messages the tile shows `—` rather than a zero. |

All money renders in your account's billing currency.

## 3. Spend over time

Below the tiles, the **Spend over time** chart plots daily total spend
across the whole window. Day buckets resolve in your organization's
timezone, so "today" on the axis means your local day. The chart
aggregates all channels into one series; the per-channel split lives in
the breakdown below it.

Use the chart to spot step changes — a campaign launch, a pricing
revision, or a channel switch — then confirm which channel moved in the
table below.

## 4. Drill into the per-channel table

The **Cost by channel** panel pairs a donut chart with a table. The
donut shows each channel's share of spend; the table gives the exact
numbers per channel — spend, billed messages, and average cost per
message — sorted by spend descending with a totals footer.

The footer sums *every* channel, so it always equals the **Total spend**
tile above. An expensive unit stands out here directly: if WhatsApp's
cost per message runs several times SMS's, that is the row to act on.

A **Billable usage records** panel sits below the breakdown: carrier-style
counters for SMS, MMS, and voice with an optional per-country split.
Voice appears in minutes; SMS counts segments. That panel is deliberately
carrier-scoped (it mirrors what a carrier bill would show, and it includes
inbound traffic), so it will not equal Total spend — a numeric
reconciliation line inside the panel shows the spend on non-carrier
channels such as email and chat. The [cost-intelligence
guide](/guides/cost-intelligence) walks that panel end to end.

## 5. Drive the same numbers over the API

Everything on the page comes from `GET /api/v1/analytics/costs`, so you
can export the rollup or build your own console on the same contract:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/analytics/costs?start_date=2026-08-01&end_date=2026-09-01&group_by=day" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

| Query parameter | Type                                 | Notes                                                                                                                  |
| --------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `start_date`    | date                                 | Inclusive window start. Defaults to the last 30 days when omitted.                                                     |
| `end_date`      | date                                 | Inclusive window end. A single-day range is accepted.                                                                  |
| `days`          | integer                              | Alternative rolling lookback (max 365); use instead of `start_date`/`end_date`.                                        |
| `channel`       | string                               | Optional single-channel filter (`sms`, `whatsapp`, `rcs`, `email`, `viber`, `voice`, `push`, `messenger`, `telegram`). |
| `group_by`      | `hour` \| `day` \| `week` \| `month` | Time-series bucket granularity. Defaults to `day`.                                                                     |

Sample response (truncated):

```json theme={null}
{
  "data": {
    "totals": {
      "total_messages": 41230,
      "total_spend": 1284.62,
      "avg_cost_per_message": 0.0312,
      "total_segments": 44981,
      "by_currency": [
        {
          "currency": "USD",
          "total_messages": 41230,
          "total_spend": 1284.62,
          "avg_cost_per_message": 0.0312,
          "total_segments": 44981
        }
      ]
    },
    "time_series": [
      {
        "period": "2026-08-01T00:00:00.000Z",
        "currency": "USD",
        "total_messages": 1480,
        "total_spend": 47.21,
        "avg_cost_per_message": 0.0319,
        "total_segments": 1612
      }
    ],
    "by_channel": [
      {
        "channel": "sms",
        "currency": "USD",
        "total_messages": 27840,
        "total_spend": 684.10,
        "avg_cost_per_message": 0.0246,
        "total_segments": 31591
      },
      {
        "channel": "whatsapp",
        "currency": "USD",
        "total_messages": 12900,
        "total_spend": 577.42,
        "avg_cost_per_message": 0.0448,
        "total_segments": 0
      }
    ],
    "group_by": "day"
  }
}
```

Map each KPI back to its field:

| Page element          | Response field                                              |
| --------------------- | ----------------------------------------------------------- |
| Total spend tile      | `totals.total_spend`                                        |
| Billed messages tile  | `totals.total_messages`                                     |
| Avg cost/message tile | `totals.avg_cost_per_message`                               |
| Spend over time chart | one point per `time_series[]` row (`period`, `total_spend`) |
| Donut / table rows    | `by_channel[]` — one row per channel                        |
| Table totals footer   | `Σ by_channel[].total_spend` — equals the Total spend tile  |

`totals.by_currency[]` splits the same totals per billing currency;
multi-currency tenants get one row per currency there, in the
time-series, and in the channel breakdown, rather than a polluted
mixed-currency sum. The [Analytics API
reference](/api-reference/analytics) documents the full payload.

## 6. How this page differs from billing and spend caps

Cost pages overlap, so pick the right one for the question:

* **Channel costs (this page)** — the cross-channel rollup: unit
  economics per channel over a window. It answers "what did a message
  on each channel cost us?"
* **Billing → usage and invoices** — the ledger: individual deductions
  from your wallet and the invoice/statement line items they settle
  into. It answers "what exactly was this charge?" The two reconcile —
  the rollup here is an aggregation of the same recorded charges the
  ledger lists one by one.
* **Spend caps** — controls, not reports: monthly/daily ceilings and
  alert rules over the ledger that notify or pause outbound traffic.
  See the [spend-cap console guide](/guides/spend-cap-console). Channel
  costs is where you read the spend those rules rate against.
* **LLM spend** — the AI token leg, per agent/model/conversation.
  Channel costs covers the message and telephony leg; read the two
  together for the full cost of an AI-handled conversation. See
  [LLM spend](/guides/insights-llm-spend).

## 7. Averages when a channel has zero messages

Average-cost-per-message divides by billed message count, so a channel
with no billed messages in the window can't have an average — the table
and the API return `0` there, and the page renders `—` rather than a
misleading `$0.00`. Expect this on a channel you have connected but not
sent on yet, or when you filter to a channel with only inbound or
free-tier traffic. Comparative averages (SMS versus WhatsApp versus
email) are only meaningful when both channels billed messages in the
window.

## Troubleshooting

| Symptom                                              | Fix                                                                                                                                                             |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "No spend in this window"                            | Widen the date range. Only priced outbound rows in the window count.                                                                                            |
| A channel is missing from the table                  | It had no billed messages in the window. Connected-but-idle channels do not show.                                                                               |
| Avg cost/message shows `—`                           | No billed messages in the window; the average is legitimately undefined (see section 7).                                                                        |
| The page says "Couldn't load cost data"              | Use Retry — the page polls the rollup continuously and recovers on the next refresh.                                                                            |
| Numbers differ from the Billable usage records panel | Expected — that panel counts SMS segments and includes inbound traffic; it is carrier-scoped, the headline is not. Reconcile with the panel's non-carrier line. |

## See also

* [Read the cost-intelligence dashboards](/guides/cost-intelligence) — the wider unit-economics surfaces and the dashboard-versus-API reconciliation loop.
* [Analytics API reference](/api-reference/analytics) — full request/response shapes for `/analytics/costs`.
* [Read the LLM spend dashboard](/guides/insights-llm-spend) — the AI token leg.
* [Read the Insights dashboards](/guides/insights-dashboards) — the non-cost Insights surfaces.
* [Spend-cap console](/guides/spend-cap-console) — ceilings and alert rules over the same ledger.
