Skip to main content

Onboarding wizard: tenant provisioning and white-label joins

Between “I signed up” and “I sent my first message” the platform runs a short, observable chain: it verifies your email, provisions your workspace’s tenant schema, seeds your first API key, and then derives — step by step, from live data — a nine-item getting-started checklist that ends at a sending workspace. This guide walks that chain end to end: where the wizard sits in the tenant journey, what each provisioning step checks, how white-label signups join an existing tenant instead of creating one, what a degraded provisioning window means for you, how the wizard’s status reads relate to webhooks, and what you hold when the wizard finishes. This page covers the provisioning wizard itself. Two sibling surfaces surround it and have their own docs: the Onboarding wizard lifecycle concept defines the checklist’s probe and override semantics in depth, and the Onboarding status timeline guide covers the human-facing verification view (account KYC, 10DLC, country profiles, per-number registration) that runs in parallel under Settings → Onboarding Status.

1. Where the wizard fits in the tenant journey

The full path from first visit to live traffic has four stages; the provisioning wizard is stages two and three:
1

Join or sign up

You either create an account yourself or arrive through a white-label domain. Self-signup mints a placeholder workspace the moment your account exists — no form required. A white-label signup skips even that: you join the tenant that owns the branded domain you arrived on (Section 3).
2

Provisioning runs in the background

Within seconds of signup the platform creates your tenant schema (every workspace’s data lives in its own isolated schema — see Tenant isolation), seeds an API key, and marks your email verified when you confirm it. The provisioning panel in the dashboard polls GET /api/v1/onboarding/provisioning-status roughly every two seconds and shows each signal as it completes, so the wait is transparent rather than a bare spinner. Once the three blocking signals are green, the dashboard swaps the panel for normal content.
3

The getting-started checklist

Once provisioning completes, the Home dashboard renders the nine-step checklist from GET /api/v1/onboarding/status (Section 2). Steps complete automatically as the underlying rows appear — name your workspace, buy a number, send a sandbox message — and any step can be marked complete or skipped manually by an admin.
4

KYC and go-live

Account KYC runs in parallel with the checklist: you submit under Settings → KYC, a reviewer decides (usually within 24 hours), and approval unlocks your trial credit and the commission of live traffic. The verification gates — KYC, 10DLC, country profiles, per-number registration — are tracked on the Onboarding status timeline, and the go-live checklist collects the final production gates. Sandbox traffic is free before any of that completes.
Two things are deliberately not wizard gates: trial credits and KYC. Credits arrive when KYC is approved, not when you verify your email, and the checklist hides its trial-credit row until that approval — so the wizard never shows a step you cannot move. Compliance state is tenant-owned throughout: every gate your tenant opens is decided and surfaced within your own workspace, never inherited from another tenant.

2. The wizard steps, as the controller derives them

GET /api/v1/onboarding/status derives the checklist from live platform rows on every cache miss — nothing about your progress is stored in the browser, and no step is a form you fill. Each step has a stable id (the same id the manual-marking endpoints accept), a label, a ctaUrl deep link, and a completion signal. The nine canonical steps, in render order: To poll the wizard directly (for an internal status board or a scripted readiness gate):
The response carries per-step completed, completedAt, and completedBy ("system" for a derivation, "user" for a manual override), plus totals (completedCount, totalCount, overallPct) and the nextIncompleteStep summary the dashboard’s resume banner uses. The response is cached 60 seconds per (workspace, user) — poll no faster than that. For the full semantics (probe model, partial success, overrides, the KYC visibility gate) read Onboarding wizard lifecycle.

Marking a step complete or skipping it

A step that is not auto-detectable — or genuinely does not apply, like a payment method on a sandbox-only workspace — can be cleared by an admin:
The body is {"stepId": one-of-the-nine}; any other id is a 422. Both endpoints require admin or higher and are applied to the caller’s own checklist view — two operators in one workspace keep independent marks.

The provisioning-status gate

Before the checklist even renders, the post-signup provisioning panel polls GET /api/v1/onboarding/provisioning-status:
  • emailVerified — your email confirmation landed.
  • tenantSchemaReady — the workspace’s tenant schema finished provisioning.
  • trialCreditsGranted — informational only; never a blocking signal.
  • apiKeySeeded — at least one active API key exists.
  • allReady — true once the three blocking booleans (email, schema, API key) are green.
Your integration does not need to poll this — the dashboard handles it — but if you script workspace readiness, allReady is the gate to wait for before creating numbers or sending.

3. The white-label join path

When a signup arrives through a white-label custom domain (a reseller’s branded app host), the wizard takes a different route than self-signup: instead of minting a placeholder workspace for the visitor, it joins the visitor into the tenant that owns the branded domain. There is no workspace-naming step and no child org — you become a member of the existing tenant at the base user seat, and the tenant owner promotes from there. Concretely, the dashboard’s workspace step POSTs POST /api/v1/onboarding/whitelabel-join with the branded host name, and the server:
  1. Re-verifies the host against the active custom-domain registry — a host that is not a live white-label domain is rejected (the host arrives over an attacker-controllable header, so it is never trusted without a registry lookup).
  2. Confirms the domain’s owning tenant is live and finished provisioning.
  3. Binds you into that tenant at the least-privilege seat — replaying the call when you already belong there is an idempotent no-op.
  4. Retires the auto-provisioned placeholder workspace so it never lingers in your org switcher.
The endpoint fails closed. The error codes are deliberate and each maps to a distinct remediation: Two consequences for tenant owners (the reseller operating the branded domain):
  • Joiners land as user, not admin. Promote them under Settings → Team if they need more (see Organization team management).
  • The joiner’s provisioning signals (tenant schema, API key) are satisfied by the owner’s tenant from day one, so their checklist starts at the workspace-name/e-mail steps and the provisioning panel resolves immediately.

4. The provisioning degradation model

Provisioning reads are written to be safe under partial failure — a degraded backend changes the shape of the answer, not the availability of the endpoint:
  • Every probe degrades per-step. If one underlying read fails (a connection blip, a briefly absent schema), that step resolves to “not complete” and every other step still resolves normally. You see an honest checklist with one understated row, never a 500.
  • The whole checklist degrades to an all-incomplete 200 when the derivation exceeds its deadline or the database is briefly unavailable. That response is deliberately not cached, so the next poll re-derives the true state the moment the backend recovers. Treat an unexpectedly-empty checklist as exactly that: one transient cycle.
  • Provisioning-gap errors — a brand-new org whose schema is still being created — return the same neutral 200. The onboarding read endpoints opt out of the hard “tenant schema not ready” 503 the rest of the API enforces, because a still-provisioning workspace genuinely has no rows yet.
  • Degraded provisioning reads are logged server-side so a persistent backend issue is distinguishable from “user has not done the step yet” — an understated row that survives more than one cache cycle is a platform signal, not a checklist item to chase.
For your integration the contract is: poll, never page, and never treat “not complete” as an error. GET /onboarding/status will not hang under a slow backend; a degraded read is indistinguishable from a genuinely-incomplete state for one cache cycle and resolves on its own.

5. Webhook and progress signaling

The wizard’s checklist is a read surface; it complements the event stream rather than replacing it, and the two answer different questions:
  • Onboarding checklist (status, provisioning-status, sms-checklist) is pull-based and per-(workspace, user): “what has this workspace done, and what is next.” It is cached and derivation-driven — there are no webhook events for “step N completed.”
  • Status timeline (GET /api/v1/onboarding/status-timeline) is the verification side of the same story: account-KYC, 10DLC, country-profile, and per-number gates, each with a blocker and a resolve link — see Onboarding status timeline.
  • Webhook events fire for the underlying activitymessage.sent / message.delivered, kyc_decision notifications, compliance.10dlc.campaign.suspended, and the rest of the catalog in Webhook events. If you want automation on “the workspace sent its first message,” subscribe to message.sent and detect the first occurrence yourself; the checklist is not the event bus.
One practical overlap: the dashboard checklist step first_message_sent flips to complete when the same sent/delivered row your webhook sees lands. Automate on webhooks, and let humans watch the checklist — they describe one timeline.

6. Post-wizard state: the sandbox and your first channel

Completing the last checklist step hands you a workspace that is ready for sandbox work; finish your onboarding there before live traffic:
  1. Sandbox mode is on before you connect anything. Every account starts with a free sandbox where traffic external to your account is simulated — messages to magic numbers validate and acknowledge without touching a carrier, so you can test end-to-end with zero risk of carrier rejections. The sandbox test mode guide and the magic-numbers playbook cover the test numbers at your disposal.
  2. Connect your first real channel through the Messages hub — SMS, WhatsApp, RCS, Telegram, Email all share the same connect-send-verify shape. The connect your first channel tutorial walks it end to end, from the hub’s Connect button to a delivered message and a handled reply.
  3. KYC approval unlocks live traffic. Submit under Settings → KYC (see the organization KYC guide); once approved, the trial credit grants and you can flip out of sandbox. The go-live checklist is the final sweep before production.
At that point the checklist’s job is done: the wizard disappears from Home (it hides once every step completes), your first channel is connected, and the verification timeline under Settings → Onboarding Status becomes the place you watch the remaining gates.