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.
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):
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:{"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 pollsGET /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.
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 baseuser 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:
- 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).
- Confirms the domain’s owning tenant is live and finished provisioning.
- Binds you into that tenant at the least-privilege seat — replaying the call when you already belong there is an idempotent no-op.
- Retires the auto-provisioned placeholder workspace so it never lingers in your org switcher.
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.
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 activity —
message.sent/message.delivered,kyc_decisionnotifications,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 tomessage.sentand detect the first occurrence yourself; the checklist is not the event bus.
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:- 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.
- 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.
- 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.