> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tech Provider Integration

> Set up your Meta Tech Provider integration with Plivo as the WhatsApp BSP — architecture, Embedded Signup, and API reference

> [!NOTE]
>
> Register as a Meta Tech Provider, run Embedded Signup with the Solution ID Plivo issues you, then call the Embedded Signup API to onboard each customer's WABA on Plivo.

Meta requires any company that resells WhatsApp Business APIs to register as a [Tech Provider](https://business.whatsapp.com/partners/become-a-partner) and comply with the [Tech Provider Terms](https://www.facebook.com/legal/BM-tech-provider-terms). This guide walks you through the architecture, prerequisites, Meta configuration, Embedded Signup implementation, and API reference for integrating with Plivo as the underlying BSP.

## Overview and architecture

### Three-layer model

WhatsApp's Multi-Partner Solution uses a three-layer model. Meta sits at the top as the platform owner, Plivo operates as the BSP (Business Solution Provider) in the middle, and you operate as the Tech Provider that serves your customers.

| Layer | Role | Responsibilities |
| - | - | - |
| **Meta** | Platform owner | Owns the WhatsApp Cloud API, enforces policies, reviews apps, and manages the Multi-Partner Solution program. |
| **Plivo (BSP)** | Business Solution Provider | Hosts the Cloud API infrastructure, manages credit lines, processes messages, and provides the Embedded Signup API. |
| **You (Tech Provider)** | Reseller / ISV | Builds the customer-facing product, implements Embedded Signup, manages your customers' onboarding, and handles billing to your customers. |

### Multi-Partner Solution — who controls what

| Capability | Plivo (BSP) | You (Tech Provider) | Your customer |
| - | - | - | - |
| Cloud API message sending | Yes | Via Plivo API | - |
| Credit line and billing | Yes | Bills your customer | Pays you |
| WABA creation (Embedded Signup) | Backend processing | Frontend implementation | Completes signup flow |
| Phone number registration | Yes | Triggers via API | Provides phone number |
| Template management | Via API | Via Plivo API | Submits templates |
| Webhook delivery | Configures per WABA | Receives and routes | - |
| Business verification with Meta | - | Must complete own verification | Must complete own verification |

## Prerequisites

### What you need (Tech Provider requirements)

Before you begin the integration, make sure you have the following in place.

| Requirement | Details |
| - | - |
| **Meta Business Portfolio** | A verified Meta Business Portfolio in [Meta Business Suite](https://business.facebook.com/). This is the top-level entity that owns your Meta assets. |
| **Meta Developer Account** | An active account at [developers.facebook.com](https://developers.facebook.com/) linked to your Meta Business Portfolio. |
| **Business Verification with Meta** | Complete [Meta Business Verification](https://www.facebook.com/business/help/1095661473946872) for your business. This typically takes fewer than 5 business days. |
| **Meta App (type: Business)** | Create a Meta App with the type set to **Business** and add the **WhatsApp** product to it. |
| **Facebook Login for Business** | Configure the **WhatsApp Embedded Signup** variant of Facebook Login for Business within your Meta App. This generates the `config_id` you need for the frontend SDK. |
| **App Review submission** | Submit your app for Meta App Review with two screen-recorded demo videos (details below). |
| **Plivo account with WhatsApp enabled** | An active Plivo account with the WhatsApp channel enabled. Contact your Plivo account manager or [Plivo support](https://support.plivo.com/hc/en-us/requests/new) if you do not have this. |

### What Plivo sets up

Once you share your Meta App details, Plivo configures the following on the backend.

| Item | Description |
| - | - |
| **Partner Solution acceptance** | Plivo accepts your Multi-Partner Solution request, linking your Tech Provider app to Plivo's BSP infrastructure. |
| **Credit line configuration** | Plivo extends the Meta credit line to cover conversation charges for WABAs onboarded through your integration. |
| **Webhook endpoint registration** | Plivo registers webhook endpoints so that inbound messages and status callbacks route correctly for each WABA. |
| **API credentials** | Plivo provides an Auth ID and Auth Token scoped to a Tech Provider sub-account. Use these credentials for all Embedded Signup API calls. |
| **Solution ID** | Plivo issues you a Tech Provider Solution ID once your Multi-Partner Solution is accepted. You pass it in `FB.login()` so Meta routes the signup through Plivo's solution. It is not your Meta App ID and not your Config ID. |

> [!WARNING]
>
> Do not begin the Embedded Signup implementation until both your Meta Business Verification and Multi-Partner Solution approval are complete. Starting before both are confirmed can cause onboarding failures that are difficult to reverse.

## Setup steps — Meta configuration

### 3.1 Create a Meta App and add WhatsApp

Follow these steps to create your Meta App and add the WhatsApp product.

1. Go to [developers.facebook.com](https://developers.facebook.com/) and log in with your Meta Developer Account.
2. Click **Create App** and select the app type **Business**.
3. Enter your app name and contact email, then select the Meta Business Portfolio you verified earlier.
4. On the app dashboard, find **WhatsApp** in the product list and click **Set Up**.
5. Confirm that the WhatsApp product appears in the left sidebar of your app dashboard.

> [!NOTE]
>
> You do not need to configure a WhatsApp phone number or WABA in your own app. Your app serves as the container for the Embedded Signup flow that your customers complete.

### 3.2 Create a Multi-Partner Solution

1. In your Meta App dashboard, navigate to **WhatsApp** > **Multi-Partner Solutions**.
2. Click **Create Solution** and give it a descriptive name (for example, "Plivo WhatsApp Integration").
3. Select **Plivo** as the BSP partner from the list.
4. Submit the solution request. Plivo receives a notification and accepts the request on the backend.
5. Wait for confirmation from Plivo that the Multi-Partner Solution is active before proceeding.

### 3.3 Configure Facebook Login for Business

1. In your Meta App dashboard, go to **Facebook Login for Business** in the left sidebar. If you do not see it, click **Add Product** and add it.
2. Click **Settings** under Facebook Login for Business.
3. Under **Login Type**, select **WhatsApp Embedded Signup**.
4. Configure the **Redirect URI** to point to your backend endpoint that handles the OAuth callback.
5. Save your settings and note the **Config ID** generated on this page. You need this value for the frontend JavaScript SDK integration.
6. Under **Permissions**, ensure that `whatsapp_business_messaging` and `whatsapp_business_management` are listed.

> [!NOTE]
>
> The **Config ID** is specific to your Facebook Login for Business configuration. You pass this value to the `FB.login()` call in your frontend code. Do not confuse it with your Meta App ID.

### 3.4 App Review submission

Submit your Meta App for App Review to gain production access. You must request two permissions and provide a screen-recorded demo video for each.

| Permission | Video requirement |
| - | - |
| `whatsapp_business_messaging` | Record a demo showing your app sending a WhatsApp message through the Plivo API on behalf of a test WABA. |
| `whatsapp_business_management` | Record a demo showing your app creating a WhatsApp message template through the Plivo API. |

**Video guidelines:**

* Each video must demonstrate the full end-to-end flow, from your application's UI to the API call and the result.
* Use a real test WABA (not a mock) for the demo.
* Keep each video under 5 minutes.
* Upload the videos as part of the App Review submission at **App Review** > **Requests** in your Meta App dashboard.

> [!NOTE]
>
> Meta typically reviews App Review submissions within 5 business days. You cannot use the Embedded Signup flow in production until Meta approves your app.

## Embedded Signup implementation

### 4.1 Full Embedded Signup flow

The Embedded Signup flow involves coordinated actions between your frontend, your backend, Meta, and Plivo. Here is the complete sequence.

| Step | Actor | Action |
| - | - | - |
| 1 | Your customer | Opens your onboarding page and clicks the "Connect WhatsApp" button. |
| 2 | Your frontend | Calls `FB.login()` with the `config_id`, `response_type: 'code'`, `override_default_response_type: true`, and the Plivo-issued Solution ID in `extras.setup.solutionID`. |
| 3 | Meta | Displays the Embedded Signup dialog where your customer logs in to their Meta account. |
| 4 | Your customer | Creates or selects a Meta Business Portfolio in the signup dialog. |
| 5 | Your customer | Creates a new WABA or selects an existing one. |
| 6 | Your customer | Creates a new WhatsApp business profile and registers a phone number, including OTP verification. |
| 7 | Your customer | Grants the requested permissions (`whatsapp_business_messaging`, `whatsapp_business_management`) and completes the flow. |
| 8 | Meta | Returns an authorization code to your frontend via the `FB.login()` callback. The `sessionInfoVersion: 2` response also includes the WABA ID, phone number ID, and business ID in the `authResponse` extras. |
| 9 | Your frontend | Sends the authorization code and session info (WABA ID, phone number ID, business ID) to your backend. |
| 10 | Your backend | Calls the Meta Graph API `debug_token` endpoint to exchange the code for a validated token and extract the WABA ID, phone number ID, and business ID if not already available from step 8. |
| 11 | Your backend | Calls the Plivo Embedded Signup API (`POST /WhatsApp/EmbeddedSignup/`) with the WABA ID, phone number ID, and business ID to complete the onboarding. |

### 4.2 JavaScript SDK integration

Add the following code to your onboarding page to load the Meta SDK and trigger the Embedded Signup flow.

```html theme={null}
<!DOCTYPE html>
<html>
<head>
  <title>Connect WhatsApp</title>
</head>
<body>
  <!-- Load the Meta JavaScript SDK -->
  <script async defer crossorigin="anonymous"
    src="https://connect.facebook.net/en_US/sdk.js">
  </script>

  <script>
    // Initialize the Facebook SDK
    window.fbAsyncInit = function () {
      FB.init({
        appId: 'YOUR_META_APP_ID',   // Replace with your Meta App ID
        autoLogAppEvents: true,
        xfbml: true,
        version: 'v19.0'
      });
    };

    // Launch Embedded Signup
    function launchEmbeddedSignup() {
      FB.login(
        function (response) {
          if (response.authResponse) {
            const code = response.authResponse.code;

            // sessionInfoVersion: 2 returns extras with WABA and phone details
            const extras = response.authResponse;
            console.log('Authorization code:', code);
            console.log('WABA ID:', extras.waba_id);
            console.log('Phone Number ID:', extras.phone_number_id);
            console.log('Business ID:', extras.business_id);

            // Send these values to your backend
            fetch('/api/whatsapp/embedded-signup', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                code: code,
                waba_id: extras.waba_id,
                phone_number_id: extras.phone_number_id,
                business_id: extras.business_id
              })
            })
              .then(res => res.json())
              .then(data => {
                console.log('Onboarding complete:', data);
              })
              .catch(err => {
                console.error('Onboarding failed:', err);
              });
          } else {
            console.log('User cancelled or did not authorize.');
          }
        },
        {
          config_id: 'YOUR_CONFIG_ID',              // Replace with your Config ID from step 3.3
          response_type: 'code',
          override_default_response_type: true,
          extras: {
            sessionInfoVersion: 2,                   // Returns WABA ID, phone number ID, business ID
            setup: {
              solutionID: 'YOUR_META_SOLUTION_ID'    // Replace with the Solution ID Plivo issued to you
            }
          }
        }
      );
    }
  </script>

  <button onclick="launchEmbeddedSignup()"
    style="background-color: #1877f2; color: #ffffff; padding: 12px 24px; border: none; border-radius: 6px; font-size: 16px; cursor: pointer;">
    Connect WhatsApp
  </button>
</body>
</html>
```

> [!NOTE]
>
> Replace `YOUR_META_APP_ID` with your actual Meta App ID, `YOUR_CONFIG_ID` with the Config ID from your Facebook Login for Business settings (step 3.3), and `YOUR_META_SOLUTION_ID` with the Solution ID Plivo issued to you.

> [!NOTE]
>
> The **Solution ID** is issued by Plivo after your Multi-Partner Solution is accepted (step 3.2). You do not choose or generate it yourself. It is not your Meta App ID and not your Config ID. If you have not received it, contact your Plivo account manager.

### 4.3 Backend — exchange code and share WABA

Your backend performs two steps after receiving the authorization code and session info from the frontend.

**Step A: Validate the authorization code with Meta**

Call the Meta Graph API `debug_token` endpoint to validate the code and retrieve the associated WABA details.

```bash theme={null}
curl -G "https://graph.facebook.com/v19.0/debug_token" \
  --data-urlencode "input_token=CODE_FROM_FRONTEND" \
  --data-urlencode "access_token=YOUR_META_APP_ID|YOUR_META_APP_SECRET"
```

The response confirms the code is valid and returns metadata including the scopes granted. If you already received the WABA ID, phone number ID, and business ID from the `sessionInfoVersion: 2` response in step 4.1, you can use those values directly.

**Step B: Call the Plivo Embedded Signup API**

Send a POST request to the Plivo Embedded Signup endpoint with the WABA ID, phone number ID, and business ID. This tells Plivo to onboard the WABA, attach it to the credit line, register webhooks, and activate the phone number for messaging. Optionally pass `webhook_url` to set the WABA's webhook at onboarding time, so your customer does not have to configure it in the Plivo console afterwards.

```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/WhatsApp/EmbeddedSignup/" \
  -H "Content-Type: application/json" \
  -u "<auth_id>:<auth_token>" \
  -d '{
    "waba_id": "WABA_ID_FROM_SIGNUP",
    "business_id": "BUSINESS_ID_FROM_SIGNUP",
    "phone_number_id": "PHONE_NUMBER_ID_FROM_SIGNUP",
    "client_ref": "customer-12345",
    "webhook_url": "https://customer.example.com/plivo/whatsapp/webhook"
  }'
```

> [!NOTE]
>
> Replace `{auth_id}` and `{auth_token}` with the API credentials Plivo provided for your Tech Provider sub-account.

## Embedded Signup API reference

### Endpoint

```bash theme={null}
POST https://api.plivo.com/v1/Account/{auth_id}/WhatsApp/EmbeddedSignup/
```

### Authentication

Use [HTTP Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) with your Plivo Auth ID as the username and Auth Token as the password. These credentials are scoped to your Tech Provider sub-account.

### Request parameters

**waba\_id** `string` *required*

The WhatsApp Business Account ID returned by the Embedded Signup flow. This is the WABA that your customer created or selected during the signup dialog.

**business\_id** `string` *required*

The Meta Business ID associated with your customer's Meta Business Portfolio. Returned by the Embedded Signup flow.

**phone\_number\_id** `string` *required*

The phone number ID registered during the Embedded Signup flow. This is the WhatsApp-enabled phone number your customer verified with an OTP.

**client\_ref** `string`

An optional reference string you can use to map this WABA to your internal customer identifier. Maximum 64 characters.

**webhook\_url** `string`

An optional HTTPS URL that Plivo calls with inbound messages and WABA-level events for this WABA. Maximum 255 characters. The URL must be reachable from Plivo's egress IP ranges. If you omit it, the WABA has no webhook set and your customer can add one later from the Plivo console. Setting it here has the same effect as your customer setting the WABA webhook URL in the console; it only lets you do it at onboarding time.

### What the webhook URL receives

Once `webhook_url` is set, Plivo delivers the following to that URL for the shared WABA:

* **Inbound messages** sent to any phone number on this WABA. The payload matches the one described in [Receive Inbound Messages and Interactions](https://plivo.com/docs/messaging/use-cases/whatsapp/getting-started/inbound-message/inbound-message.md).
* **WABA-level events**, including:
  * Phone number verification and display-name status changes (see [Manage WhatsApp phone numbers](https://plivo.com/docs/messaging/concepts/whatsapp/manage-whatsapp-phonenumbers.md))
  * Messaging limit tier changes
  * Quality rating changes
  * Template status changes (see [WhatsApp Templates API](https://plivo.com/docs/messaging/api/whatsapp-templates.md))
  * Business capability updates from Meta

The payload shape is the same as Plivo's existing WhatsApp inbound message and event webhooks. This list is not exhaustive; Meta adds event types over time.

### Sample request

```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/WhatsApp/EmbeddedSignup/" \
  -H "Content-Type: application/json" \
  -u "<auth_id>:<auth_token>" \
  -d '{
    "waba_id": "109876543210987",
    "business_id": "198765432109876",
    "phone_number_id": "112233445566778",
    "client_ref": "customer-12345",
    "webhook_url": "https://customer.example.com/plivo/whatsapp/webhook"
  }'
```

### Success response

**HTTP 200 OK**

```json theme={null}
{
  "api_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "message": "Embedded signup completed successfully.",
  "waba_id": "109876543210987",
  "phone_number_id": "112233445566778",
  "business_id": "198765432109876"
}
```

### Error responses

**HTTP 401 Unauthorized**

Returned when the Auth ID or Auth Token is invalid or missing.

```json theme={null}
{
  "api_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "error": "Authentication credentials were not provided or are invalid."
}
```

**HTTP 403 Forbidden**

Returned when your account does not have Tech Provider permissions or WhatsApp is not enabled.

```json theme={null}
{
  "api_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "error": "Your account is not authorized for the Embedded Signup API."
}
```

**HTTP 400 Bad Request**

Returned when request parameters are missing or invalid. The following table lists common scenarios.

| Scenario | Error message |
| - | - |
| Missing `waba_id` | `waba_id is required.` |
| Missing `business_id` | `business_id is required.` |
| Missing `phone_number_id` | `phone_number_id is required.` |
| Invalid `waba_id` format | `waba_id is not a valid WhatsApp Business Account ID.` |
| WABA already onboarded | `This WABA is already registered with Plivo.` |
| Phone number already registered | `This phone number is already registered under another WABA.` |
| Invalid `webhook_url` | `webhook_url must be an HTTPS URL of at most 255 characters.` |
| Multi-Partner Solution not active | `Multi-Partner Solution is not active for your app. Contact Plivo support.` |

```json theme={null}
{
  "api_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "error": "waba_id is required."
}
```

**HTTP 500 Internal Server Error**

Returned when an unexpected error occurs on the server side. Retry the request after a short delay. If the error persists, contact [Plivo support](https://support.plivo.com/hc/en-us/requests/new).

```json theme={null}
{
  "api_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "error": "An internal error occurred. Please try again later."
}
```

### HTTP status summary

| Status code | Meaning | When it occurs |
| - | - | - |
| 200 | OK | Embedded Signup completed successfully. The WABA, phone number, and webhooks are configured. |
| 400 | Bad Request | One or more required parameters are missing, invalid, or the WABA/phone number is already registered. |
| 401 | Unauthorized | Auth ID or Auth Token is missing or invalid. |
| 403 | Forbidden | Your account lacks Tech Provider permissions or WhatsApp is not enabled. |
| 500 | Internal Server Error | An unexpected server-side error occurred. Retry after a short delay. |
