# WhatsApp Tech Provider program integration guide

By the end of this guide, your customers will onboard to the WhatsApp Business Platform directly in your application using Embedded Signup. You'll create a Meta app and become a WhatsApp Tech Provider, add the Twilio Partner Solution, and integrate Embedded Signup into your application.

**Note**: If you've already integrated Embedded Signup into your application and registered your customer's first WhatsApp sender, see [Register WhatsApp senders](/docs/whatsapp/isv/register-senders) to register additional senders.

## Prerequisites

Complete the following prerequisites before becoming a Tech Provider and integrating your application with WhatsApp and Twilio.

* **Create a Meta business portfolio.**

  If you don't have a Meta business portfolio, go to [business.facebook.com](https://business.facebook.com/business/loginpage) and create a Meta Business Suite account using your Facebook credentials.
* **Register a WhatsApp sender for your ISV using Self Sign-up.**

  Create a WhatsApp sender for your company using [WhatsApp Self Sign-up](/docs/whatsapp/self-sign-up). Creating a WhatsApp sender makes your Meta Business Portfolio eligible for verification by Meta, and allows you to create templates and send or receive messages on WhatsApp for your own company.
* **Turn on two-factor authentication and complete business verification.**

  To participate in the Tech Provider program you need to turn on two-factor authentication (2FA) and complete business verification in your Meta Business Manager settings.

  * To turn on 2FA authentication for your Meta business, follow the steps in [Turn on the two-factor authentication requirement in your business portfolio](https://www.facebook.com/business/help/280940009201586?id=199156230960298).
  * To complete business verification on Meta, follow the steps in [How to verify your business on Meta](https://www.facebook.com/business/help/2058515294227817?id=180505742745347). If your business isn't eligible for verification, then complete [WhatsApp Self Sign-up](/docs/whatsapp/self-sign-up) for your company first.
    Meta's processing time for business verification varies by region and can take several weeks. Start the verification process early to avoid onboarding delays.

## Part 1: Become a Tech Provider

Register as a Meta Developer, create and configure your app, and submit your app for review.

### Register as a Meta Developer

If you haven't created a Meta app before, you need to register as a Meta Developer. For more information, see Meta's [Register as a Meta Developer](https://developers.facebook.com/docs/development/register) documentation.

### Create a Meta app

Create a new Meta app. Don't reuse an existing app.

1. Log in to your Meta Developers account.
2. On the [Apps](https://developers.facebook.com/apps/) page, click **Create App**.
3. Under **App details**, enter the **App name** and an **App contact email**.

   Your Meta app name and business portfolio name are visible to your customers when they go through Embedded Signup. Don't include Meta's trademarks, such as "WhatsApp", in the app name.
4. Under **Use cases**, select **Other**.
5. Under **Type**, select **Business**.
6. Under **Details**, validate that the **app name** and **app contact email** are correct, and select your company's **Business portfolio**.
7. Click **Create app**.

You end up at the App Dashboard for your new app.

### Add app details

1. In the App Dashboard, go to **App settings** > **Basic**.
2. Add the following information:

   * Your App Icon, which can be your company's logo. Your customers see the icon when onboarding to WhatsApp.
     * Don't use any Meta logos or trademarks on the icon. For example, don't use "WA" or "WhatsApp".
   * A URL to your company's privacy policy. Your customers can access the link when onboarding to WhatsApp.
   * A category that best represents your app or business.
3. Click **Add Platform**.
4. Specify the platform you're using. Ignore the testing instructions section.
5. Save your changes.

### Add the WhatsApp product to your app

Add WhatsApp to your app.

1. In the App Dashboard, find the **WhatsApp** card and click **Set Up**.

   #### Help! I don't see a WhatsApp card.

   WhatsApp [isn't available in certain regions](https://help.twilio.com/articles/360051177134). You must access the Meta App Dashboard from a region where WhatsApp is supported.
2. Complete the flow until you get to the **Quickstart** panel.

### Onboard as a Tech Provider

1. In the App Dashboard, go to **WhatsApp** > **Quickstart**.
2. Under **Scale your Business**, in the **Become a Tech Provider** card, click **Start onboarding**.
3. Read and accept Meta's [Tech Provider Terms](https://www.facebook.com/legal/BM-tech-provider-terms) and any other associated terms from Meta.
4. On the next screen, select **Independent Tech Provider** and click **Start onboarding**.

The **Quickstart** > **Onboarding** panel guides you through the rest of the process to become a Tech Provider.

To return to the **Quickstart** > **Onboarding** panel anytime during onboarding, follow these steps:

1. In the App Dashboard, go to **WhatsApp** > **Quickstart**.
2. Under **Scale your Business**, in the **Become a Tech Provider** card, click **Start onboarding** or **Continue onboarding**.

### Review your app settings

Review your app settings and provide any missing information.

1. In the **Quickstart** > **Onboarding** panel, find the Review your app settings row and click **Review app settings**.
2. Confirm that the information you supplied is accurate and update if necessary.

### Record your screen for app review

As part of the App Review process you need to provide screen recordings that show creating a message template and sending a message from your app to a WhatsApp number.

To view information about creating videos for app review, go to the **Quickstart** > **Onboarding** panel, find the Record video documentation row and click **Record video**. Note that the **Record video** button provides only information and doesn't record anything for you. You'll need to make the recordings yourself.

You must record your screen (no audio) showing the following actions:

* To request the `whatsapp_business_messaging` permission, send a WhatsApp message from your app to a WhatsApp number. The recording must show your app sending the message and the WhatsApp interface (either web or mobile app) receiving the message.
* To request the `whatsapp_business_management` permission, create a WhatsApp template for your use case.

You can record your screen using one of the following methods:

* With the Twilio Console using the [Content Template Builder](/docs/content/overview#content-template-builder). If you use the Twilio Console, you can use the account where you onboarded your company's brand using [WhatsApp Self Sign-up](/docs/whatsapp/self-sign-up).
* Within Meta's WhatsApp Manager.

Save the recording files for upload in a later step.

### Select access permissions

1. In the App Dashboard, go to **App Review** > **Permissions and Features**.
2. Request advanced access for the `whatsapp_business_messaging` and `whatsapp_business_management` permissions.

   1. In the list of permissions and features, search for the permission.
   2. Click **Request advanced access**.

   **Note**: The `public_profile` permission is granted automatically when you create your Meta app.
3. Click **Continue request**.

   The **App Review** > **Requests** page opens.

### Prepare and submit for App Review

You can work on your App Review submission and return to edit it at any time before submission.

1. In the App Dashboard, go to **App Review** > **Requests**.
2. Review the list of permissions under **New requests**. You should have `whatsapp_business_messaging` and `whatsapp_business_management`.
3. Click **Next**.

The checklist interface for App Review requirements opens. **Verification** and **App settings** should be marked as done, since you completed them in previous steps.

#### Answer allowed usage and data handling questions

> \[!WARNING]
>
> Neither Twilio nor Meta can provide guidance on answering data handling questions for your organization. Consult legal, policy, and data handling experts within your organization for guidance on how to answer these questions.

1. In the App Dashboard, go to **App Review** > **Requests**.
2. Click **Next** to open your in-progress submission.
3. In the **Data handling questions** card, click the right arrow icon and provide all of the requested information.

   For answers to frequently asked questions about the data handling questions process, see [Meta's Data Handling Questions FAQs](https://developers.facebook.com/docs/resp-plat-initiatives/data-handling-questions/faqs).
4. In the card asking **How will this app use `whatsapp_business_messaging`?**, click the right arrow icon and provide all of the requested information, including the screen recording you created in [Record your screen for app review](#record-your-screen-for-app-review).
5. In the card asking **How will this app use `whatsapp_business_management`?**, click the right arrow icon and provide all of the requested information, including the screen recording you created in [Record your screen for app review](#record-your-screen-for-app-review).
6. Click **Next** or **Back to submission**.

Your answers are saved and you can return to edit them anytime before submitting for App Review.

### Add reviewer instructions

1. In the App Dashboard, go to **App Review** > **Requests**.
2. Click **Next** to open your in-progress submission.
3. Expand the **Reviewer instructions** card and click **Provide reviewer instructions**.

> \[!NOTE]
>
> If you're prompted to add a platform, go back and complete the steps in the [Add app details](#add-app-details) section.

4. For each platform your application uses, in the box where you're prompted to provide instructions, paste the following text:

   ```text
   We are applying to become a WhatsApp Tech Provider. We will be submitting videos for the whatsapp_business_messaging and whatsapp_business_management permissions.
   ```
5. Click **Done**.

### Submit for App Review

When all the App Review checklist items are marked done, you can submit for App Review.

1. In the App Dashboard, go to **App Review** > **Requests**.
2. Click **Next** to open your in-progress submission.
3. Make sure that all the checklist items are marked as done.
4. Click **Submit for Review**.

After Meta reviews your App, you'll receive an email and an alert in your App Dashboard. To review the submission results, go to **Alerts > Inbox**.

### Complete Access Verification

After Meta approves your app, complete Meta's Access Verification to verify that your business is a Tech Provider.

1. In the App Dashboard, go to **App Settings** > **Basic**.
2. Under **Access verification**, click **Start verification**.
3. Fill out the Access Verification information.
4. Click **Submit**.

Meta typically takes 5 business days to complete Access Verification.

## Part 2: Connect your Meta app to the Twilio Partner Solution

To connect your Meta app, [open a support ticket](https://help.twilio.com) so that Twilio can create a Partner Solution for the app.

1. Go to the Twilio Help Center and create a new support ticket.
   * If your account supports direct tickets, submit the ticket there. Otherwise, create a general ticket through the Help Center.
   * Set the ticket subject to **Part 2: Connect your Meta app to the Twilio Partner Solution**. Twilio will route the ticket to the correct team and send next-step instructions.

For Meta to grant Twilio access to your customers' WhatsApp Business Accounts (WABAs), you must accept the Twilio Partner Solution for your app.

### Submit your Meta app ID to Twilio

1. In the Meta App Dashboard, change **App Mode** to **Live**.\
   Your app must be Live (published) for Twilio to create the Partner Solution. After Twilio submits the Partner Solution request, you can return the mode to **Development** if needed.
2. Copy your Meta **App ID** and include it in the support ticket.
3. Wait 1 to 2 business days for the Channel Operations team to send the Partner Solution request.
   * Twilio will update the support ticket when the request is sent.
   * Meta will also send an email notification.
4. After you receive the notifications, change **App Mode** back to **Development**.

### Accept the Partner Solution request from Twilio

1. In the App Dashboard, go to **WhatsApp** > **Partner Solutions**.
2. To confirm the Twilio Partner Solution request, click **Accept**.
3. Inform Twilio that you accepted the request using the support ticket created.
4. Copy and save the **Partner Solution ID** for use in Part 3 when you add the Embedded Signup code to your application.

### Add the Partner Solution to WABAs for existing customers

If you onboarded customers to WhatsApp using Twilio's WhatsApp Self Sign-up, you currently can't add the Partner Solution to their existing WABAs. Twilio will support this use case in a future release.

* If you haven't previously onboarded customers to WhatsApp using Twilio, go to Part 3.
* To onboard new customers to WhatsApp, complete the integration steps in Part 3.

## Part 3: Complete the technical integration

You'll need to do some additional technical setup within your Meta app before completing integration.

The goal of integration is to implement the following workflow for your customers to onboard to WhatsApp:

1. Your customer chooses a phone number to use on WhatsApp or you assign them a Twilio number automatically.

   > \[!NOTE]
   >
   > Phone number selection or assignment must happen before your customer starts the Embedded Signup flow, so that you can get the full phone number as required later by the Twilio Messaging API Senders resource.
   >
   > The WhatsApp Tech Provider Program supports both Twilio phone numbers and non-Twilio phone numbers on WhatsApp.
2. Your customer clicks **Login with Facebook** in your application to open the Embedded Signup popup.
3. In the popup window, the customer follows the Embedded Signup flow, including the following:

   * Create or select a Meta Business Portfolio.
   * Create a WhatsApp Business Account (WABA).
   * If the customer isn't using a Twilio SMS number assigned by you, then they must verify ownership of their phone number with Meta using a one-time password (OTP) verification.

   The window closes when the customer completes the flow.
4. Your application registers your customer's WhatsApp Sender using the Twilio Messaging API Senders resource and the subaccount credentials assigned to the customer. Your application won't need to call any Meta APIs.

> \[!NOTE]
>
> Meta provides the Embedded Signup flow and might make changes to the flow from time to time. For up-to-date information about Embedded Signup, see Meta's [Embedded Signup documentation](https://developers.facebook.com/docs/whatsapp/embedded-signup/default-flow).

### Get your Configuration ID

Create the login configuration that allows your customers to log in to their Facebook account and select or create their Meta business portfolio and WABA, and then share it with your app and business.

1. In the App Dashboard home page, find the **Facebook Login for Business** card and click **Set Up**.
2. Go to **Configurations**, and click **Create Configuration**.
3. Add a name for your configuration. The name won't be visible to your customers.
4. Click **Next**.
5. For **Login variation**, select **WhatsApp Embedded Signup**.
6. Click **Next**.
7. For **Choose access token**, select **System-user access token** and leave the default token expiration as **60 days**.

   The access token section refers to your Meta Graph API access token. Since you're working with Twilio and won't call Meta's Graph API directly, this setting is not relevant for you.
8. Click **Next**.
9. For **Assets**, make sure **WhatsApp accounts** is selected.
10. Click **Next**.
11. For **Permissions**, make sure the `whatsapp_business_management` permission is selected. Don't include any other permissions.
12. Click **Create**.
13. Copy and save the resulting **Configuration ID** to use later when you add the JavaScript code for Embedded Signup to your application.

### Update login settings on your Meta app

Embedded Signup requires updates to your **Facebook Login for Business** settings.

1. In the App Dashboard, go to **Facebook Login for Business** > **Settings**.
2. Under **Client OAuth settings**, set the following options to **Yes** if they're not already set:

   * Client OAuth login
   * Web OAuth login
   * Enforce HTTPS
   * Embedded Browser OAuth Login
   * Use Strict Mode for redirect URIs
   * Login with the JavaScript SDK
3. Add your application's domains into both **Valid OAuth Redirect URIs** and **Allowed Domains for the JavaScript SDK** fields. These URIs need to be served using HTTPS and can only be static, not dynamic URLs that use a wildcard.

   > \[!NOTE]
   >
   > For security purposes, Meta doesn't allow the Facebook SDK to be loaded on any website not using HTTPS. We recommend using [ngrok](https://ngrok.com/) or a similar tool to expose your localhost externally where it can be served using HTTPS. Alternatively, if your company has a developer environment that uses HTTPS, that would also work.
4. Click **Save changes**.

### Add other developers to your app

When your Meta app's **App Mode** is set to **Development**, only users that have been added to your Meta app can access it.

To add additional developers and testers to your Meta app, follow these steps:

1. In the App Dashboard, go to **App roles** > **Roles**
2. Click **Edit roles in Business Manager**.
3. In the Business Manager interface:
   1. If needed, go to **Users** > **People** and invite people to your Business Portfolio.
   2. Go to **Apps**, click **Assign people** and add the people who need to test your Embedded Signup integration.

### Integrate Embedded Signup into your application

To complete the integration with Meta's Embedded Signup you'll need to do the following:

* Add a **Login with Facebook** button into your application's user interface.
* Use the information returned when your customers complete the Embedded Signup flow and the Senders API to register the user's phone number. You'll create a Twilio subaccount for your customer and then create a WhatsApp Sender resource in that subaccount.

#### Add the "Login with Facebook" button

Meta's Embedded Signup requires the Facebook SDK to be loaded only on the application page where Embedded Signup is surfaced.

1. Add the snippet below after the opening `<body>` tag on the page you intend to add the "Login with Facebook" button. Replace *`APP_ID`* with your App ID.

   ```js
   <script>
     window.fbAsyncInit = function() {
       FB.init({
         // !mark
         appId: 'APP_ID', // Replace with your Meta app ID
         autoLogAppEvents: true,
         xfbml: true,
         version: 'v21.0' // Latest version when this doc was published
        })
     };
   </script>
   <script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js"></script>
   ```
2. Add the following HTML where you want to surface the **Login with Facebook** button. Styles are included to match Meta's style guide.

   ```html
   <button onclick="launchEmbeddedSignup()" 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>
   ```
3. The button added in the previous step triggers the `launchEmbeddedSignup` function as shown in the following example, which opens the Embedded Signup popup window.

   Replace the placeholder values with your [Configuration ID](#get-your-configuration-id) and [Partner Solution ID](#accept-the-partner-solution-request-from-twilio).

   ```js
   // Handle WhatsApp Embedded Signup
   function launchEmbeddedSignup() {
     // Launch Facebook login
     FB.login(
       function (response) {
         // Since you are using Twilio's APIs, you do not need to do anything with the response here.
       },
       {
         // !mark
         config_id: "KEEP_IN_QUOTES_BUT_REPLACE_WITH_YOUR_CONFIG_ID",
         auth_type: "rerequest", // Avoids 'user is already logged' in errors if users click the button again before refreshing the page
         response_type: "code",
         override_default_response_type: true,
         extras: {
           sessionInfoVersion: 3, // Required to get WABA ID
           setup: {
             // !mark
             solutionID: "KEEP_IN_QUOTES_BUT_REPLACE_WITH_YOUR_SOLUTION_ID" // This is the Partner Solution ID
           }
         }
       }
     );
   }
   ```

> \[!NOTE]
>
> Meta provides the Embedded Signup flow and might make changes to the flow from time to time. For up-to-date information about Embedded Signup, see Meta's [Embedded Signup documentation](https://developers.facebook.com/docs/whatsapp/embedded-signup/default-flow).

4. Add a listener to capture the session information that Meta returns when a customers completes the Embedded Signup flow.

   ```js
   // Define session handler
   const embeddedSignupInfoListener = (event) => {
     if (!event.origin.endsWith('facebook.com')) return;
     try {
           const data = JSON.parse(event.data);
           if (data.type === 'WA_EMBEDDED_SIGNUP') {
             
             // if user finishes the Embedded Signup flow
             if (data.event === 'FINISH' || data.event === 'FINISH_ONLY_WABA') {
               const {phone_number_id, waba_id} = data.data;
               console.log('Phone number ID ', phone_number_id, ' WhatsApp business account ID ', waba_id);
         
             // if user cancels the Embedded Signup flow
             } else if (data.event === 'CANCEL') {
               const {current_step} = data.data;
               console.warn('Cancel at ', current_step);

             // if user reports an error during the Embedded Signup flow
             } else if (data.event === 'ERROR') {
               const {error_message} = data.data;
               console.error('error ', error_message);
             }
           }
         } catch {
           console.log('Non JSON Responses', event.data);
         }
   };


   // Listen for Embedded Signup events
   window.addEventListener('message', embeddedSignupInfoListener);


   // When the user navigates away from the page, remove the event listener
   window.addEventListener('beforeunload', () => 
     window.removeEventListener('message', embeddedSignupInfoListener)
   );
   ```

#### Test the Embedded Signup flow

Test the Embedded Signup flow in your application using a Meta business portfolio you create for that purpose.

When you test the Embedded Signup flow, Meta doesn't allow you to select the Meta business portfolio that you used to create your Meta app within the Embedded Signup flow.

We recommend creating an additional Meta business portfolio, for example "MyCompany Test", using accurate business details. To avoid Meta's phone number and WABA limit restrictions when testing, we also recommend submitting your test business portfolio for business verification.

> \[!NOTE]
>
> When your Partner Solution (`solutionID`) is working correctly, you'll notice that the Embedded Signup flow displays a message that states your company is working with Twilio to enable your customers on WhatsApp. Meta requires that this information displays and it can't be removed.

#### Update Embedded Signup for Twilio phone numbers

If you're purchasing and assigning Twilio SMS-capable phone numbers for your customers to use with WhatsApp, you need to update the default Embedded Signup configuration.

The default Embedded Signup flow is as follows:

1. Create or select their Meta Business Portfolio.
2. Create their WhatsApp Business Account (WABA).
3. Enter a phone number and their WhatsApp Display Name.
4. Verify phone number ownership by entering a one-time passcode (OTP) sent via SMS or a voice call.

If you've purchased Twilio SMS-capable phone numbers for your customers to use with WhatsApp, it's against Twilio policy to display OTPs within your account. As a result, Twilio's Senders API handles steps 3 and 4 automatically when you make the API request to create the WhatsApp Sender, and you need to turn off those steps within Embedded Signup.

If you've purchased Twilio voice-only phone numbers for your customers to use with WhatsApp, you need to [configure the phone number so it can receive the OTP via voice call](/docs/whatsapp/isv/register-senders#using-the-senders-api).

If you're using a combination of Twilio SMS-capable phone numbers, Twilio voice-only numbers, and non-Twilio numbers, then you need to configure Embedded Signup conditionally based on the type of phone number the customer chooses.

To configure Embedded Signup to skip the steps to provide a phone number, update your `FB.login` call to include `featureType: 'only_waba_sharing'`. For example:

```js {title="Embedded Signup: Only WABA sharing (Skip phone number screens)"}
// !focus(15:18)
// Handle WhatsApp Embedded Signup
function launchEmbeddedSignup() {
  // Launch Facebook login
  FB.login(
    function (response) {
      // Since you are using Twilio's APIs, you do not need to do anything with the response here.
    },
    {
      config_id: "KEEP_IN_QUOTES_BUT_REPLACE_WITH_YOUR_CONFIG_ID",
      auth_type: "rerequest", // Avoids "user is already logged" in errors if users click the button again before refreshing the page
      response_type: "code",
      override_default_response_type: true,
      extras: {
        sessionInfoVersion: 3, // Required to get WABA ID
        // set the following "featureType" to 'only_waba_sharing'
        // if and only if using a Twilio SMS-capable number, otherwise
        // do not include it or set it to null
        // !mark
        featureType: 'only_waba_sharing',
        setup: {
          solutionID: "KEEP_IN_QUOTES_BUT_REPLACE_WITH_YOUR_SOLUTION_ID", // This is the Partner Solution ID
        }
      }
    }
  );
}
```

> \[!NOTE]
>
> Meta allows you to add in details about the customer's business if you've already collected that information. Pre-filled data can speed up the onboarding process for your customers.
>
> Customers can still edit the data that you prefill, if necessary.
>
> Review Meta's documentation about [pre-filling screens](https://developers.facebook.com/docs/whatsapp/embedded-signup/pre-filled-data) and make sure you test any changes.

#### Collect the phone number

Meta returns only the `phone_number_id` when the user completes the Embedded Signup flow:

```js
const embeddedSignupInfoListener = (event) => {
  if (!event.origin.endsWith('facebook.com')) return;
  try {
        const data = JSON.parse(event.data);
        if (data.type === 'WA_EMBEDDED_SIGNUP') {
          
          // if user finishes the Embedded Signup flow
          if (data.event === 'FINISH' || data.event === 'FINISH_ONLY_WABA') {
            const {phone_number_id, waba_id} = data.data;
            console.log('Phone number ID ', phone_number_id, ' WhatsApp business account ID ', waba_id);
      
          // if user cancels the Embedded Signup flow
          } else if (data.event === 'CANCEL') {
            const {current_step} = data.data;
            console.warn('Cancel at ', current_step);

          // if user reports an error during the Embedded Signup flow
          } else if (data.event === 'ERROR') {
            const {error_message} = data.data;
            console.error('error ', error_message);
          }
        }
      } catch {
        console.log('Non JSON Responses', event.data);
      }
};
```

The Twilio Senders API requires a phone number in [E.164](/docs/glossary/what-e164) format. If you allow your customers to bring their own phone number to register on WhatsApp, you must collect it from your customers separately from the Embedded Signup flow. You can collect the number before launching the Embedded Signup flow or after the customer completes the Embedded Signup flow, but before making the call to the Twilio Senders API.

Once you have the WABA ID from the `embeddedSignupInfoListener` function and the phone number in E.164 format, **pass these parameters to your backend** to register the WhatsApp sender.

> \[!CAUTION]
>
> Don't make any of the following or other Twilio API calls involving a Twilio `AuthToken` on the front end of your application, where you implemented the Embedded Signup feature.

#### Create a subaccount for each customer

Create a subaccount for each new new customer using the [Twilio Accounts API](/docs/iam/api/subaccounts). A single Twilio account or subaccount is mapped to a single WABA.

When your customer onboards to WhatsApp for the first time, they will create a new WABA as part of the Embedded Signup flow. Every customer WABA needs to be connected to a separate Twilio subaccount.

Your customers should reuse their WABA when onboarding additional WhatsApp senders.

> \[!WARNING]
>
> Each WABA must be mapped to a single Twilio account or subaccount. You must keep track of every customer business or brand and connect each one to a dedicated Twilio subaccount. WhatsApp doesn't allow senders from different businesses to be registered in the same WABA.

If you're not already familiar with Twilio subaccounts, you can learn more in the **[Accounts API docs](/docs/iam/api/subaccounts)**.

1. **Create a subaccount** using the example below if you don't already have a subaccount for this customer. Make sure to replace the `FriendlyName` with your customer's company name. Use your main Twilio account (e.g., parent account) credentials to make this request.

   Create a subaccount

   ```js
   // Download the helper library from https://www.twilio.com/docs/node/install
   const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";

   // Find your Account SID and Auth Token at twilio.com/console
   // and set the environment variables. See http://twil.io/secure
   const accountSid = process.env.TWILIO_ACCOUNT_SID;
   const authToken = process.env.TWILIO_AUTH_TOKEN;
   const client = twilio(accountSid, authToken);

   async function createAccount() {
     const account = await client.api.v2010.accounts.create({
       friendlyName: "Owl, Inc.",
     });

     console.log(account.authToken);
   }

   createAccount();
   ```

   ```python
   # Download the helper library from https://www.twilio.com/docs/python/install
   import os
   from twilio.rest import Client

   # Find your Account SID and Auth Token at twilio.com/console
   # and set the environment variables. See http://twil.io/secure
   account_sid = os.environ["TWILIO_ACCOUNT_SID"]
   auth_token = os.environ["TWILIO_AUTH_TOKEN"]
   client = Client(account_sid, auth_token)

   account = client.api.v2010.accounts.create(friendly_name="Owl, Inc.")

   print(account.auth_token)
   ```

   ```csharp
   // Install the C# / .NET helper library from twilio.com/docs/csharp/install

   using System;
   using Twilio;
   using Twilio.Rest.Api.V2010;
   using System.Threading.Tasks;

   class Program {
       public static async Task Main(string[] args) {
           // Find your Account SID and Auth Token at twilio.com/console
           // and set the environment variables. See http://twil.io/secure
           string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
           string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");

           TwilioClient.Init(accountSid, authToken);

           var account = await AccountResource.CreateAsync(friendlyName: "Owl, Inc.");

           Console.WriteLine(account.AuthToken);
       }
   }
   ```

   ```java
   // Install the Java helper library from twilio.com/docs/java/install

   import com.twilio.Twilio;
   import com.twilio.rest.api.v2010.Account;

   public class Example {
       // Find your Account SID and Auth Token at twilio.com/console
       // and set the environment variables. See http://twil.io/secure
       public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID");
       public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN");

       public static void main(String[] args) {
           Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
           Account account = Account.creator().setFriendlyName("Owl, Inc.").create();

           System.out.println(account.getAuthToken());
       }
   }
   ```

   ```go
   // Download the helper library from https://www.twilio.com/docs/go/install
   package main

   import (
   	"fmt"
   	"github.com/twilio/twilio-go"
   	api "github.com/twilio/twilio-go/rest/api/v2010"
   	"os"
   )

   func main() {
   	// Find your Account SID and Auth Token at twilio.com/console
   	// and set the environment variables. See http://twil.io/secure
   	// Make sure TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN exists in your environment
   	client := twilio.NewRestClient()

   	params := &api.CreateAccountParams{}
   	params.SetFriendlyName("Owl, Inc.")

   	resp, err := client.Api.CreateAccount(params)
   	if err != nil {
   		fmt.Println(err.Error())
   		os.Exit(1)
   	} else {
   		if resp.AuthToken != nil {
   			fmt.Println(*resp.AuthToken)
   		} else {
   			fmt.Println(resp.AuthToken)
   		}
   	}
   }
   ```

   ```php
   <?php

   // Update the path below to your autoload.php,
   // see https://getcomposer.org/doc/01-basic-usage.md
   require_once "/path/to/vendor/autoload.php";

   use Twilio\Rest\Client;

   // Find your Account SID and Auth Token at twilio.com/console
   // and set the environment variables. See http://twil.io/secure
   $sid = getenv("TWILIO_ACCOUNT_SID");
   $token = getenv("TWILIO_AUTH_TOKEN");
   $twilio = new Client($sid, $token);

   $account = $twilio->api->v2010->accounts->create([
       "friendlyName" => "Owl, Inc.",
   ]);

   print $account->authToken;
   ```

   ```ruby
   # Download the helper library from https://www.twilio.com/docs/ruby/install
   require 'twilio-ruby'

   # Find your Account SID and Auth Token at twilio.com/console
   # and set the environment variables. See http://twil.io/secure
   account_sid = ENV['TWILIO_ACCOUNT_SID']
   auth_token = ENV['TWILIO_AUTH_TOKEN']
   @client = Twilio::REST::Client.new(account_sid, auth_token)

   account = @client
             .api
             .v2010
             .accounts
             .create(friendly_name: 'Owl, Inc.')

   puts account.auth_token
   ```

   ```bash
   # Install the twilio-cli from https://twil.io/cli

   twilio api:core:accounts:create \
      --friendly-name "Owl, Inc."
   ```

   ```bash
   curl -X POST "https://api.twilio.com/2010-04-01/Accounts.json" \
   --data-urlencode "FriendlyName=Owl, Inc." \
   -u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
   ```

   ```json
   {
     "auth_token": "auth_token",
     "date_created": "Thu, 30 Jul 2015 20:00:00 +0000",
     "date_updated": "Thu, 30 Jul 2015 20:00:00 +0000",
     "friendly_name": "Owl, Inc.",
     "owner_account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
     "sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
     "status": "active",
     "subresource_uris": {
       "available_phone_numbers": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/AvailablePhoneNumbers.json",
       "calls": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls.json",
       "conferences": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Conferences.json",
       "incoming_phone_numbers": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/IncomingPhoneNumbers.json",
       "notifications": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Notifications.json",
       "outgoing_caller_ids": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/OutgoingCallerIds.json",
       "recordings": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Recordings.json",
       "transcriptions": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Transcriptions.json",
       "addresses": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Addresses.json",
       "signing_keys": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/SigningKeys.json",
       "connect_apps": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/ConnectApps.json",
       "sip": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/SIP.json",
       "authorized_connect_apps": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/AuthorizedConnectApps.json",
       "usage": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Usage.json",
       "keys": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Keys.json",
       "applications": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Applications.json",
       "short_codes": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/SMS/ShortCodes.json",
       "queues": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Queues.json",
       "messages": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Messages.json",
       "balance": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Balance.json"
     },
     "type": "Full",
     "uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json"
   }
   ```
2. The newly created subaccount's `AccountSid` and `AuthToken` will be returned in the response. Save this in your database to use for this customer. You will also use these credentials in the next step when calling the Twilio Senders API to register your customer's phone numbers on WhatsApp.

#### Register the WhatsApp sender

Use the [Twilio Senders API](/docs/whatsapp/api/senders) to connect new WABAs to new subaccounts and register phone numbers with WhatsApp.

Create the WhatsApp Sender resource using the Senders API:

1. Use the WABA ID and phone number passed from your frontend and, with the subaccount's Account SID and Auth Token, call the [Twilio Senders API](/docs/whatsapp/api/senders) with the following fields:

   * `sender_id`: provide the phone number that you are registering in E.164 format.
   * `waba_id`: provide the WABA ID if this is the first number for the customer. This will connect it to the subaccount. Note that once a WABA ID has been mapped to a subaccount, it will stay connected unless all WhatsApp senders have been deleted from the account. You don't need to provide it when registering additional senders in the same subaccount.
   * `callback_url`, `callback_method`, `fallback_url`, `fallback_method`, and `status_callback_url`: these webhooks are used for inbound messages and message statuses (not for the sender's status). Note that status callbacks only support HTTP `POST`.
   * `profile.name` is only required when using a Twilio SMS-capable number; otherwise, Twilio will use the one provided by your customer during the Embedded Signup flow and ignore this field. Even when testing, the display name must comply with Meta's [WhatsApp display name guidelines](https://www.facebook.com/business/help/757569725593362).
   * Other fields are optional.

   ```bash
   ## Create Sender
   curl -X "POST" "https://messaging.twilio.com/v2/Channels/Senders" \
     -H "Content-Type: application/json; charset=utf-8" \
     -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" \
     -d $'{
     "sender_id": "whatsapp:+15017122661",
     "configuration": {
       "waba_id": "12345678912345"
     },
     "profile": {
       "address": "101 Spear Street, San Francisco, CA",
       "emails": [
         "support@twilio.com"
       ],
       "vertical": "Other",
       "logo_url": "https://www.twilio.com/logo.png",
       "description": "We\'re excited to see what you build!",
       "about": "Hello! We are Twilio.",
       "name": "Twilio",
       "websites": [
         "https://twilio.com",
         "https://help.twilio.com"
       ]
     },
     "webhook": {
       "callback_method": "POST",
       "callback_url": "https://demo.twilio.com/welcome/sms/reply/"
     }
   }'
   ```

   ```json
   {
       "status": "CREATING",
       "sender_id": "whatsapp:+15017122661",
       "sid": "XEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
       "configuration": {
         "waba_id": "12345678912345"
       },
       "profile": {
         "about": "Hello! This is Twilio's official account.",
         "name": "Twilio",
         "vertical": "Other",
         "websites": [
           {
             "website": "https://twilio.com",
             "label": "Website"
           },
           {
             "website": "https://help.twilio.com",
             "label": "Website"
           }
         ],
         "address": "101 Spear Street, San Francisco, CA",
         "logo_url": "https://www.twilio.com/logo.png",
         "emails": [
           {
             "email": "support@twilio.com",
             "label": "Email"
           }
         ],
         "description": "We're excited to see what you build!"
       },
       "webhook": {
         "callback_method": "POST",
         "callback_url": "https://demo.twilio.com/welcome/sms/reply/"
       },
       "url": "https://messaging.twilio.com/v2/Channels/Senders/XEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
       "properties": null
     }
   ```
2. The Senders API registers WhatsApp senders asynchronously. When you make the `POST` call above to create the WhatsApp Sender resource, the sender's SID is returned. WhatsApp sender SIDs start with `XE`.
3. To check if the WhatsApp sender has been successfully registered and is online, make a request to fetch the WhatsApp sender's current status:

   ```bash
   ## Fetch Sender
   curl -X "GET" "https://messaging.twilio.com/v2/Channels/Senders/XEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
        -H "Content-Type: application/json; charset=utf-8" \
        -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN"
   ```

   ```json
   {
     "status": "ONLINE",
     "sender_id": "whatsapp:+15017122661",
     "sid": "XEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
     "configuration": {
       "waba_id": "12345678912345"
     },
     "profile": {
       "about": "Hello! This is Twilio's official account.",
       "name": "Twilio",
       "vertical": "Other",
       "websites": [
         {
           "website": "https://twilio.com",
           "label": "Website"
         },
         {
           "website": "https://help.twilio.com",
           "label": "Website"
         }
       ],
       "address": "101 Spear Street, San Francisco, CA",
       "logo_url": "https://www.twilio.com/logo.png",
       "emails": [
         {
           "email": "support@twilio.com",
           "label": "Email"
         }
       ],
       "description": "We're excited to see what you build!"
     },
     "webhook": {
       "callback_method": "POST",
       "callback_url": "https://demo.twilio.com/welcome/sms/reply/"
     },
     "url": "https://messaging.twilio.com/v2/Channels/Senders/XEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
     "properties": {
       "messaging_limit": "1K Customers/24hr",
       "quality_rating": "HIGH"
     }
   }
   ```
4. When the sender's status shows as `ONLINE`, you can use Twilio's APIs to send and receive messages.

Learn how to [register additional WhatsApp senders](/docs/whatsapp/isv/register-senders#register-additional-whatsapp-senders). To troubleshoot WhatsApp sender registration, see [Troubleshooting](/docs/whatsapp/isv/register-senders#troubleshooting).

### Launch into production

It's time to move your application to production and start onboarding your customers to the WhatsApp Business Platform with Twilio.

* At the top of the App Dashboard, set the **App Mode** to **Live**.
* Make sure your production URLs are added to your Meta app in the App Dashboard at **Facebook Login for Business** > Settings. See [Update login settings on your Meta App](#update-login-settings-on-your-meta-app).
* Let the Twilio Channel Operations team know you successfully completed the integration through the support ticket created when you submitted the WhatsApp Tech Provider program request form. Once complete, the team closes the ticket.

## Next steps

* [Register WhatsApp senders](/docs/whatsapp/isv/register-senders)
* [Migrate phone numbers and WhatsApp senders](/docs/whatsapp/migrate-numbers-and-senders)
* Review [Tech Provider FAQs](/docs/whatsapp/isv/tech-provider-program/faq)
* [Create WhatsApp Templates with the Content Template Builder](/docs/content/create-templates-with-the-content-template-builder)
* Learn about [WhatsApp Messaging Limits and Quality Ratings](https://help.twilio.com/articles/360024008153)
