Skip to main content

Reseller Usage Metering API

For platforms reselling Orbit to their own customers — agencies, MSPs, vertical SaaS. Send a batch of your end customers’ usage events with a custom meter definition, and get back a rated, per-subaccount rollup plus the wallet-ledger and invoice draft you would bill each subaccount with. This is a programmatic partner endpoint: you already hold your end customers’ usage events in your own system, so you POST them here and get the rated result back. It is stateless — nothing is persisted and no wallet or invoice is charged. Use it to rate a billing period, preview the numbers, and (optionally) render the branded invoice you hand your customer. Resolving a tax-exemption certificate is a control your organization’s billing team owns: you pass the resolved certificate into the request, and the invoice draft foots accordingly. The concept page Reseller margin and the tax pipeline explains what the resellerMarginPct percentage is, why it applies before tax, and how it differs from a rate markup. Base path: /api/v1/usage/meters Authentication: Organization session JWT or an owner/admin API key. You only ever rate your own payload.

Rate a batch

Rollup usage events

POST /api/v1/usage/meters/rollup Rate a batch of metered events against a custom meter and return the rollup. Each event names the subaccount that incurred it and a quantity; the meter defines the included quantity and the graduated overage tiers used to price the overflow.

Meter definition

Request body

Invoice metadata

Supply the optional invoice block to also receive a branded, standalone HTML invoice (billing.invoice.rendered_html) for the marked-up draft — the document you hand your end customer.
All amounts are in minor currency units (cents). The billing block is a preview of the write descriptors — the wallet-ledger debits and the invoice draft you would charge each subaccount with. This endpoint does not commit them; persisting the ledger and invoice writes is a separate step in your own billing flow.

Tax exemption — the approved vs. reverted branch

The invoice branch is deterministic: an approved exemption certificate whose jurisdiction matches tax.jurisdiction (or is a blanket certificate with no jurisdiction) and whose validity window covers the rating period suppresses the tax line entirely. Any other status — pending, rejected, or expired — taxes the invoice as normal, so an approved certificate whose validity window has lapsed reverts to a taxed invoice even though the status itself still reads approved. The invoice echoes the outcome so you can audit it: tax_exemption_status mirrors the status you passed, and tax_exemption_applied is true only when tax was actually suppressed.
Now replay the same call with a certificate that no longer qualifies (status: "rejected", an expired status, or an approved status whose valid_to has already lapsed) — the tax line comes back:
Response truncated to the billing.invoice block for readability — the rest of the envelope is unchanged. When the exemption matches, the rendered document (if you asked for one) omits the tax row; when it reverts, the tax row comes back.
A blanket exemption (no jurisdiction on the certificate) matches any tax.jurisdiction. A certificate that names a jurisdiction matches case-insensitively, but never against an absent or mismatched tax.jurisdiction.

Using the SDKs

The typed resources do not cover usage metering yet, so this page’s calls go through each SDK’s generic escape hatch — the same pattern the event-sinks page uses. The samples below run the full rollup envelope from the Rollup usage events section above — meter, events, period, margin, tax, exemption, and invoice — so you get the rated totals and the rendered HTML invoice back in one call. Node (orbit.request):
Swap the path to /api/v1/usage/meters/credit-note to issue a credit note the same way. request() attaches your API key, retries 429/5xx with backoff, and returns the same { data, meta } envelope a raw call returns — fetch() with an X-API-Key header works identically. Python (client.request — the escape hatch, not plain requests, because the rollup POST needs a JSON body):
The Python SDK is core-scope — it wraps the 8 core resources (messaging, voice, contacts, campaigns, verify, numbers) and reaches everything else through the generic client.request() escape hatch above. See the Python SDK. Go (client.Request — the exported low-level method an untyped endpoint uses):
The Go SDK is core-scope like Python — typed helpers cover the core resources, and client.Request(ctx, method, path, query, body, out, idempotencyKey) carries the rest. See the Go SDK. Ruby (client.request — the same escape-hatch shape as Python):
PHP ($client->request(...) — the same escape-hatch shape as the others):
Raw curl in the body of this page works identically. Full SDK index at SDK quickstart.

Issue a credit note

Credit a prior charge

POST /api/v1/usage/meters/credit-note Issue a credit note (credit memo) or a manual invoice adjustment against a charge you already billed a downstream customer. A credit note reduces what the customer owes on their invoice — use it for an overbilled line, a goodwill credit, a negotiated discount, or a billing-error correction. Unlike a Stripe refund it moves no money on a card; it produces the finance document you hand your customer. Like the rollup endpoint it is stateless — nothing is persisted. It returns the credited totals and, when you supply a credit_note block, a branded, standalone HTML credit note (credit_note.rendered_html).

Request body

Credit-note metadata

Amounts are in minor currency units (cents), and the totals are the credited (owed-back) figures. This endpoint does not persist the credit note or apply it to a wallet — record it and apply it against the invoice in your own billing flow.

Totals-only responses

The credit_note block is optional on this endpoint (just as invoice is optional on rollup). Omit it and the rated/credited totals come back without any rendered HTML — the shape you’d poll programmatically or preview before printing a document. Conversely, pair a tax/exemption combination like the rollup samples above and supply or suppress the document block the same way — for example, omit invoice from an exemption-suppressed rollup call and billing.invoice still carries tax_exemption_status: "approved" and tax_exemption_applied: true, just without rendered_html:
The original_total_minor guard works the same either way: a credit whose total exceeds the original invoice’s tax-inclusive total is rejected with a 422, whether or not you asked for the document.