The usage metering pipeline
Every billable thing in Devotel Orbit — a message, a completed call, an AI request — flows through the same pipeline: resolve the sender, resolve the destination cost, write one usage record, debit the wallet once, and roll the row into the aggregates your invoices and dashboards read. Read this page when you need the whole loop in a single model — the detail pages (sender and routing, pricing and rate resolution, the usage-records feed, the channel cost rollup, and the wallet ledger) each zoom in on one stage of what is laid out end to end here.1. The chain: sender resolution → destination cost → per-message quote
A send becomes a billable event at the moment the platform can state who you are sending as and what the destination costs.- Sender resolution. The send path picks the sender identity it will bill on — which owned number, sender-ID, or channel identity carries the message. The resolution order is fixed, documented on sender resolution and sender and routing.
- Destination cost resolution. For SMS the per-operator lookup (MCC/MNC) runs first — override verbatim, operator cost × your markup, then the platform-default markup — before falling through to the generic per-country rate ladder. Voice resolves a per-minute rate the same way. The full precedence is on pricing and rate resolution.
- Per-message cost quote. One shared resolution step returns the full price breakdown: the per-unit price, the quantity multiplier (SMS segments, call minutes, AI tokens), the total, and the attribution label naming the rule that produced the price. This quote is stamped on the usage record before the wallet moves. The wallet pre-flight then checks the balance against the quote, and only then does the send proceed.
2. The usage-record write: one row per billed thing, append-only
The rated send writes exactly one usage record — the row-level ledger fact you reconcile against. One record per message, one per completed call (see the usage-records feed for the full field set):- The record carries the billed units (SMS segments per message, one unit otherwise) and the price the resolution quote computed, in the wallet currency.
- A record that failed to rate stays on the feed with an empty
pricerather than disappearing, so the feed always counts the same rows the aggregate counters count. - The feed is append-only in effect: a reversal or correction is a new row, never an in-place edit — the same property the wallet ledger relies on.
3. Aggregation lifetime: raw records → rollups → invoice lines
The usage record is the only source of truth. Every higher-order number is an aggregate over it:- Row feeds.
GET /api/v1/usage-recordsand its CSV export are the raw window — one page or file of records, ungrouped. - Counter rollups. The aggregate counter surface
(
GET /api/v1/messages/usage/records) rolls the same rows up per channel and direction — sms-inbound, sms-outbound, voice, and so on — over a configurable window, optionally split per country. - Channel cost rollups.
GET /api/v1/analytics/costsgroups priced rows by channel and currency over a day/week/month granularity — the Insights → Costs dashboard reads this projection. - Invoice lines. An invoice is assembled by summing the filtered rows for the billing period — the invoice is built from the ledger, never from a standing counter.
GET /api/v1/usage-records,
sum units × price, and you rebuild any rollup the period contains. The
rollup vs ledger reconciliation model
documents why the projections can legitimately disagree (filters, not
missing data) and how to join them back to the raw rows.
4. Metering vs billing: recording is unconditional, charging depends on the plan
Metering and billing are decoupled by design:- Metering is the recording of the event. The usage record is written whenever the billable thing happens — before any plan evaluation and independently of what your subscription includes.
- Billing is the decision to charge. Whether the record debits the wallet depends on what the rating pipeline resolved: included quantity, graduated tiers, free-tier, or a zero-price rule.
price > 0 reports only the charged subset.
5. Backfill and replay: re-aggregation must be idempotent
Two replay guarantees define the pipeline:- Ledger replay collapses. A retried charge carrying the same idempotency key resolves to the same ledger row — the debit lands exactly once, and the replayed response is flagged so side effects (webhooks, notifications) do not refire.
- Re-aggregation re-derives. Any rollup is additive over the raw records, so backfilling or recomputing a window is a re-read of those records, not a re-charge. Rebuilding the channel rollup for last month cannot move money twice; it recomputes sums from the same append-only rows.
6. Currency and units: cents, smallest unit, no float
All money arithmetic is integer, always:- The wallet stores whole cents; the charge ledger tracks sub-cent precision in integer micro-cents (1 USD = 100,000,000 micro-cents), so a million sub-cent debits sum exactly.
- Every usage record and rollup row carries an ISO-4217
currency, and multi-currency sums stay split per currency. Never merge currencies; the dashboard merges only for display and the API remains the source of truth. - Field-scale representations like
balance_usdare display-only floats. Do any comparison or projection inbalance_centsorbalance_micro_cents— a float projection will disagree with the ledger on small amounts.
7. Where to go next
- Usage records: the per-record billing feed — the row-level feed, its filters, pagination, and reconciliation loop.
- How billing meters your usage — the wallet, rating pipeline, FX on converted top-ups, and tax.
- Wallets, credits, and charges — the append-only ledger, units, pause gates, and idempotency.
- Channel cost rollup vs the billing ledger — why the aggregate surfaces and the ledger legitimately disagree, and how to reconcile them.
- Pricing and rate resolution — the per-operator precedence behind the resolved price stamped on each record.
- Usage Metering API reference — the reseller-facing rating surface (stateless preview; does not touch the wallet).
- CDR export & billing reconciliation API — the endpoint contract for the usage-records feed and export.