> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-environment subaccounts: dev, staging, prod, and product-line isolation

> Split one organization into environment or product-line subaccounts — per-environment wallets, budgets, and scoped keys — then attribute spend per stage without any reseller setup.

# 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](/guides/organization-team-management) 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 plain `POST /api/v1/subaccounts` (or the one-shot `POST /api/v1/subaccounts/provision`) — both the [reseller import flow](/guides/subaccounts-reseller) and the [channel connection modes](/guides/subaccount-connection-modes) pages build on the same pair:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/subaccounts \
  -H "X-API-Key: dv_live_sk_your_parent_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "payments-staging",
    "plan": "growth",
    "monthly_spend_cap_cents": 50000,
    "initial_credits_cents": 10000
  }'
```

Only `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_cents` on 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.

The parent's wallet is the feeder for every stage. When `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](/guides/api-keys-messaging-ccaas-cdp) 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.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/subaccounts/sub_9x4tqkz/api-keys \
  -H "X-API-Key: dv_live_sk_your_parent_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "staging-worker", "scopes": ["messages:read", "messages:write"] }'
```

Hand the returned key to the staging worker. A production worker gets a key minted on the production subaccount the same way — the pair never share credentials. Because the child-scope boundary sits at the key layer, you can rotate the stage key on a schedule without touching production.

## 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}/usage` reads one child's metered usage, and `GET /api/v1/subaccounts/usage-rollup` folds the whole tree, so the parent's statement line-items per environment.
* **Chargeback per stage** — finer tags still work: a `metadata.cost_center` on the send (see [Cost-center chargeback](/guides/cost-center-chargeback)) lets one environment split its own spend internally, e.g. `stage_regression` vs `stage_ux`, while the parent still sees one rollup line per child.

Membership structure stays relevant here: the parent's admins are the members who read both surfaces — see [Team management](/guides/organization-team-management) for who can reach the billing endpoints when the operator list changes.

## 6. Operate the lifecycle

Day-to-day operation is the parts you exercise once the tree exists:

1. **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/subaccounts` returns `403`, the parent key against a child's data returns `404` on reads the child scopes.
2. **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.
3. **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.

Worked example: a dev org runs a staged campaign against a `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](/guides/subaccounts-reseller) — the reseller flow (provision, pricing, branding) all of these steps build on
* [Per-channel connection modes](/guides/subaccount-connection-modes) — BYO vs platform default connections your parent's registry hands to subaccounts
* [Choose and scope API keys](/guides/api-keys-messaging-ccaas-cdp) — the scope-per-integration walk through that inheritance relies on
* [Cost-center chargeback](/guides/cost-center-chargeback) — the `metadata.cost_center` tag pattern
* [Team members, invitations, and roles](/guides/organization-team-management) — operator-role membership
* [Subaccounts API](/api-reference/subaccounts) — endpoint catalog
