Multi-environment subaccounts
Subaccounts are not only a reseller feature. A single organization can declare its own child organizations — one per environment (dev, staging, prod) or one per product line — and get per-subaccount wallets, spend caps, connection-scoped keys, and a spend-attribution structure that flat membership cannot express. Traffic and billing stay separated by design, without you maintaining three login environments.
Every control in this guide is tenant-owned: nothing below changes how outbound traffic terminates. This guide covers the whole lifecycle — election, provisioning, funding, scope assignment, billing, and daily operations. Readers: platform engineers splitting one org into stages, or an org head splitting product lines.
1. The account after election
Provisioning follows the account operators you chose during signup. The creator of the organization becomes its owner; the people you invite into Settings → Team become the operators who administer subaccounts. Subaccount writes accept only owner or admin role tokens, so the election step of choosing operators lands here: subaccount management follows whoever you made an admin. See Team members, invitations, and roles if the operator list needs adjusting first — an environment subaccount inherits nothing about your member roster, and the parent’s admins are the people who can wire it.2. Declare one subaccount per environment
One call per stage against the flat create endpoint. Reach for the plainPOST /api/v1/subaccounts (or the one-shot POST /api/v1/subaccounts/provision) — both the reseller import flow and the channel connection modes pages build on the same pair:
name is required; plan, cap, and initial funding are optional. Repeat once per environment so naming stays unambiguous: payments-dev, payments-staging, or product-a / product-b for a product-line split. The response returns the child id (sub_...) you carry into every later step.
3. Deploy stages
A subaccount per stage gives each environment its own wallet, budget, and isolation boundary:- Per-subaccount wallet — credits transfer between the parent’s wallet and the child’s wallet with
POST /api/v1/subaccounts/{id}/transfer-credits. Traffic on the child draws only from the child’s balance. - Budget —
monthly_spend_cap_centson the child stops a stage from draining the parent wallet. Stage budgets are usually tighter than the production cap. - Plan and limits — seats and the rate limit follow the child, so a dev subaccount’s traffic ceiling does not compete with production callers.
staging empties, another transfer tops it up; the parent’s remaining balance is unchanged until you move credits.
4. Reuse stages through scoped keys
Inheritance means the scoping rules your integration already knows apply per subaccount too. A key minted on the parent administers the tree; a key minted on the child reaches only that child — one leak can’t pivot across environments. The scope-per-integration guide walks through which scope family each surface needs; on a child you mint the same narrow pair (messages:write + messages:read, e.g.) and your staging worker uses its own scoped key just as a production one does.
5. Billing and attribution
A multi-environment tree gives you two attribution patterns at once; pick either or combine:- Payer/payee attribution — the parent’s org is the payer; each child is a payee.
GET /api/v1/subaccounts/{id}/usagereads one child’s metered usage, andGET /api/v1/subaccounts/usage-rollupfolds the whole tree, so the parent’s statement line-items per environment. - Chargeback per stage — finer tags still work: a
metadata.cost_centeron the send (see Cost-center chargeback) lets one environment split its own spend internally, e.g.stage_regressionvsstage_ux, while the parent still sees one rollup line per child.
6. Operate the lifecycle
Day-to-day operation is the parts you exercise once the tree exists:- Subaccount-scoped vs tenant-scoped keys — a parent-scope key mints, funds, and retires children; a child-scope key does only the child’s messaging. Guard the integration by which scope the caller actually holds — a child key against
POST /api/v1/subaccountsreturns403, the parent key against a child’s data returns404on reads the child scopes. - Wallet isolation — a child cannot see the parent’s balance; the parent’s remaining-credit figure only moves when you transfer. Stage top-ups are explicit calls, never automatic drain.
- Organization-profile hygiene — when the parent’s profile changes (billing contact, organization name), the change lives on
GET/PUT /api/v1/organization/profile; children inherit nothing by design, so environment display names and branding remain per-child even if you update the parent.
stage child while production runs against the primary. POST /api/v1/campaigns on stage’s key sends the regression traffic; the same call with the production child’s key — which is the production workspace — handles live traffic. The parent’s rollup shows one usage line per stage, and the spend cap on stage means a runaway test campaign cannot drain production’s wallet.
See also
- White-label subaccounts — the reseller flow (provision, pricing, branding) all of these steps build on
- Per-channel connection modes — BYO vs platform default connections your parent’s registry hands to subaccounts
- Choose and scope API keys — the scope-per-integration walk through that inheritance relies on
- Cost-center chargeback — the
metadata.cost_centertag pattern - Team members, invitations, and roles — operator-role membership
- Subaccounts API — endpoint catalog