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

# Inbound traffic cost metering: see what received calls and messages cost

> Read the GET /usage/inbound-cost endpoint end-to-end — calendar-month and rolling windows, the per-channel composition of received SMS/MMS and inbound voice, how MO traffic is rated, sample queries and dashboard rollups, and the measurement caveats to apply before you treat the total as an invoice.

# Inbound traffic cost metering

`GET /api/v1/usage/inbound-cost` reports what your **received** traffic — inbound SMS, MMS, and voice — costs over a period or rolling window. It closes a blind spot in spend tracking: every outbound (MT) send is rated and shows up on the usage and billing surfaces, while the received (MO) volume carriers bill on your numbers was never metered. If you run contact inquiry lines, callback numbers, or two-way support, a share of your real carrier spend only ever appeared in one direction. This endpoint prices that share so "total spend" actually means total.

## 1. Why inbound differs

Inbound traffic arrives unsolicited: a customer texts your support DID, a prospect calls the number in the ad, a subscriber replies STOP to a campaign. Two consequences follow:

* **Volume is customer-driven, not campaign-driven.** You can't forecast inbound the way you forecast a send — it follows contact inquiries, inbound callbacks, helpdesk conversations, and message replies your own traffic generates.
* **The billing surface has historically been outbound-centric.** The usage, billing, and spend-anomaly surfaces all report MT spend through the pricing and wallet surface. Received SMS/MMS on your leased numbers and inbound voice minutes are billable events too, but nothing priced them — so "total spend" silently excluded received volume.

`/usage/inbound-cost` aggregates your persisted inbound volume and prices it with `direction: "mo"` (mobile-originated) through the same rating every other usage surface uses. It is **reporting-only**: it never touches a wallet, deducts credits, or calls a provider — it reads recorded traffic and resolves rates so received spend is visible and budgetable.

## 2. Read the totals

### Window forms

The endpoint accepts three ways of choosing the window; the `"mo"` rating and response shape are identical across all of them.

| Form           | Query                                                | Window resolved                                                                 |
| -------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------- |
| Calendar month | `?period=2026-06`                                    | UTC month `[first day, first day of next month)` — default is the current month |
| Rolling window | `?window=24h` / `?window=7d` / `?window=30d`         | Trailing window ending now                                                      |
| Explicit range | `?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z` | `[from, to)` — both are required together                                       |

Precedence when several are passed: rolling `window` wins, then `from`+`to`, then calendar `period`.

### Working with the response

```bash theme={null}
curl -s https://api.orbit.devotel.io/api/v1/usage/inbound-cost?period=2026-06 \
  -H "Authorization: Bearer <API key or session token>"
```

```json theme={null}
{
  "data": {
    "period": "2026-06",
    "range": { "from": "2026-06-01T00:00:00.000Z", "to": "2026-07-01T00:00:00.000Z" },
    "currency": "USD",
    "total_cost_cents": 1513,
    "lines": [
      { "channel": "sms",   "unit": "per_message", "quantity": 1205, "unit_price_cents": 0.8, "cost_cents": 964, "pricing_source": "default_markup" },
      { "channel": "voice", "unit": "per_minute",  "quantity": 310,  "unit_price_cents": 1.6, "cost_cents": 496, "pricing_source": "fallback" },
      { "channel": "mms",   "unit": "per_message", "quantity": 70,   "unit_price_cents": 0.75, "cost_cents": 53, "pricing_source": "fallback" }
    ]
  }
}
```

Two interpretation rules apply to every response:

* The `period` label echoes the month you asked for (or the month containing `from` / the window's end); the `range` is the authoritative `[from, to)` interval the totals cover. A rolling-window response also carries `window` back.
* All money is integer cents in `currency` — the endpoint reports in the same wallet currency every other billing surface uses, and the per-line `cost_cents` always sums exactly to `total_cost_cents`.

## 3. What makes up each channel line

Each line is one channel's rated received traffic for the window. What's included per channel — and what isn't.

| Line          | What's counted                                                                                                                      | What's not                                                                                                                                                                                       |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sms` / `mms` | Received messages persisted on those channels — SMS/MMS replied to by a contact or delivered on an owned number, priced per message | Outbound sends (covered by the MT surfaces)                                                                                                                                                      |
| `voice`       | Inbound voice minutes, carrier-rounded up to the minute per call, priced per minute                                                 | Outbound minutes; free and BYO inbound channels — WhatsApp, email, RCS — which carry no per-event carrier termination cost and are intentionally excluded so the report doesn't over-state spend |

Each line also reports `unit` (headline billing basis: `per_message` or `per_minute`), `unit_price_cents` (the resolved rate), and `pricing_source` — attribution for where the rate came from, the same ladder the wallet charges through (`org_markup`, `default_markup`, `mccmnc_floor`, `fallback`, …). A `fallback` source means no configured inbound rate row existed and the per-channel fallback rate was used — never a fabricated or silent rate.

## 4. What decides the price

Two inputs move a number: the inbound rating and the origin network.

* **MO rating.** Each bucket is rated as `direction: "mo"` against the global country code `*` — the global inbound rate configured for the channel, falling back to the per-channel fallback when no inbound rate row has been uploaded. Org-level overrides, below-cost floors, and currency conversion apply exactly as they do to outbound pricing, so a configured MO rate and an MT rate never diverge from different pricing rules.
* **Origin network.** The counts read operator-billable voice duration (per-call minutes rounded up, matching how carriers bill inbound duration) and per-message MO volume. The endpoint prices the volume that was received; it does not project what a missed or abandoned call would have cost.

Match this against the tally use cases — customer contact lines, support callback numbers, subscriber replies to campaigns — where the received leg of the conversation is exactly what this endpoint is built to price.

## 5. Sample queries and dashboards

Three patterns cover most inbound-cost checks:

1. **Monthly budget line.** Pull `?period=YYYY-MM` once per closing month and post `total_cost_cents` against the outbound usage total. Received spend that used to be invisible now foots against your full carrier budget, month over month.
2. **Rolling-window watch.** Pull `?window=24h` on a cron and alert when `total_cost_cents` jumps day-over-day beyond your envelope — an inbound abuse or routing loop surfaces as an inbound-cost spike before the carrier statement would.
3. **Channel composition.** Slice the response on `lines[].channel` and graph the composition per channel over time. A support-mainly-inbound month will show a `voice`-heavy split; a reply-heavy campaign month shows it in `sms`.

The same endpoint backs dashboards and alerts — because the lines carry a stable schema (`channel`, `unit`, `quantity`, `unit_price_cents`, `cost_cents`, `pricing_source`), date-, channel-, and rating-source breakdowns can be built on the response alone.

## 6. Refund and measurement caveats

Read these before you treat the report as an invoice:

* **Not a refund surface.** The report tells you what received traffic *cost* as rated — it doesn't fetch provider credits, dispute a rate, or reconcile against a carrier invoice. If a carrier over-bills an inbound leg, that's a carrier dispute; this report shows what your rated view says it should have cost.
* **Partial coverage returns what succeeded, not an error.** Each channel aggregate is independent: if a scan is unavailable (e.g., a schema predating a table), that bucket is skipped — the response returns the channels that resolved and a zero-omitted set. A window with no received traffic returns `lines: []` and `total_cost_cents: 0`, not a 5xx.
* **Inbound-only scope by construction.** Historical schemas without a `messages` / `call_logs` table, and received MMS/voice on channels outside those persisted surfaces, simply contribute nothing — the report never estimates unrecorded traffic into the total.
* **Statement timeout as a guard, not a retry.** Each aggregate runs with a bounded statement timeout; a pathological full-window scan returns an explicit error rather than riding into a silent edge failure. Treat a bounded-timeout error as "the window is too hot to read right now," narrow the window, and retry — it is a read constraint, not lost data.

## Related

* [Cost intelligence](/guides/cost-intelligence) — outbound cost surfaces, anomaly views, and burn-rate reporting the inbound complement.
* [Billing cost calculator](/guides/billing-cost-calculator) — presale cost-walk lanes for MT traffic; inbound metering fills the received side.
* [Usage anomaly alert rules](/guides/usage-anomaly-alert-rules) — the tenant-configured rules that flag spend envelopes; inbound-cost totals are the inbound-side comparator.
* [Rate cards](/billing/rate-cards) — the rate-card library `pricing_source` ladder rows map to.
