Skip to main content

Meta Embedded Signup Setup — WhatsApp Channel Connection

1. Overview

Current state: The codebase reads META_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

3. Step 1 — Create or Select a Meta App

  1. Navigate to developers.facebook.com > My Apps > Create App (or select an existing app)
  2. Select app type: Business
  3. Fill in the app name (e.g., “Agentix”) and contact email
  4. After creation, go to Settings > Basic to find your credentials:
SettingNavigationWhat to Copy
App IDSettings > 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 SecretSettings > 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_ID in the API and NEXT_PUBLIC_META_APP_ID in the web app. They must be identical.

4. Step 2 — Add WhatsApp Product

  1. In the Meta App Dashboard, click Add Product in the left sidebar
  2. Find WhatsApp and click Set Up
  3. 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

  1. In the Meta App Dashboard, navigate to WhatsApp > Configuration in the left sidebar
  2. Under Webhook, click Edit
  3. Set the following values:
SettingValue
Callback URLhttps://{your-api-domain}/webhooks/whatsapp
Verify TokenSee note below
About the Verify Token: The Agentix webhook handler (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 webhookVerifyToken value 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.
  1. After setting the Callback URL, click Manage under Webhook Fields
  2. 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)

  1. 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
  2. Go to Configurations > Create Configuration
  3. Configure the following settings in the creation wizard:
SettingValue
Configuration namee.g., “Agentix WhatsApp Signup”
Login variationWhatsApp Embedded Signup
Token typeSystem-user access token with 60-day expiry
AssetsWhatsApp accounts with manage permission
Permissionswhatsapp_business_management
  1. After saving, you will be returned to the Configurations list
  2. 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

  1. In the Meta App Dashboard, navigate to Facebook Login for Business > Settings
  2. Under Client OAuth Settings, configure:
SettingValue
Valid OAuth Redirect URIshttps://{your-frontend-domain}
Allowed Domains for the JavaScript SDKhttps://{your-frontend-domain}
Requirements:
  • 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:
VariableAppWhere to FindExample
META_APP_IDapps/api (Railway)Settings > Basic > App ID123456789012345
META_APP_SECRETapps/api (Railway)Settings > Basic > App Secret > Showabc123def456...
NEXT_PUBLIC_META_APP_IDapps/web (Vercel)Same App ID as META_APP_ID123456789012345
NEXT_PUBLIC_META_WA_CONFIG_IDapps/web (Vercel)Facebook Login for Business > Configurations > Config ID987654321098765
CRITICAL: META_APP_ID (in the API) and NEXT_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 with OAuthException: Invalid verification code format because the authorization code issued by the frontend’s FB.login call will not match the App ID the backend uses to exchange it.
For local development, add these to your .env files:
  • apps/api/.env — set META_APP_ID and META_APP_SECRET
  • apps/web/.env.local — set NEXT_PUBLIC_META_APP_ID and NEXT_PUBLIC_META_WA_CONFIG_ID
For production, set via your hosting provider’s environment variable configuration:
  • 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 messages field
  • 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_ID and NEXT_PUBLIC_META_APP_ID are identical values
  • META_APP_SECRET is 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. The NEXT_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 the messages 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

PermissionPurposeRequired?
whatsapp_business_managementManage WhatsApp Business accounts, phone numbersYes
whatsapp_business_messagingSend and receive WhatsApp messagesYes
business_managementAccess business portfolio informationRecommended
To submit for App Review: Meta App Dashboard > App Review > Permissions and Features > Request each permission with a description of your use case.

References

Code references:
  • apps/api/src/services/meta-channel-oauth.ts — Backend OAuth service (token exchange, channel creation)
  • apps/web/src/app/layout.tsx L53 — Facebook SDK initialization with NEXT_PUBLIC_META_APP_ID
  • apps/web/src/app/app/[workspaceId]/settings/channels/_components/connect-wizard-dialog.tsx L21-26 — Frontend Meta OAuth constants
  • apps/api/src/routes/webhook.ts — Webhook verification handler (per-channel verify token lookup)
Last verified: 2026-03-27