Option A — Hosted (app.switchbord.ai)
If you are an operator joining an existing team or starting a new workspace on the hosted platform:
- Sign up at app.switchbord.ai.
- Create a workspace (or accept an invite from an existing workspace admin).
- Go to Settings → Provider and connect your Meta Business account and WhatsApp phone number.
- Follow the Connect WhatsApp guide for the full credential setup walkthrough.
If you were invited to a workspace and land on /pending-access, your invite is still processing. Contact your workspace admin.
Option B — Local contributor setup
Install
Validate the workspace
Copy the example files before starting the workspace:
If you are working on worker or webhook-runtime behavior, also seed:
apps/control-plane has been removed. Do not create a .env.local for it.
Minimum Supabase variables
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
SUPABASE_SECRET_KEY — for server-side admin paths
WHATSAPP_PLATFORM_DATA_MODE=supabase — only for surfaces with a real Supabase-backed implementation
WORKSPACE_BOOTSTRAP_ADMIN_EMAILS — recommended for any shared or hosted environment to set the first privileged operator
WORKSPACE_ALLOW_FIRST_CLAIM=true — only for intentional one-time first-user owner claim during local bootstrap
The repo still accepts NEXT_PUBLIC_SUPABASE_ANON_KEY and SUPABASE_SERVICE_ROLE_KEY as legacy aliases, but new setup should use the publishable key and secret key forms.
WHATSAPP_META_ACCESS_TOKEN — for the worker
WEBHOOK_SIGNATURE_SECRET — for apps/api
META_WEBHOOK_VERIFY_TOKEN — for explicit webhook challenge verification
SUPABASE_DB_URL — if using Supabase Vault for workspace-managed provider secrets
If a signed-in user is not yet provisioned into a workspace, the operator app routes them to /pending-access until an invite is accepted or bootstrap rules grant membership.
If the first local operator gets stranded on /pending-access, do not delete the auth user. Fix bootstrap by setting WORKSPACE_BOOTSTRAP_ADMIN_EMAILS, temporarily enabling WORKSPACE_ALLOW_FIRST_CLAIM=true, or manually inserting the missing workspace_members row.
See Environment for the full runtime configuration contract.
Start the workspace
Local ports
- app:
3000
- web:
3001
- api:
3002
- docs:
3004
- storybook:
6006
- worker: background process, no HTTP port
High-value routes
- operator inbox:
http://localhost:3000/inbox
- runtime diagnostics:
http://localhost:3000/runtime
- API readiness:
http://localhost:3002/ready
- OpenAPI spec:
http://localhost:3002/spec
- Meta webhook ingress:
http://localhost:3002/webhooks/meta
Working assumptions
- feature flags default to
on
- the Supabase env contract must be satisfied before any surface uses Supabase directly
- forward-only migration is the active posture
- historical message migration is intentionally out of scope for the first cut
Read next