Volume-tier pricing auto-resolution
How billing meters your usage rates usage against a meter definition: anincludedQuantity you prepay, then
graduated overageTiers where each tier covers a bounded range and the
last tier is open-ended. Volume tiers are the same graduated idea applied
to Orbit’s own send-side rating — instead of one flat per-unit price for a
channel, the price steps down automatically as your month-to-date
usage crosses the thresholds a published ladder defines. This page
explains which ladder your send resolves against, where admins publish
and edit ladders, and why every tier edit is reconstructible after the
fact.
What volume tiers solve
A flat per-unit rate prices every send the same whether you moved a thousand messages this month or ten million. That is the right model at low volume, and the wrong one at high volume: the platform’s wholesale cost per message genuinely falls with committed traffic, and a customer who can forecast their volume should be able to bank that fall instead of renegotiating it quarterly. Included-quantity wallet rates (pricing and rate resolution) solve a different problem: they answer “which pricing rule supplied this number” for one send — operator cost plus your markup, or a verbatim per-operator override. Volume tiers answer “which number”: they sit inside that same resolution step and swap the per-unit price to the discounted rung once your cumulative monthly usage has earned it. The two compose — the per-send resolver first finds the applicable rate, then the volume-tier post-pass replaces it with the rung your current volume qualifies for, when a ladder exists for that channel.Tier shapes
Each ladder is a set of rows over one channel —sms, whatsapp, or
voice_minutes (voice accumulates in minutes, because that is how it is
billed). Each row carries three fields that define one rung:
min_volume— the month-to-date usage at which the rung opens (inclusive).max_volume— the usage at which the next rung takes over;nullmeans the rung is open-ended and holds for all higher volumes.price_cents_per_unit— the per-unit price the rung bills at.
country_code narrows a rung to one destination; null
means the rung applies to every destination for its channel. Prices are
integer cents — the ladder can never price a send at a negative or
fractional-cent rate.
Rows come in two scopes, and the scope decides whose ladder wins:
- Platform defaults — rows with
organization_id IS NULL. Devotel publishes these; every tenant resolves against them until something more specific exists. - Organization overrides — rows scoped to one
organization_id. They are private to that tenant and outrank the defaults outright.
Precedence: which row your send resolves to
At debit time the resolver considers only rows for the send’s channel whose range contains the current month-to-date volume (min_volume ≤ volume, and volume < max_volume when a max exists), then
walks four bands from most to least specific — the first band with any
matching row wins:
- Your organization, country-specific row.
- Your organization, country-wildcard row (
country_code IS NULL). - Platform default, country-specific row.
- Platform default, country-wildcard row.
min_volume your volume has crossed, which is the largest
discount the ladder has actually unlocked. If no row in any band matches,
the helper returns nothing and the send bills at the preexisting flat
price — volume tiers are purely additive and can never invent a charge
where none existed before.
One honesty note on the counters: month-to-date volume is cached with a
roughly one-minute staleness window, so a send right at a threshold can
bill at the previous rung for up to a minute. Tiers change at thousands
of messages, so the window cannot flip a tier in practice.
Endpoint surface
Administering ladders is owner/admin work on four endpoints:GET /api/v1/billing/volume-tiers— list and filter, by channel, by organization, or across scopes.POST /api/v1/billing/volume-tiers— create a rung.PATCH /api/v1/billing/volume-tiers/:id— update the mutable fields of a rung (thresholds, price, country).DELETE /api/v1/billing/volume-tiers/:id— remove a rung.
owner or admin role, and all four scope the
caller to their own organization: a tenant operator can only create,
list, update, or delete rows whose organization_id is their own. Only
a super-admin may write rows with organization_id IS NULL — publishing
or editing the shared platform ladder is deliberately a platform-side
act, and a mismatched scope answers 404 rather than confirming the row
exists. Full field schemas live in the
Billing API reference.
Tenant operators manage the same ladder visually under
Billing → Volume tiers in the dashboard, which reads and writes
through these endpoints.
How rating consults tiers at debit time
The send path asks the volume-tier helper after the per-send price resolution described in pricing and rate resolution has produced its flat answer. The helper loads the channel’s ladder (cached for minutes, invalidated cluster-wide the moment any admin writes a tier), counts the tenant’s month-to-date usage from the tenant schema — message rows for SMS/WhatsApp, per-minute-rounded call durations for voice — and runs the four-band precedence above. On a match, the wallet is debited at the rung’sprice_cents_per_unit; on no match, the flat
price stands unchanged. The ladder never widens a charge: if a rung
resolved, its price replaced the flat one; if none resolved, nothing
about the debit changes.
Preview before you land an edit
GET /api/v1/billing/volume-tier-preview is the money-free counterpart.
Pass a channel, a hypothetical projected_volume, and optionally a
country_code, and it returns the ladder your tenant would bill against
at that volume: every rung with its thresholds, the rack rate (the
lowest rung’s price), the per-unit price the projected volume earns, the
discount versus rack, and the projected spend and savings. It reads only
your own rows plus the platform defaults, moves no money, and touches no
wallet state — use it to sanity-check a ladder before publishing, or to
answer “what would 5M messages a month cost?” without a spreadsheet.
Worked example: a three-rung SMS ladder
Take a platform-default SMS ladder:
Walk one tenant’s month through
billing and wallet’s rating pipeline:
- Message #1 of the month — month-to-date volume is 0, the only applicable rung is 0–1M, and the wallet is debited 0.9¢. This is the same number the flat rate card would have produced; rung 1 is the rack rate.
- Message #1,000,001 — the volume counter has crossed the first threshold, rung 2 is now the highest earned rung, and this and every later send this month debits 0.7¢. Messages already sent keep their original 0.9¢ ledger entries — the discount is progressive, not retroactive: each send bills at the rung earned at its own debit time.
- Message #10,000,001 — rung 3 opens; the rest of the month bills at 0.5¢.
- On the first of next month (UTC) the cycle resets, the volume counter returns to zero, and the tenant starts again at rung 1.
organization_id would shadow this default ladder at every step — same
walk, your rungs. And because the ledger carries the applied pricing
attribution, any individual debit can be traced back to the rung that
priced it.
Auditability
Every create, update, and delete on a tier row is audit-logged at the controller — the actor, the action (billing.volume_tier_created / _updated / _deleted), the affected
tier id, whether the row was a platform default, and the request
context. A pricing change is therefore never an anonymous edit: pair the
audit entries with the ledger’s per-debit attribution and you can
reconstruct who changed a rung, when it took effect (tier caches
invalidate on write), and which debits billed under it — the same
journal-traceability bar the pricing override changelog holds
(rate resolution) applies here to
the ladder itself.
See also
- Pricing and rate resolution — the precedence that picks the flat per-send price a volume-tier rung then discounts.
- How billing meters your usage — the wallet, included quantity, and graduated-tier metering the rating pipeline debits into.
- Volume tiers and revenue recognition guide — the finance-ops workflow over the same dashboard surface, including the what-if simulator.
- Spend caps — the ceiling that complements a volume ladder: tiers lower the price as you scale, caps bound the total regardless.
- Rate cards — the reseller-side price books that assign per-subaccount pricing, a different surface from the tenant-facing ladder on this page.
- Billing API reference — endpoint schemas for the tier CRUD and the preview.