Cost-center chargeback
Internal chargeback starts with one habit: tag every send with the department that should carry its cost. Devotel Orbit turns those tags into a department-first statement — every cost center as a line item with its per-channel split and share of the period total, plus the totals for spend that is still untagged. This guide covers the full loop:- Tag sends with a
metadata.cost_centerlabel. - Read the rollup at
GET /api/v1/billing/chargeback-rollup. - Cross-check a single tag on
GET /api/v1/billing/usage-by-channel. - Export the period with the statement exporter.
1. Tag sends with a cost center
Set a free-form string on the requestmetadata object. The same field works
on every messaging send endpoint (/sms, /mms, /rcs, /whatsapp,
/email, …) and on outbound voice calls — any entry you put there is stored
on the message or call row.
dept_sales and
Dept_Sales are two different cost centers. A short, stable convention like
dept_<name> or <name>_<region> keeps the rollup readable.
Tagging works from today onward. Only outbound rows carry price, so inbound
traffic never enters the totals.
2. The chargeback rollup
GET /api/v1/billing/chargeback-rollup folds the tagged sends into a
department-first statement over a rolling window:
The response is department-first: a grand total, the split of allocated
(tagged) against unallocated (untagged) spend, and one line per cost center
with its per-channel breakdown and its share of the period:
*_minor, cents) and a
two-decimal string. Channel lines sum exactly to their cost-center total, and
the cost-center lines sum exactly to the grand total — the rollup uses
integer arithmetic, so there is no rounding drift between the field groups.
Reading the response:
allocatedis spend carrying a real tag;unallocatedis the untagged pool;allocated_pcttells you how much of the bill is ready to charge back. Watch that percentage rather than the raw totals.cost_centersis ordered by spend descending, with theuntaggedline always sorted last — real departments lead the report.- The sourcing is your own metered usage ledger (message and voice prices), so figures exclude subscription fees, credits, discounts, and tax. Treat the rollup as a proportional allocation of usage spend, not invoice math.
3. Slice one cost center with usage-by-channel
The companion axis on GET /api/v1/billing/usage-by-channel answers the
inverse question: break a single cost center (or the whole tag dimension)
down by channel, country, campaign, or sender.
group_by=cost_centerwith nocost_centerfilter returns one bucket per tag — with no upper bound on the bucket list (other axes return the top 100). Use it to enumerate tags.- Adding
cost_center=dept_salesnarrows the response to that tag, split by the axis you chose (e.g.group_by=channel&cost_center=dept_sales). The filter is only valid whengroup_byis one of the tag-bearing axes (country,campaign,sender,cost_center); ongroup_by=channelthe filter is rejected with a400.
4. Untagged spend and the untagged bucket
A send without a metadata.cost_center entry (or with an empty one) lands in
the untagged bucket on both surfaces. It is not dropped — it totals
separately and shows up as the unallocated totals in the rollup, so the
rollup always reconciles to the full bill.
Best practice is to require the tag at the send layer in your integration:
reject outbound sends that miss it, or stamp a fallback department server-side.
Drive allocated_pct toward 100 and treat what is left as the exception
queue. Before changing tags, remember the tag is a plain string: renaming a
value re-buckets history going forward, so settle the convention before
sends scale.
5. Access and rate limits
Both endpoints are read-only and gated to the billing role: owner, admin, or billing session tokens (and API keys carrying thebilling:read scope where
Billing is scope-able). They run under the standard billing read limit, and
responses are cached for 60 seconds, so a dashboard or polling script is not
running the aggregation on every load.
6. Where this fits with Billing overview and the statements feed
The passing mention of cost centers on the Billing overview page lands behind this guide: thecost_center axis and the rollup are the
attribution surfaces; overview then frames them against usage, the ledger,
and spend alerts.
For the month-end packet, the statement exporter serves the same period as
CSV or JSON:
GET /api/v1/billing/statements— list monthly summaries.GET /api/v1/billing/statements/:period— a month’s detail rows.GET /api/v1/billing/statements/:period/download— CSV or JSON export.
allocated_pct, export when the period closes.