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.
Precedence when several are passed: rolling
window wins, then from+to, then calendar period.
Working with the response
- The
periodlabel echoes the month you asked for (or the month containingfrom/ the window’s end); therangeis the authoritative[from, to)interval the totals cover. A rolling-window response also carrieswindowback. - All money is integer cents in
currency— the endpoint reports in the same wallet currency every other billing surface uses, and the per-linecost_centsalways sums exactly tototal_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.
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.
5. Sample queries and dashboards
Three patterns cover most inbound-cost checks:- Monthly budget line. Pull
?period=YYYY-MMonce per closing month and posttotal_cost_centsagainst the outbound usage total. Received spend that used to be invisible now foots against your full carrier budget, month over month. - Rolling-window watch. Pull
?window=24hon a cron and alert whentotal_cost_centsjumps day-over-day beyond your envelope — an inbound abuse or routing loop surfaces as an inbound-cost spike before the carrier statement would. - Channel composition. Slice the response on
lines[].channeland graph the composition per channel over time. A support-mainly-inbound month will show avoice-heavy split; a reply-heavy campaign month shows it insms.
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: []andtotal_cost_cents: 0, not a 5xx. - Inbound-only scope by construction. Historical schemas without a
messages/call_logstable, 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 — outbound cost surfaces, anomaly views, and burn-rate reporting the inbound complement.
- Billing cost calculator — presale cost-walk lanes for MT traffic; inbound metering fills the received side.
- Usage anomaly alert rules — the tenant-configured rules that flag spend envelopes; inbound-cost totals are the inbound-side comparator.
- Rate cards — the rate-card library
pricing_sourceladder rows map to.