Meta Embedded Signup Setup — WhatsApp Channel Connection
1. Overview
Current state: The codebase readsMETA_APP_ID, META_APP_SECRET, NEXT_PUBLIC_META_APP_ID, and NEXT_PUBLIC_META_WA_CONFIG_ID from environment variables, but these are not documented in .env.example files.
Target: All Meta App Dashboard settings configured, environment variables set, and the WhatsApp Embedded Signup OAuth flow functional for connecting WhatsApp Business accounts.
Why this is needed: The WhatsApp Embedded Signup flow allows tenants to connect their WhatsApp Business API phone number through an iframe-based OAuth flow. Without these Meta App Dashboard settings correctly configured, the connect channel wizard cannot function.
2. Prerequisites
- A Meta Developer account
- A Facebook Business account (Meta Business Suite)
- A Meta App of type Business (created or selected in Step 1)
- Admin access to the Agentix deployment environment (Railway for API, Vercel for web)
3. Step 1 — Create or Select a Meta App
- Navigate to developers.facebook.com > My Apps > Create App (or select an existing app)
- Select app type: Business
- Fill in the app name (e.g., “Agentix”) and contact email
- After creation, go to Settings > Basic to find your credentials:
| Setting | Navigation | What to Copy |
|---|---|---|
| App ID | Settings > Basic > App ID (numeric ID at the top of the page) | Copy this value — it is used for both META_APP_ID and NEXT_PUBLIC_META_APP_ID |
| App Secret | Settings > Basic > App Secret > Show (requires re-authentication) | Copy this value — it is used for META_APP_SECRET only in the API |
IMPORTANT: The App ID is a numeric string (e.g.,123456789012345). You will need this same value in two places:META_APP_IDin the API andNEXT_PUBLIC_META_APP_IDin the web app. They must be identical.
4. Step 2 — Add WhatsApp Product
- In the Meta App Dashboard, click Add Product in the left sidebar
- Find WhatsApp and click Set Up
- Follow the prompts to associate a Meta Business account if not already linked
IMPORTANT: The WhatsApp product must be added to the app BEFORE configuring Login for Business (Step 4). Without it, the “WhatsApp Embedded Signup” login variation will not appear as an option.
5. Step 3 — Configure Webhook URL and Verify Token
- In the Meta App Dashboard, navigate to WhatsApp > Configuration in the left sidebar
- Under Webhook, click Edit
- Set the following values:
| Setting | Value |
|---|---|
| Callback URL | https://{your-api-domain}/webhooks/whatsapp |
| Verify Token | See note below |
apps/api/src/routes/webhook.ts) validates Meta’s verification challenge by looking up the verify token in the database. It checks the channel.webhookVerifyToken field for a matching active channel record.
Since the verify token is per-channel and auto-generated when a channel is created through Embedded Signup (randomBytes(16).toString('hex') in meta-channel-oauth.ts), you have two options for initial setup:
- Option A (recommended): Skip webhook verification in the Meta Dashboard for now. Complete the Embedded Signup flow first (which creates a channel with an auto-generated verify token), then return here and use that channel’s
webhookVerifyTokenvalue from the database to verify the webhook in the Meta Dashboard. - Option B: Manually insert a channel record with a known verify token into the database before verifying the webhook. Use that same token in the Meta Dashboard.
- After setting the Callback URL, click Manage under Webhook Fields
- Subscribe to the messages field (required for receiving inbound WhatsApp messages)
IMPORTANT: The webhook URL must be configured and the messages field subscribed BEFORE channels will receive inbound messages. If you skip this step, channels will appear “connected” but will not receive any messages.
6. Step 4 — Create Login for Business Configuration (config_id)
- In the Meta App Dashboard, navigate to Facebook Login for Business in the left sidebar
- If you don’t see it, click Add Product and add Facebook Login for Business
- Go to Configurations > Create Configuration
- Configure the following settings in the creation wizard:
| Setting | Value |
|---|---|
| Configuration name | e.g., “Agentix WhatsApp Signup” |
| Login variation | WhatsApp Embedded Signup |
| Token type | System-user access token with 60-day expiry |
| Assets | WhatsApp accounts with manage permission |
| Permissions | whatsapp_business_management |
- After saving, you will be returned to the Configurations list
- Copy the numeric Config ID from the Configurations list — this is the value for
NEXT_PUBLIC_META_WA_CONFIG_ID
IMPORTANT: The Config ID (config_id) is NOT the same as the App ID. The config_id is found here in Facebook Login for Business > Configurations, while the App ID is found in Settings > Basic. These are different numeric values. Using the wrong one will cause the Embedded Signup popup to show a generic Facebook login instead of the WhatsApp Embedded Signup flow.
7. Step 5 — Set OAuth Redirect URIs and Allowed Domains
- In the Meta App Dashboard, navigate to Facebook Login for Business > Settings
- Under Client OAuth Settings, configure:
| Setting | Value |
|---|---|
| Valid OAuth Redirect URIs | https://{your-frontend-domain} |
| Allowed Domains for the JavaScript SDK | https://{your-frontend-domain} |
- URIs must use HTTPS (no HTTP, even for localhost — use a tunnel like ngrok for local development)
- No wildcards allowed
- The domain must exactly match where your frontend is hosted (e.g.,
https://app.agentix.app)
8. Step 6 — Configure Environment Variables
Set the following environment variables in your deployment environment:| Variable | App | Where to Find | Example |
|---|---|---|---|
META_APP_ID | apps/api (Railway) | Settings > Basic > App ID | 123456789012345 |
META_APP_SECRET | apps/api (Railway) | Settings > Basic > App Secret > Show | abc123def456... |
NEXT_PUBLIC_META_APP_ID | apps/web (Vercel) | Same App ID as META_APP_ID | 123456789012345 |
NEXT_PUBLIC_META_WA_CONFIG_ID | apps/web (Vercel) | Facebook Login for Business > Configurations > Config ID | 987654321098765 |
CRITICAL:For local development, add these to yourMETA_APP_ID(in the API) andNEXT_PUBLIC_META_APP_ID(in the web app) MUST be the same value. They are both the Facebook App ID from Settings > Basic. A mismatch causes the OAuth token exchange to fail withOAuthException: Invalid verification code formatbecause the authorization code issued by the frontend’s FB.login call will not match the App ID the backend uses to exchange it.
.env files:
apps/api/.env— setMETA_APP_IDandMETA_APP_SECRETapps/web/.env.local— setNEXT_PUBLIC_META_APP_IDandNEXT_PUBLIC_META_WA_CONFIG_ID
- Railway: API service > Variables
- Vercel: Project > Settings > Environment Variables
9. Verification Checklist
After completing all steps, verify your configuration:- Meta App type is “Business”
- WhatsApp product added to the app
- Webhook Callback URL set to
https://{your-api-domain}/webhooks/whatsapp - Webhook subscribed to the
messagesfield - Facebook Login for Business configuration created with “WhatsApp Embedded Signup” variation
- Config ID copied and set as
NEXT_PUBLIC_META_WA_CONFIG_ID - OAuth Redirect URI set to frontend domain (HTTPS)
- Allowed Domains for the JavaScript SDK includes frontend domain
-
META_APP_IDandNEXT_PUBLIC_META_APP_IDare identical values -
META_APP_SECRETis set only in the API (never in the web/frontend app) - All 4 environment variables are set in the deployment environment
10. Troubleshooting
”WhatsApp Embedded Signup” not visible in Login Variation dropdown
Cause: The WhatsApp product has not been added to the Meta App. Fix: Go to the Meta App Dashboard > Add Product > WhatsApp > Set Up (Step 2), then return to create the Login for Business configuration.Token exchange fails with OAuthException
Cause:META_APP_ID and NEXT_PUBLIC_META_APP_ID are set to different values.
Fix: Verify both environment variables contain the exact same App ID from Settings > Basic. The frontend sends an authorization code scoped to NEXT_PUBLIC_META_APP_ID, and the backend must exchange it using the same App ID via META_APP_ID.
FB.login popup shows generic Facebook login (not WhatsApp Embedded Signup)
Cause: Wrong config_id. TheNEXT_PUBLIC_META_WA_CONFIG_ID is set to the App ID instead of the Login for Business Config ID.
Fix: Go to Facebook Login for Business > Configurations and copy the correct Config ID. The config_id and App ID are different numeric values from different parts of the dashboard.
Channel connected but no inbound messages
Cause: Webhook URL was not configured before the channel was connected, or themessages webhook field was not subscribed.
Fix: Configure the webhook URL and subscribe to the messages field (Step 3). You may need to disconnect and reconnect the channel for webhook subscriptions to take effect.
OAuth flow works for me but not teammates
Cause: The Meta App is in Development mode. Only users listed as admins, developers, or testers in the app roles can complete the OAuth flow. Fix: Either add teammates as testers in the Meta App Dashboard (App Roles > Add People), or switch the app to Live mode (requires Meta App Review — see Step 11).11. Development vs Live Mode
Development Mode
- Only app admins, developers, and testers can use the OAuth flow
- Fine for initial testing and internal verification
- No Meta App Review required
- Limited to 250 API calls per hour
Live Mode
- Any Facebook/WhatsApp user can use the OAuth flow
- Required before production launch or external user access
- Requires Meta App Review (typically 3-7 business days)
Required Permissions for App Review
| Permission | Purpose | Required? |
|---|---|---|
whatsapp_business_management | Manage WhatsApp Business accounts, phone numbers | Yes |
whatsapp_business_messaging | Send and receive WhatsApp messages | Yes |
business_management | Access business portfolio information | Recommended |
References
- Meta App Dashboard
- WhatsApp Cloud API Documentation
- WhatsApp Embedded Signup Documentation
- Facebook Login for Business Documentation
apps/api/src/services/meta-channel-oauth.ts— Backend OAuth service (token exchange, channel creation)apps/web/src/app/layout.tsxL53 — Facebook SDK initialization withNEXT_PUBLIC_META_APP_IDapps/web/src/app/app/[workspaceId]/settings/channels/_components/connect-wizard-dialog.tsxL21-26 — Frontend Meta OAuth constantsapps/api/src/routes/webhook.ts— Webhook verification handler (per-channel verify token lookup)