# Implementation | Developer Documentation

<div id="bkmrk-implementationupdate">## Implementation

<div><span>Updated: Mar 25, 2026</span></div><div>This document explains how to implement Embedded Signup v4 and capture the data it generates to [onboard business customers](#bkmrk-onboarding-business--1) onto the WhatsApp Business Platform.</div><div id="bkmrk-before-you-start"><div id="bkmrk-before-you-start-1"><div>### Before you start

</div></div></div><span>You must already be a [Solution Partner](/books/meta-whatsapp/page/get-started-as-a-solution-partner-developer-documentation) or [Tech Provider](/books/meta-whatsapp/page/become-a-tech-provider-developer-documentation).</span><span>If your business customers will be using your app to send and receive messages, you should already know how to use the API to send and receive messages using your own WhatsApp Business Account and business phone numbers. You should also know how to create and manage templates and have a webhooks callback endpoint properly set up to digest webhooks.</span><span>You must be subscribed to the [account\_update](/documentation/business-messaging/whatsapp/webhooks/reference/account_update) webhook, as this webhook is triggered whenever a customer successfully completes the Embedded Signup flow, and contains their business information that you will need.</span><span>If you are a Solution Partner, you must already have a [line of credit<span>?</span>](https://www.facebook.com/business/help/1684730811624773?id=2129163877102343).</span><span>The server where you will be hosting Embedded Signup must have a valid SSL certificate.</span><div id="bkmrk-step-1%3A-add-allowed-"><div id="bkmrk-step-1%3A-add-allowed--1"><div>### Step 1: Add allowed domains

</div></div></div><div>Load your app in the [App Dashboard](/apps) and navigate to **Facebook Login for Business** &gt; **Settings** &gt; **Client OAuth settings**:</div><div>![](https://support2.chatarchitect.com/uploads/images/gallery/2026-04/embedded-image-s9qusvek.png)</div><div>Set the following toggles to **Yes**:</div><span>**Client OAuth login**</span><span>**Web OAuth login**</span><span>**Enforce HTTPS**</span><span>**Embedded Browser OAuth Login**</span><span>**use Strict Mode for redirect URIs**</span><span>**Login with the JavaScript SDK**</span><div>Embedded Signup relies on the JavaScript SDK. When a business customer completes the Embedded Signup flow, the customer's WABA ID, business phone number ID, and an exchangeable token code will be returned to the window that spawned the flow, but only if the domain of the page that spawned the flow is listed in the **Allowed domains** and **Valid OAuth redirect URIs** fields.</div><div>Add any domains where you plan to host Embedded Signup, including any development domains where you will be testing the flow, to these fields. Only domains that have enabled **HTTPS** are supported.</div><div id="bkmrk-step-2%3A-create-a-fac"><div id="bkmrk-step-2%3A-create-a-fac-1"><div>### Step 2: Create a Facebook Login for Business configuration

</div></div></div><div>A Facebook Login for Business configuration defines which permissions to request, and what additional information to collect, from business customers who access Embedded Signup.</div><div>Navigate to **Facebook Login for Business** &gt; **Configurations**:</div><div>![](https://support2.chatarchitect.com/uploads/images/gallery/2026-04/embedded-image-yl3xedik.png)</div><div>Click the **Create from template** button and create a configuration from the **WhatsApp Embedded Signup Configuration With 60 Expiration Token** template. This will generate a configuration for the most commonly used permissions and access levels.</div><div>Alternatively, you create a custom configuration. To do this, in the **Configurations** panel, click the **Create configuration** button and provide a name that will help you differentiate the custom configuration from any others you may create in the future. When completing the flow, be sure to select the **WhatsApp Embedded Signup** login variation:</div><div>![](https://support2.chatarchitect.com/uploads/images/gallery/2026-04/embedded-image-dt6zpe3b.png)</div><div>Select your products you want to onboard for this configuration.</div><div>![](https://support2.chatarchitect.com/uploads/images/gallery/2026-04/embedded-image-qlqmpjeg.png)</div><div>When choosing assets and permissions, select only those assets and permissions that you will actually need from your business customers. Assets that are already selected are added by default.</div><div>For example, if you select the **Catalogs** asset but don't actually need access to customer catalogs, your customers will likely abandon the flow at the catalog selection screen and ask you for clarification.</div><div>When you complete the configuration flow, capture your configuration ID, as you will need it in the next step.</div><div>![](https://support2.chatarchitect.com/uploads/images/gallery/2026-04/embedded-image-qjgnsbex.png)</div><div id="bkmrk-step-3%3A-add-embedded"><div id="bkmrk-step-3%3A-add-embedded-1"><div>### Step 3: Add Embedded Signup to your website

</div></div></div><div>Add the following HTML and JavaScript code to your website. This is the complete code needed to implement Embedded Signup. Each portion of the code will be explained in detail below.</div><div id="bkmrk-session-logging-mess"><div id="bkmrk-session-logging-mess-1"><div>#### Session logging message event listener

</div></div></div><div>This portion of the code creates a message event listener that captures the following critical information:</div><span>The business customer's newly generated asset IDs, if they successfully completed the flow</span><span>The name of the screen they abandoned, if they abandoned the flow</span><span>An error ID, if they encountered an error and used the flow to report it</span><div>```
// Session logging message event listener
window.addEventListener('message', (event) => {
  if (!event.origin.endsWith('facebook.com')) return;
  try {
    const data = JSON.parse(event.data);
    if (data.type === 'WA_EMBEDDED_SIGNUP') {
      console.log('message event: ', data); // remove after testing
      // your code goes here
    }
  } catch {
    console.log('message event: ', event.data); // remove after testing
    // your code goes here
  }
});

```

</div><div>This information will be sent in a message event object to the window that spawned the flow and will be assigned to the data constant. **Add your own custom code to the try-catch statement that can send this object to your server.** The object structure will vary based on flow completion, abandonment, or error reporting, as described below.</div><div>**Successful flow completion structure:**</div><div>On the final screen, both clicking **Finish** and closing the popup (for example, by clicking the X button) are considered successful onboarding. In both scenarios, the exchangeable token code and the session info object containing the customer's asset IDs will be returned. Exiting on the final screen is not considered a cancel event.</div><div><div>```
{
  data: {
    phone_number_id: '<CUSTOMER_BUSINESS_PHONE_NUMBER_ID>',
    waba_id: '<CUSTOMER_WABA_ID>',
    business_id: '<CUSTOMER_BUSINESS_PORTFOLIO_ID>',

    <!-- only included if customer selected ad accounts -->
    ad_account_ids: ['<CUSTOMER_AD_ACCOUNT_ID_1>', '<CUSTOMER_AD_ACCOUNT_ID_2>'],

    <!-- only included if customer selected Facebook Pages -->
    page_ids: ['<CUSTOMER_PAGE_ID_1>', '<CUSTOMER_PAGE_ID_2>'],

    <!-- only included if customer selected datasets -->
    dataset_ids: ['<CUSTOMER_DATASET_ID_1>', '<CUSTOMER_DATASET_ID_2>'],

    <!-- only included if customer selected catalogs -->
    catalog_ids: ['<CUSTOMER_CATALOG_ID_1>', '<CUSTOMER_CATALOG_ID_2>'],

    <!-- only included if customer selected Instagram accounts -->
    instagram_account_ids: ['<CUSTOMER_IG_ACCOUNT_ID_1>', '<CUSTOMER_IG_ACCOUNT_ID_2>'],

    <!-- only included for multi-WABA flows -->
    waba_ids: ['<CUSTOMER_WABA_ID_1>', '<CUSTOMER_WABA_ID_2>']
  },
  type: 'WA_EMBEDDED_SIGNUP',
  event: '<FLOW_FINISH_TYPE>',
}
```

</div></div><div><table><thead><tr><th><span>Placeholder </span></th><th><span>Description </span></th><th><span>Example value </span></th></tr></thead><tbody><tr><td><div><div>`<CUSTOMER_BUSINESS_PHONE_NUMBER_ID>`</div></div></td><td><div><div>The business customer's business phone number ID</div></div></td><td><div><div>`106540352242922`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_WABA_ID>`</div></div></td><td><div><div>The business customer's WhatsApp Business Account ID.</div></div></td><td><div><div>`524126980791429`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_BUSINESS_PORTFOLIO_ID>`</div></div></td><td><div><div>The business customer's business portfolio ID.</div></div></td><td><div><div>`2729063490586005`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_AD_ACCOUNT_ID>`</div></div></td><td><div><div>Only included if the customer selected ad accounts during the flow. The business customer's ad account ID.</div></div></td><td><div><div>`4052175343162067`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_PAGE_ID>`</div></div></td><td><div><div>Only included if the customer selected Facebook Pages during the flow. The business customer's Facebook Page ID.</div></div></td><td><div><div>`1791141545170328`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_DATASET_ID>`</div></div></td><td><div><div>Only included if the customer selected datasets during the flow. The business customer's dataset ID.</div></div></td><td><div><div>`524126980791429`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_CATALOG_ID>`</div></div></td><td><div><div>Only included if the customer selected catalogs during the flow. The business customer's catalog ID.</div></div></td><td><div><div>`8827498273649182`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_IG_ACCOUNT_ID>`</div></div></td><td><div><div>Only included if the customer selected Instagram accounts during the flow. The business customer's Instagram account ID.</div></div></td><td><div><div>`1749204838281942`</div></div></td></tr><tr><td><div><div>`<CUSTOMER_WABA_ID>` (in `waba_ids` array)</div></div></td><td><div><div>Only included for multi-WABA flows. Array of the business customer's WhatsApp Business Account IDs.</div></div></td><td><div><div>`524126980791429`</div></div></td></tr><tr><td><div><div>`<FLOW_FINISH_TYPE>`</div></div></td><td><div><div>Indicates the customer successfully completed the flow.</div><div>**Possible Values:**</div><span>`FINISH`: Indicates successful completion of [Cloud API flow](/books/meta-whatsapp/page/customizing-the-default-flow-developer-documentation).</span><span>`FINISH_ONLY_WABA`: Indicates user completed flow [without a phone number](/books/meta-whatsapp/page/bypassing-the-phone-number-addition-screen-developer-documentation).</span><span>`FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING`: Indicates user completed flow [with a WhatsApp business app number](/books/meta-whatsapp/page/onboarding-whatsapp-business-app-users-aka-coexistence-developer-documentation).</span><span>`FINISH_OBO_MIGRATION`: Indicates user completed an on-behalf-of migration flow.</span><span>`FINISH_GRANT_ONLY_API_ACCESS`: Indicates user completed a grant-only API access flow.</span><span>`ERROR`: Indicates the user encountered an error during the flow.</span></div></td><td><div><div>`FINISH`</div></div></td></tr></tbody></table>

</div><div>Abandoned flow structure:</div><div><div>```
{
  data: {
    current_step: '<CURRENT_STEP>',
  },
  type: 'WA_EMBEDDED_SIGNUP',
  event: 'CANCEL',
}
```

</div></div><div><table><thead><tr><th><span>Placeholder </span></th><th><span>Description </span></th><th><span>Example value </span></th></tr></thead><tbody><tr><td><div><div>`<CURRENT_STEP>`</div></div></td><td><div><div>Indicates which screen the business customer was viewing when they abandoned the flow. See [Embedded Signup flow errors](/documentation/business-messaging/whatsapp/embedded-signup/errors) for a description of each step.</div></div></td><td><div><div>`PHONE_NUMBER_SETUP`</div></div></td></tr></tbody></table>

</div><div>User reported errors</div><div><div>```
{
  data: {
    error_message: '<ERROR_MESSAGE>',
    error_code: '<ERROR_CODE>',
    session_id: '<SESSION_ID>',
    timestamp: '<TIMESTAMP>',
  },
  type: 'WA_EMBEDDED_SIGNUP',
  event: 'CANCEL',
}
```

</div></div><div><table><thead><tr><th><span>Placeholder </span></th><th><span>Description </span></th><th><span>Example value </span></th></tr></thead><tbody><tr><td><div><div>`<ERROR_MESSAGE>`</div></div></td><td><div><div>The error description text displayed to the business customer in the Embedded Signup flow. See [Embedded Signup flow errors](/documentation/business-messaging/whatsapp/embedded-signup/errors) for a list of common errors.</div></div></td><td><div><div>Your verified name violates WhatsApp guidelines. Please edit your verified name and try again.</div></div></td></tr><tr><td><div><div>`<ERROR_CODE>`</div></div></td><td><div><div>Error code. Include this value if you contact support.</div></div></td><td><div><div>`524126`</div></div></td></tr><tr><td><div><div>`<SESSION_ID>`</div></div></td><td><div><div>Unique session ID generated by Embedded Signup. Include this ID if you contact support.</div></div></td><td><div><div>`f34b51dab5e0498`</div></div></td></tr><tr><td><div><div>`<TIMESTAMP>`</div></div></td><td><div><div>Unix timestamp indicating when the business customer used Embedded Signup to report the error. Include this value if you are contacting support.</div></div></td><td><div><div>`1746041036`</div></div></td></tr></tbody></table>

</div><div>Parse this object on your server to extract and capture the customer's phone number ID and WABA ID, or to determine which screen they abandoned. See [Abandoned flow screens](/documentation/business-messaging/whatsapp/embedded-signup/errors#abandoned-flow-screens) for a list of possible `<CURRENT_STEP>` values and the screens they correspond to.</div><div>Note that the try-catch statement in the code above has two statements that can be used for testing purposes:</div><div>```
console.log('message event: ', data); // remove after testing

console.log('message event: ', event.data); // remove after testing

```

</div><div>These statements just dump the returned phone number and WABA IDs, or the abandoned screen string, to the JavaScript console. You can leave this code in place and keep the console open to easily see what gets returned when you are testing the flow, but you should remove them when you are done testing.</div><div id="bkmrk-response-callback"><div id="bkmrk-response-callback-1"><div>#### Response callback

</div></div></div><div>Whenever a business customer successfully completes the Embedded Signup flow, we will send an exchangeable token code in a [JavaScript response<span>?</span>](https://l.facebook.com/l.php?u=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FAPI%2FResponse&h=AT7nB7RrhSvturBcaku2bbnsOUv9cPFSLRQAO1DJNe6zogToTX_p4GISb8epgn6o6OyE7li81jcp3lLzodFFePdsUBoxi1yMR_4b2G-lZWM7Lx0EpZqTcceMS4D_kZaWwZ6mHzPYBPy_QitYQtjeLw) to the window that spawned the flow.</div><div>```
// Response callback
const fbLoginCallback = (response) => {
  if (response.authResponse) {
    const code = response.authResponse.code;
    console.log('response: ', code); // remove after testing
    // your code goes here
  } else {
    console.log('response: ', response); // remove after testing
    // your code goes here
  }
}

```

</div><div>The callback function assigns the exchangeable token code to a `code` constant.</div><div>**Add your own, custom code to the if-else statement that sends this code to your server** so you can later exchange it for the customer's business token when you [onboard the business customer](#bkmrk-onboarding-business--1).</div><div>Note that the if-else statement in the code above has two statements that can be used for testing purposes:</div><div>```
console.log('response: ', code); // remove after testing

console.log('response: ', response); // remove after testing

```

</div><div>These statements just dump the code or the raw response to the JavaScript console. You can leave this code in place and keep the console open to easily see what gets returned when you are testing the flow, but you should remove them when you are done testing.</div><div id="bkmrk-launch-method-and-ca"><div id="bkmrk-launch-method-and-ca-1"><div>#### Launch method and callback registration

</div></div></div><div>This portion of the code defines a method which can be called by an `onclick` event that registers the response callback from the previous step and launches the Embedded Signup flow.</div><div>Add your configuration ID here.</div><div>```
// Launch method and callback registration
const launchWhatsAppSignup = () => {
  FB.login(fbLoginCallback, {
    config_id: '<CONFIGURATION_ID>', // your configuration ID goes here
    response_type: 'code',
    override_default_response_type: true,
    extras: {
      setup: {},
    }
  });
}

```

</div><div id="bkmrk-launch-button"><div id="bkmrk-launch-button-1"><div>#### Launch button

</div></div></div><div>This portion of the code defines a button that calls the launch method from the previous step when clicked by the business customer.</div><div><div>```
<!-- Launch button -->
<button onclick="launchWhatsAppSignup()" style="background-color: #1877f2; border: 0; border-radius: 4px; color: #fff; cursor: pointer; font-family: Helvetica, Arial, sans-serif; font-size: 16px; font-weight: bold; height: 40px; padding: 0 24px;">Login with Facebook</button>
```

</div></div><div id="bkmrk-testing"><div id="bkmrk-testing-1"><div>### Testing

</div></div></div><div>Once you have completed all of the implementation steps above, you should be able to test the flow by simulating a business customer while using your own Meta credentials. Anyone who you have added as an admin or developer on your app (in the **App Dashboard** &gt; **App roles** &gt; **Roles** panel) can also begin testing the flow, using their own Meta credentials.</div><div id="bkmrk-onboarding-business-"><div id="bkmrk-onboarding-business--1"><div>### Onboarding business customers

</div></div></div><div>Embedded Signup generates assets for your business customers, and grants your app access to those assets. However, you still need to make a series of API calls to fully onboard new business customers who have completed the flow.</div><div>The API calls you must make to onboard customers are different for Solution Partners and Tech Providers/Tech Partners.</div><span>[Onboarding customers as a Solution Partner](/books/meta-whatsapp/page/onboarding-business-customers-as-a-solution-partner-developer-documentation)</span><span>[Onboarding customers as a Tech Provider](/books/meta-whatsapp/page/onboarding-business-customers-as-a-tech-provider-or-tech-partner-developer-documentation)</span></div>