Skip to main content
Back to blog

Cost centers, GA — allocate communications spend, export it, close the loop

Devotel Orbit's Billing dashboard now carries cost-center chargeback ledgers, straight-line revenue-recognition schedules, CDR reconciliation feeds, and finance-grade spend guards. This walkthrough shows the full allocation loop — from tagging sends with metadata.cost_center to the month-end close.

Orbit Editorial Team

Finance asks three questions about a communications platform: which department or client carries this spend, how much of the prepaid contract has actually been earned, and does the invoice match the traffic. Orbit's billing surface now answers all three without a spreadsheet in between: cost-center chargeback ledgers, revenue-recognition-ready schedules, and CDR/usage-record reconciliation sit next to the wallet on the same dashboard, with tenant-owned spend guards on top. This walkthrough covers the loop end to end.

1. What a cost center is on Orbit

A cost center is a rollup key over the same per-message and per-call usage rows your wallet charges against. You set the grouping at send time — put a department, client, or project name under metadata.cost_center on the send request — and every priced row with that tag rolls up under that key. From then on the spend is attributable instead of pooled.

Orbit keeps that rollup clearly separated from the two other cost views it exposes, because they answer different questions:

  • Insights → Costs is the channel aggregate — "what did we spend on WhatsApp this month," grouped by channel and currency. It filters to priced rows only and is a planning surface.
  • Billing → Usage records is the raw ledger — one row per message or call, both directions, priced or unpriced. It is the invoicing surface; the invoice reads from here.
  • Billing → Cost centers is the chargeback projection — it folds the ledger rows by metadata.cost_center and reports anything untagged as unallocated so the gap is visible, not silently pooled.

The dashboard page at Billing → Cost centers renders that projection: total attributed spend, per-cost-center allocation with a per-channel breakdown, and an explicit reconciliation bucket for untagged traffic. Multi-channel spend — SMS, WhatsApp, voice — rolls into one ledger view; for tenants running agent workloads, AI-surface spend attribution works the same way, with a per-lane or per-agent view of token and usage cost. With it in place, "which department carries this" is a lookup, not an archaeology project.

2. Revenue-recognition-ready exports

For finance teams running under ASC 606, money received up front for a committed-use contract or a subscription invoice line is deferred revenue until it is earned across the service window. Orbit computes straight-line recognition schedules on demand from your contract data — no upload, no schedule construction, no mapping table. Two endpoints cover the surface:

  • Per-contract schedule (GET /api/v1/billing/revenue-recognition/schedule) — month-by-month recognized amounts per contract.
  • Summary (GET /api/v1/billing/revenue-recognition/summary) — recognized-to-date versus deferred-remaining as of a reporting date, plus recognized per period, summed across contracts.

The split reconciles by construction: recognized plus deferred always equals total contract value, so the summary ties straight into a deferred-revenue roll-forward. Amounts are computed in integer cents, and a cumulative rounding method keeps per-period entries summing to the contract total exactly. Pass an explicit as_of date and re-running the report reproduces the same figures — the month-end close property you want in an export. The same data renders read-only under Billing → Revenue recognition, gated to owner, admin, and billing roles.

3. Reconciling against the invoice

Reconciliation runs on two API-level feeds, so your finance stack — not a shared spreadsheet — checks invoices:

  • Usage counters (GET /api/v1/messages/usage/records) — per-category counts and summed prices over a rolling window: SMS and MMS inbound/outbound, voice inbound/outbound, with an optional per-country breakdown. SMS counts by segment, so the counter matches what the invoice charges; inbound traffic is included deliberately.
  • Call detail records (GET /api/v1/voice/calls/export) — a streamed CSV or JSON of per-call records: timestamps, duration, the rated price and currency, and a pre-signed recording URL when one exists. Export month-by-month when the window is wide.

If your finance stack lives in a warehouse, the reverse-ETL mechanism mirrors usage records and call detail records to BigQuery on a schedule — the same records, landed in tables you own.

4. Caps and anomaly alerts as finance guards

Raw allocation answers "who owes it"; Orbit also ships the controls that stop a runaway bill before the invoice lands, in two layers:

  • Spend-cap alert rules (Billing → Alerts) — thresholds on percent of monthly budget, month-to-date amount, daily spend, or balance floor. A tripped threshold emails or texts your recipients, and when you choose an enforcement action it pauses or blocks outbound traffic automatically — a tenant-owned, org-owned guard with no support ticket required.
  • Usage-anomaly alert rules — hard thresholds or a learned baseline over roughly four weeks of your own history, watching SMS delivery rate, outbound volume, and account-wide spend. Pick anomaly when you have not named a hard number yet.

Together they are the finance side of trip-security: bill shock surfaces as an alert, not as an invoice line.

5. Rate-card lineage per ledger

Resellers and managed-service operators need a third property: knowing which price book priced a lane. Billing → Pricing → Rate cards is a named price-book library on the parent organization — draft it once, assign it to subaccounts, and the same margins apply across deployments and re-provisioning. When a subaccount is tagged to a cost center, its allocation view resolves on the assigned card, so the chargeback line shows both the wholesale cost and the marked-up price against it — rate lineage is visible on the ledger, not inferred.

6. Tenant-owned controls

Everything on this loop is configured and owned by your org, not by platform policy:

  • You decide the rollup key (metadata.cost_center on your sends).
  • You choose the recognition windows as they sit on your contracts; the schedule reflects live contract data, recomputed on demand.
  • You configure alert rules, thresholds, recipients, actions, and cooldowns.
  • You assign and version rate cards on your parent org.

Roles gate the surface end to end — owner, admin, and billing can view cost-center and revenue-recognition data; writes for rules and caps follow the same role map. Per the compliance posture, these are tenant-owned controls in the strictest sense: your workspace sets the policy; the platform enforces it.

Roll your own ledger vs Orbit

Rolling your own allocation pipeline means wiring every send path to a home-grown ledger, maintaining a reconciliation job per channel, keeping a recognition engine in sync with contract changes, and building the guard rules yourself — then answering to finance every month when the numbers disagree. Orbit moves that loop to first-party surfaces: the rollup key on send, the recognition schedule on demand, the reconciliation feed over API, guards as tenant-owned rules, and rate lineage on every chargeback line. The honest limit: Orbit solves attribution and reporting, not full accounting — the invoice still comes from the platform's own billing ledger. That is the trade to make: one CSV or API contract to finance, replaced by none at all.

Frequently asked questions

What is a cost center in Orbit?

A rollup key you set at send time. Put a department, client, or project under metadata.cost_center on the send request, and priced usage rows roll up to that bucket. The Billing → Cost centers page renders the attribution with a per-channel breakdown and flags untagged traffic as unallocated.

How do I export a revenue-recognition schedule?

Call GET /api/v1/billing/revenue-recognition/schedule or /summary. Pass an explicit as_of date — for example as_of=2026-08-31 for the August close — and the figures reproduce exactly on re-run. Both endpoints are gated to the owner, admin, or billing role.

How do I reconcile my invoice against actual traffic?

Use GET /api/v1/messages/usage/records for per-category tabulation (SMS per segment, inbound included) and GET /api/v1/voice/calls/export for per-call CSV or JSON. The same feeds can be mirrored to a warehouse on the reverse-ETL schedule.

Is spend capped automatically, or only alerted?

Whichever you configure. Spend-cap alert rules default to notify-only, but you can attach an enforcement action that pauses or blocks outbound traffic the moment the threshold trips — tenant-owned, no support ticket.

Who can see cost-center and revenue-recognition data?

Both surfaces are gated to the owner, admin, and billing roles, matching the billing API.

Resources

Published 21 September 2026.

Cost centers, GA — allocate communications spend, export it, close the loop — Orbit by Devotel