Billing overview
Orbit runs on a prepaid wallet. Every organization holds a single USD wallet that funds messaging, voice, video, and AI usage. Charges are deducted from the wallet in real time as usage happens, and every deduction is recorded in an append-only ledger you can read, download, and reconcile. This page maps the whole billing surface — wallet, top-ups, plans, invoices, usage, alerts, contracts, and refunds — and links each concept to its API endpoints and deeper guides.- The dashboard exposes the same surface under Billing (alerts, invoices, statements, usage, cost-centers, pay-by-link, pricing, calculator, and the what-if simulator).
- The full request/response reference for every endpoint named here is in the Billing API reference.
<CodeGroup> with three tabs — cURL,
Node.js (TypeScript), and Python. The Node tab prefers the typed
@devotel-orbit/node helper where the SDK ships one (getBalance, topUp);
where the SDK has no typed billing helper yet (pay-by-link, plans,
transactions, crypto top-up) it falls back to plain fetch. The Python tab
uses plain requests per the
sample-writing guide, so it runs without
installing the SDK. All read the key from ORBIT_API_KEY and every response
carries the same { data, meta } envelope (meta.request_id,
meta.timestamp).
1. Wallet & prepaid model
Your wallet holds prepaid funds. Usage — per message, per voice minute, per AI token — debits the wallet as it happens; top-ups, refunds, and grants credit it. Read the live balance plus the account’s pause state here — call it before every send batch to gate on funds, and on your billing dashboard to render the same number the Orbit dashboard shows:GET /api/v1/billing/balance
200
HTTP 402 with code: "SENDING_PAUSED" — branch
on the code, not the status, and top up before you retry. A
429 RATE_LIMITED on this read carries error.retry_after seconds; back off
that long before polling again.
See the
full balance reference
for field semantics.
The balance is returned in dollars, whole cents, and exact integer
micro-cents (balance_micro_cents = cents × 1,000,000), along with the ISO
4217 currency the ledger is denominated in. Use balance_micro_cents when
subtracting sub-cent rates (per-email, per-token) from the balance in integer
math.
Pause-state flags explain whether outbound sending is available:
outbound_paused—truewhen sending is paused (balance exhausted, a billing alert’s pause action, or repeated payment-method failures). Outbound sends returnSENDING_PAUSED(HTTP 402) while paused.outbound_block_reason— why the pause is in effect, when set.payment_failure_count— consecutive Stripe payment failures (0–3) driving dunning; at 3 the account is frozen until the card is updated.
degraded: true appears in the response, the value is a last-known
fallback during a short availability blip — the dashboard shows a “Balance
recently degraded” notice rather than a phantom zero.
2. Top-up flows
Hosted card checkout.POST /api/v1/billing/balance/top-up mints a
Stripe Checkout session and returns the hosted URL; the wallet is credited
when the payment settles (topped up immediately on return via the confirm
endpoint, even if the webhook is delayed). Requires the owner, admin, or
billing role. Use this whenever a payer funds the wallet with a card — the
Idempotency-Key header is required, and re-using it returns the original
Checkout URL instead of a duplicate session.
200
Idempotency-Key was re-used with a different (amount, currency) — the
replay was rejected, not duplicated. Treat 409 as “you already have a Checkout
URL for this key”; re-fetch with the same key to get the original session
instead of minting a new one.
Crypto top-up. POST /api/v1/billing/balance/top-up-crypto mints a
hosted invoice for Bitcoin, USDT, ETH, and other coins, settling to the
wallet in USD. Use this when a payer wants to fund the wallet with crypto
instead of a card. See Cryptocurrency payments for
the full flow, status meanings, and cancellation semantics.
200
POST /api/v1/billing/balance/top-up-crypto/:intentId/cancel) returns HTTP 402 PAYMENT_REQUIRED
when the on-chain payment has not yet confirmed enough
to cancel cleanly, and HTTP 409 when a payment is already in flight
(code: "PAYMENT_IN_FLIGHT"). Treat 402 as “wait for confirmation before
cancelling”; treat 409 as a terminal state you should surface, not retry.
Collecting a customer payment. POST /api/v1/billing/pay-by-link mints
a hosted checkout link and renders a request-to-pay message for the best
reachable channel (SMS, RCS, WhatsApp, email, or voice IVR read-out). Orbit
returns the rendered message and URL — the send goes through your own channel
pipeline. Use this when you collect payments from your customers, not for
funding your own wallet.
200
amountMinor below the provider’s per-currency minimum (50 minor units for
USD/EUR) — read error.details.field and bump the amount, never retry the
same body.
All three are covered in the
API reference
— parameters, idempotency semantics, and the crypto-fee policy.
Currency conversion. Paying in a currency other than your wallet
currency converts at credit time, with the applied rate recorded on the
transaction. See Wallet top-up currency conversion.
Choose Cryptocurrency or Credit / debit card in the payment-method
selector on Dashboard → Billing to top up manually.
3. Auto-top-up
Auto-top-up charges your saved payment method off-session whenever the balance crosses a threshold, so outbound never stops for want of funds. Configure it from Dashboard → Billing → auto-replenish, or via the API. The surface is a three-call triad — read the config, write it, and (when needed) clear it:GET /api/v1/billing/auto-topup— read the current config.PUT /api/v1/billing/auto-topup— create or update the rule.DELETE /api/v1/billing/auto-topup— disable it and clear its state.
200
recharge_amount_minor did not exceed threshold_minor (or a cap/validation
rule failed) — read error.details.field and fix the amounts instead of
retrying the same body.
The
auto-top-up reference adds the
clear-cap variant and the validation rules.
Semantics when enabled is true:
threshold_minor— the balance level (minor units, e.g. cents) that triggers a top-up. Minimum $1.00.recharge_amount_minor— the amount charged when triggered. Must exceed the threshold so each top-up lifts the balance back above the trigger (otherwise you would get charged repeatedly).max_monthly_minor— optional monthly cap. Persisting it is explicit: omitting the field (or sendingnull) keeps any saved cap; removing a cap requires"clear_cap": true.max_topups_per_day— optional per-day cap (default 5) bounding runaway-loop exposure.
4. Plans & subscriptions
Orbit is a unified pay-as-you-go platform — plan tiers are retired by design, so the catalog intentionally lists one default plan rather than a tier matrix.GET /api/v1/billing/plans returns the default plan (payg), its included
capabilities (every channel on one wallet), and its starting limits (2 team
seats, 1,000 requests/second sustained). It is informational pricing that any
authenticated session can read, including a brand-new owner on onboarding.
Use it to render a pricing or onboarding screen before a workspace activates.
200
error.retry_after (seconds) from the envelope and hold that long before the
next poll instead of hammering the endpoint.
Each plan also reports the free-trial credit, the entitlement limits, and the
entitled channel/capability keys — the
full field list sits behind the same endpoint.
The subscription lifecycle endpoints exist for enterprise contracts and for
legacy lifecycle actions:
POST /api/v1/billing/subscription—cancel,reactivate, orchange_planwith an audit-loggedreason(owner/admin/billing role).POST /api/v1/billing/checkout— mint a hosted checkout session for a one-off enterprise contract price.POST /api/v1/billing/portal— open the payment-method portal for the org’s Stripe customer.GET /api/v1/billing/payment-method— read the saved payment method.
GET /api/v1/billing/trial-credits/status reports whether the
org has claimed them.
5. Invoices & statements
Invoices.GET /api/v1/billing/invoices lists the org’s invoices, and
GET /api/v1/billing/invoices/:id returns line-item detail. Card and crypto
top-ups both produce receipts under Dashboard → Billing → Invoices, with
payment method, network/coin detail for crypto, and USD-equivalent recorded
at confirmation time.
Monthly statements. Orbit aggregates the prepaid-wallet ledger into native
monthly statements — opening balance, top-ups, usage-by-channel, closing
balance — for pay-as-you-go tenants. GET /api/v1/billing/statements lists
monthly summaries; GET /api/v1/billing/statements/:period (e.g. 2026-08)
returns detail; GET /api/v1/billing/statements/:period/download exports CSV
or JSON. Owner/admin role. Dashboard → Billing → Statements is the same data.
Revenue recognition. For finance teams, GET /api/v1/billing/revenue-recognition/schedule produces the per-contract
straight-line recognition schedule for committed-use commitments and
recurring subscription invoice lines; GET /api/v1/billing/revenue-recognition/summary rolls recognized-in-period vs.
remaining-deferred as of a reporting date. Read-only, billing-role. See
Revenue recognition for the model, field
reference, dashboard walkthrough, and month-end workflow.
6. Usage, burn rate, and spend alerts
Usage.GET /api/v1/billing/usage returns the current-billing-period
usage metrics (name, usage, limit per metric). For a per-channel breakdown
with cost and volume, use GET /api/v1/billing/usage-by-channel with
group_by axes channel | country | campaign | sender | cost_center; the
cost_center tag set on sends enables chargeback attribution, and
GET /api/v1/billing/chargeback-rollup rolls the period up by department.
Dashboard → Billing → Usage is the same surface.
Transactions ledger. GET /api/v1/billing/transactions reads the
append-only wallet ledger with cursor pagination — every credit and debit.
Use it to reconcile deductions against what the wallet actually recorded.
Per-channel pricing rules are documented in the
Billing API reference.
200
next_cursor returns HTTP 422 with code: "INVALID_CURSOR" — drop the
cursor and restart from the first page rather than retrying it.
Burn rate. GET /api/v1/billing/burn-rate returns average daily spend
and projected days remaining before the wallet hits zero (the dashboard
balance widget’s “X days remaining” line). GET /api/v1/billing/spend-series
returns the same window plus a forward projection and anomaly flags.
Spend alerts. Billing alerts watch spend or balance thresholds and act
when crossed. Config is org-owned; the scheduler evaluates thresholds on a
10-minute tick.
GET /api/v1/billing/alerts/GET /api/v1/billing/alerts/:id— list and read.POST /api/v1/billing/alerts— create (thresholds:spend_percent,spend_amount,balance_remaining,daily_spend; recipients by email and/or SMS;action_on_hit:notify,pause_outbound, orblock_outbound; cooldown up to 30 days).POST /api/v1/billing/alerts/:id/test— dry-run test-fire.GET /api/v1/billing/spend-anomalyandGET /api/v1/billing/spend-anomaly/ledger— velocity-anomaly detection that flags channels projecting a spend surge above your trailing baseline.
notify so an operator reviews the hit; pause_outbound pauses
outbound sending until the alert is reset in the dashboard.
7. Committed-use contracts
Enterprise tenants on a negotiated monthly commitment can watch the drawdown meter:GET /api/v1/billing/commitment reports how much of the monthly
commit has been consumed this period, a linear run-rate projection, and the
projected end-of-period true-up (minimum-commit shortfall when under pace,
overage when exceeded).
commitment: null and the dashboard panel self-hides.
For pricing forecasting you might also use GET /api/v1/billing/volume-tier-preview (see what committing more volume earns),
GET /api/v1/billing/budget-cap (the org’s monthly budget cap for campaign
checks), and POST /api/v1/billing/whatif-pricing/preview (re-price real
usage against a candidate rate card). All are read-only.
8. Refunds
Crypto refunds. Crypto payments are final and are not reversible from the dashboard; a human operator processes each refund via a manual payout. See Cryptocurrency refunds for the request flow and the same-chain wallet requirement. Card refunds. Owner-role endpoints wrap Stripe refunds against the original charge, subject to a 30-day window and unused-balance-only scope:POST /api/v1/billing/refunds— create a refund request (owner only).GET /api/v1/billing/refunds/GET /api/v1/billing/refunds/:id— list and poll request status.
Where next
- Billing API reference — endpoint-by-endpoint request/response detail.
- API error handling by example — how to read the error envelope and branch on the codes above.
- API recipes — #22 billing what-if and spend/burn — re-price real usage and read burn rate end to end.
- Revenue recognition — straight-line deferred-revenue schedules for finance teams.
- Cryptocurrency payments — crypto top-ups.
- Cryptocurrency refunds — the operator-managed refund process.
- Wallet top-up currency conversion — FX behavior on non-wallet-currency credits.