Skip to main content

Per-channel connection mode: BYO vs platform default

When you resell Orbit to your own customers, each channel your subaccounts use — SMS, Voice, Email, WhatsApp — runs on one of two connections:
  • Platform default — Orbit’s shared connection. Standard usage billing; nothing to set up.
  • Your own connection (BYO) — a connection you bring (your own SIP trunk, SMPP account, email domain, WhatsApp Business account, and so on). Traffic on it carries a flat per-transaction platform fee in place of the platform default rate.
This guide covers reseller mode: the parent-org capability that lets a whitelabel parent decide, per channel, which of those two connections every one of its subaccounts uses.

The inheritance model

One place to look, one decision per channel:
  • One active BYO connection per channel. The registry holds at most one connection per provider type.
  • No per-subaccount registry. BYO inheritance is all-or-nothing per channel, from the parent down — a subaccount cannot pick its own connection.
  • Subaccounts inherit transparently. An active parent BYO row carries every subaccount’s traffic on that channel; no row (or reseller mode off) falls back to the platform default.
Mixed mode is the normal case: bring your own SMPP account and SIP trunk, leave email on the platform default. Each channel is independent.

Provider types

Like SMS (smpp + sms_http_api), email has both connectivity shapes: email_smtp for host/user/pass relay and email_api for providers that expose a key-authed HTTP API instead of raw SMTP. Both rows can be configured independently for the email channel.

1. Turn on reseller mode

Reseller mode is the gate. Until it is on, no BYO connection resolves — everything runs on the platform default even if you’ve saved connections.
Turning it off is a fail-safe, not a wipe: saved connections stay on record, and every channel falls back to the platform default. Turn it back on and the prior configuration picks up where it left off.
Only a parent org (an org with no parent of its own) can enable reseller mode. A subaccount calling this endpoint with enabled: true gets 403 — nested resellers are not a supported shape.

2. Bring your own connection for a channel

Define — or replace — a channel’s connection with PUT /organization/reseller/providers/:providerType. Because the registry is one-connection-per-type, a PUT on an existing type overwrites the prior connection.
Two things to know about the body:
  • status — set it to "active" to put the connection in service. Anything else (pending, degraded, failed) keeps the registry entry but resolves the channel to the platform default. Only active rows take traffic.
  • credentials — a plaintext map of whatever fields that connection needs. The API encrypts every value before it persists and never echoes a raw secret back: reads return each saved field as the masked sentinel ••••••. To rotate a secret, send the new value in the same field; to clear a field, send it as an empty string. At most 50 fields, each value at most 2000 characters.
The response tells you where the channel resolves now:
mode: "byo" means subaccounts’ SMS now runs on your connection. If reseller mode is off, the same save returns mode: "devotel_default" — the connection is stored, just not in service.

3. Revert a channel to the platform default

Delete the registry entry and the channel flips back immediately:
Deleting a provider type that was never set is a safe no-op.

4. Read the current state

One call returns the whole reseller slice:
  • enabled — the reseller-mode flag.
  • isSubaccount — true when the caller itself is a subaccount; subaccounts always receive an empty providers list.
  • effectiveResellerOrgId — the org the caller resolves against: its parent when the caller is a subaccount, itself when it is the reseller org, otherwise null.
  • providers — the registry with credential values masked.
When you only need the resolution for one channel: GET /organization/reseller/resolve/:providerType returns { "mode": "byo" | "devotel_default", "providerType", "config": … }.

Dashboard

Everything above is also a point-and-click surface — resellers typically have no admin-panel access, so the whole model is dashboard-driven. The Channel Connection Mode panel renders the master toggle, one row per provider type, and the inline credential editor. It appears in two places: on the Subaccounts list page (Settings → Subaccounts, the card below the child-org list) and in step 3 of the 5-step new-subaccount wizard. Same card, same endpoints — the only difference is that the wizard treats the mode choice as part of onboarding. A subaccount viewing either surface sees a read-only “managed by your parent” note.

The master toggle

At the top of the card, a strip holds the Reseller mode (bring your own connections) switch. Toggle it on and the per-channel controls below enable; toggle it off and every channel falls back to the platform default immediately (registry rows stay). The switch hides when the caller is a subaccount, and disables while a save is in flight.

Per-row states and actions

Each row shows a state badge and the actions that match:
  • No registry row — a neutral Platform default badge; one action: Use your own connection (saves status: "active").
  • Saved but not active (pending / degraded / failed) — the badge reads Pending — not in service for pending, or the raw status word in an amber/red tint for degraded/failed. Same single action: Use your own connection.
  • Active BYO — a green Your own connection (BYO) badge with two actions: Save connection (re-PUT with credential edits, staying active) and Revert to platform default (a confirmation dialog that names the channel and warns credentials are deleted, then DELETE).
On an active row the panel renders password inputs, one per stored credential field, pre-filled with the masked sentinel. Retype a field to rotate it, empty it to clear it, then Save connection. Untouched fields pass through unchanged. When the master toggle is off, a hint line renders and every activate/save button stays disabled.

Per-channel status

The registry contract is uniform; what differs is whether a channel’s routing integration consumes the resolution yet: Use GET /organization/reseller/resolve/:providerType to probe any of the eleven: mode: "byo" means the parent’s active row is what a subaccount resolves to — the routing side still depends on that lane having shipped. A mode: "devotel_default" answer means no active row, or reseller mode off — check the sibling enabled field on the full slice. Do not rely on a stored-but-unwired lane in production; watch the channel’s changelog entry for the integration that turns a pending lane live.

Failure recovery: a credential rotation runbook

When a rotated credential turns out bad mid-incident, the behavior is always: while the row’s status is anything but active, the channel falls back to the platform default and the saved row stays for you to fix.
  1. Detect. Subaccount sends on one channel start failing. Read GET /organization/reseller/resolve/:providerType — if it still reports mode: "byo" but sends fail, the registry believes the row is active and the upstream is rejecting the credential.
  2. Mark the row degraded. PUT the providerType with status: "degraded" (no credential fields). The channel falls back to the platform default at the next resolution; the row stays on file.
  3. Fix the credential. PUT the providerType again with the corrected fields and status: "active". The resolution flips back to byo with the first save that lands.
  4. Verify from the parent. Re-read the resolver endpoint and confirm a subaccount’s next send succeeds. The parent’s registry row is the single source of truth; subaccounts never see the fix.
If a plaintext is lost outright, the recovery is the same rotation path with no incident window: type the replacement into the dashboard row or PUT it, then save. There is no history lookup — the masked sentinel is all the read path returns.

Limits and rules

Troubleshooting

  • 403 — “a subaccount cannot enable it on itself” — the caller is itself a subaccount; reseller mode is parent-scope only. Use the parent org’s API key.
  • 403 — “Provider configuration belongs to the reseller parent” — same cause on provider writes: provider rows are parent-owned.
  • Saved a row but resolve still reports devotel_default — either the row’s status is below active (pending/degraded/failed), or reseller mode is off. Check GET /organization/reseller for enabled and the row’s status.
  • Lost the plaintext of a saved field — nothing in the API returns it; rotate by re-saving the field with the replacement value.
  • Branded SMPP / branded SIP preconditions — DNS pointing at your carrier’s endpoint and a TLS certificate for the hostname are still yours to own before the parent flips the lane; the registry stores the parameters but the carrier-side TLS/DNS is your responsibility so a connection is not declared active against an endpoint that fails the handshake.
  • A row shows failed or degraded — that status flips the resolution to the platform default. Fix the upstream credential and re-activate with a PUT carrying status: "active".