Multi-Partner Solutions

This document explains how to set up a Multi-Partner Solution via the App Dashboard and API, and how to use Multi-Partner Solutions with Embedded Signup.

Multi-Partner Solution allow Solution Partners and Tech Providers to jointly manage customer WhatsApp assets in order to provide WhatsApp messaging services to their customers. For example, if you are a Tech Provider and are unable to offer custom or full WhatsApp messaging services to your customers, you can work with a Solution Partner to offer your customers the Solution Partner's services.

The basis of a Multi-Partner Solution is a partner solution, which defines which customer WhatsApp assets each partner can access. Once created and accepted via API or App Dashboard, the solution can be used to customize the Embedded Signup flow. Any customers onboarded via the flow can grant asset access to all of the solution's partners.

Note that Multi-Partner Solution can also be set up via an embedded button that trigers an interface that gathers app information from Tech Providers. This flow and the API calls involved are described in the Multi-Partner Solution — Embedded Creation document, but the information below is still relevant and should be read first.

Limitations

Only Solution Partner apps can be used by onboarded business customers to send messages.

Requirements

You must be an approved Solution Partner, a Tech Provider who has completed the steps in our Get Started for Tech Providers document appropriate for your intended usage, or a Tech Provider who has been upgraded to a Tech Partner.

If your app will be calling our APIs to access onboarded customer data:

  • The app must be the same app whose token will be used in API requests.
  • The app must have completed App Review and been approved for the whatsapp_business_management and whatsapp_business_messaging permissions.
  • The app must be subscribed to the account_updates webhooks field and be able to successfully digest webhooks for onboarded customers.

Partner Solutions

A partner solution is an asset sharing relationship between two partners — a Tech Provider (or Tech Partner) and a Solution Partner.

Solutions are initiated, accepted, and managed in the App Dashboard > WhatsApp > Partner Solutions panel.

Solutions can be created by either partner of the solution. Once created, a solution request is sent to the invited partner, who can then use the panel in their app dashboard to accept or decline the request. Once accepted, either partner can use the solution to customize the Embedded Signup flow and onboard customers.

Solution States

Solutions states are displayed in the partner solutions panel. Solutions can have the following states:

StateDescription

Active

The solution has been accepted by the invited party and can be used to configure Embedded Signup for customer onboarding.

Deactivated

The solution has been deactivated.


Customers who attempt to access Embedded Signup configured for a solution in this state will see an error informing them that it cannot be used for onboarding at this time.

Draft

The solution has been initiated and saved, but you have not sent it to your partner.


Customers who attempt to access Embedded Signup configured for a solution in this state will see an error informing them that it cannot be used for onboarding at this time.

Inactive

The solution request was declined by your partner.


Customers who attempt to access Embedded Signup configured for a solution in this state will see an error informing them that it cannot be used for onboarding at this time.

Pending

Solution has not been accepted or declined by your partner.


Customers who attempt to access Embedded Signup configured for a solution in this state will see an error informing them that it cannot be used for onboarding at this time.

Pending deactivation

Your partner has requested to deactivate the solution. You can accept or decline this request.

Onboarding Limits

Tech Providers who are part of a partner solution can onboard up to 200 total new customers in a rolling one week period. Only customers who are new to the WhatsApp Business Platform count against this limit.

Embedded Signup

Embedded Signup can be configured and hosted by either of the solution's partners, or both partners. Once implemented, customers who access it will see a customized version of the Embedded Signup flow, which makes it clear that by completing the flow they are granting WhatsApp data access to both partners:

When a customer completes the flow, all of the customer's WhatsApp assets that we need are automatically generated, and access to those assets is granted to both partners of the solution.

Billing

Customers onboarded via Embedded Signup configured for a solution share the credit line of the Solution Partner associated with the solution.

Step 1: Determine Solution Details

Contact your potential partner and work together to determine:

  • A solution name. The solution name will appear in the partner solutions panel in the app dashboard, so both you and your partner should agree on a name that can be distinguished from other solutions you may initiate or accept.
  • Who will initiate the solution request. Either you or your partner can initiate the request. If you are initiating the request, you will need your partner's app ID, so be sure to ask for it.
  • Who will configure Embedded Signup and surface it to business customers. Both you and your partner can configure and surface Embedded Signup.
  • Anything else, such as contracts, service level agreements, services provided, billing processes, etc. This is left to the discretion of you and your partner, subject to each of your separate agreements with Meta.

Step 2: Subscribe to Webhooks

Subscribe to the account_update and partner_solutions webhooks fields. These webhooks will inform you when new business customers are onboarded, and when partner solutions that you are associated with are created or edited.

See the Webhooks section below for example payloads and what to look for when you receive any of these webhooks.

Step 3: Create a Solution

If you are creating the partner solution, navigate to the App Dashboard > WhatsApp > Partner solutions panel and click the Create a partner solution button.

Use your partner's app ID to complete the flow.

Upon creation, an email and Meta Business Suite notification will be sent to your partner, and a partner_solutions webhook will be triggered.

The partner solution will appear in the Partner solutions panel with a Pending status until accepted by your partner. If accepted, it's status will change to Active. If declined, it's status will change to Inactive.

Step 4: Accept The Solution Request

Everyone with admin (Full control) privileges on your business portfolio will be notified by email and Meta Business Suite notification when your partner sends you a partner solution request.

In addition, a partner_solutions webhook will be triggered with event set to SOLUTION_CREATED and solution_status set to INITIATED. Capture the included solution ID (solution_id) if you will be accepting/rejecting and managing the solution via API.

You can use either the App Dashboard or the API to accept the partner solution request.

Via App Dashboard

The request will appear in the App Dashboard > WhatsApp > Partner solutions panel with a Pending status.

If you have multiple solutions and are having a hard time locating the solution request, use the dropdown menu in the top-right corner of the panel and filter by Pending.

Confirm that everything is correct before accepting the request, as solutions cannot be declined once they have been accepted.

Once you accept the solution, its status will be set to Active and you and your partner can use it to configure Embedded Signup and begin surfacing it to business customers.

If any information is incorrect, decline the request and ask your partner to submit a new request with the correct settings. Your partner will automatically be notified by email and Meta Business Suite notification if you decline the request.

Via API

Before accepting the solution, use the GET /<SOLUTION_ID> endpoint to get details about the solution and confirm that everything is correct, as solutions cannot be declined once they have been accepted.

Include the following fields in your query:

  • name
  • owner_permissions
  • partners{partner_permissions,partner_app}

Example request

curl -g 'https://graph.facebook.com/v20.0/795033096057724&fields=name,owner_permissions,partners{partner_permissions,partner_app}' \
-H 'Authorization: Bearer EAAAT...'

Example response

{
  "name": "Social OVD with Lucky Shrub",
  "owner_permissions": [
    "MANAGE",
    "DEVELOP",
    "MANAGE_TEMPLATES",
    "MANAGE_PHONE",
    "VIEW_COST",
    "MANAGE_EXTENSIONS",
    "VIEW_PHONE_ASSETS",
    "MANAGE_PHONE_ASSETS",
    "VIEW_TEMPLATES",
    "VIEW_INSIGHTS"
  ],
  "partners": {
    "data": [
      {
        "partner_permissions": [
          "MANAGE",
          "DEVELOP",
          "MANAGE_TEMPLATES",
          "MANAGE_PHONE",
          "VIEW_COST",
          "MANAGE_EXTENSIONS",
          "VIEW_PHONE_ASSETS",
          "MANAGE_PHONE_ASSETS",
          "VIEW_TEMPLATES",
          "VIEW_INSIGHTS"
        ],
        "partner_app": {
          "link": "https://www.facebook.com/games/?app_id=21202248997039",
          "name": "Lucky Shrub",
          "id": "21202248997039"
        },
        "id": "795033099391057"
      }
    ],
    "paging": {
      "cursors": {
        "before": "QVFIUl9hX0RqLUZAPemJQVWdsYTl5WlBsY0lCb0FNTExOY2N2NzJtRENZAbDd3azBNXzhPZAndqaU5sSXdfWWJaSXJ1S2pqMi0tQUdUdm1LTGZATUDNIdGRNNE1B",
        "after": "QVFIUl9hX0RqLUZAPemJQVWdsYTl5WlBsY0lCb0FNTExOY2N2NzJtRENZAbDd3azBNXzhPZAndqaU5sSXdfWWJaSXJ1S2pqMi0tQUdUdm1LTGZATUDNIdGRNNE1B"
      }
    }
  },
  "id": "795033096057724"
}
  • name — the name of the solution, as it appears in the App Dashboard.
  • owner_permissions — the permissions your partner's app will be granted by business customers who onboard via Embedded Signup.
  • partner_permissions — the permissions your app will be granted by business customers who onboard via Embedded Signup.
  • partner_app — the app (your app) that will be granted the permissions identified in partner_permissions.

If everything is correct, use the POST /<SOLUTION_ID>/accept endpoint to accept the solution request, otherwise use the POST /<SOLUTION_ID>/reject endpoint to reject it.

Example accept request

curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/accept' \
-H 'Authorization: Bearer EAAAT...'

Example reject request

curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/reject' \
-H 'Authorization: Bearer EAAAT...'

Example response

Upon success:

{
  "success": true
}

Step 5: Configure Embedded Signup

Assign the solution ID to the solutionID property in the extras.setup object within your implementation of Embedded Signup:

<script type="text/javascript">
  document.getElementById('login-btn').onclick = () =>
    FB.login(response => {}, {
      config_id: '<CONFIGURATION_ID>',
      response_type: 'code',
      override_default_response_type: true,
      extras: {
        setup: {
          solutionID: '<SOLUTION_ID>'  // Solution ID goes here
        }
      }
    });
</script>

<button id="login-btn" style="background-color:green; padding:10px 20px; color:#fff;">
  Launch Embedded Signup
</button>

Both you and your partner's business portfolio (Business Settings > Business Info) will appear throughout the Embedded Signup flow.

Once configured, surface the customized Embedded SIgnup flow to customers on your platform wherever you feel it is appropriate. Note that if you have multiple active partner solutions, it is your responsibility to inject the correct solution ID into your Embedded Signup configuration and surface it to your intended customers, otherwise a customer could be onboarded using the wrong solution.

Step 6: Listen for Onboarded Business Customers

To listen for onboarded customers, your app must be subscribed to the account_update webhook field.

When a customer completes the Embedded Signup flow configured with your solution, an account update webhook is triggered with a PARTNER_ADDED event. Capture the waba_id, solution_id, and owner_business_id property values contained in the webhook payload, as well as any other values you may need in order to provide the customer with WhatsApp messaging services.

In addition, we will send an email to admins of the business portfolio that owns the app, and a Meta Business Suite notification to the business portfolio that owns the app.

Step 7: Share Your Credit Line (Solution Partners only)

If you are a Solution Partners, share your line of credit with any business customers newly onboarded via the partner solution.

See Share and Revoke Credit Lines.

Webhooks

account_update

When a new business customer has successfully completed the Embedded Signup flow, an account_update webhook will be triggered with the event property set to PARTNER_ADDED.

{
  "entry": [
    {
      "id": "<BUSINESS_PORTFOLIO_ID>",
      "time": <TIMESTAMP>,
      "changes": [
        {
          "value": {
            "event": "<EVENT>",
            "waba_info": {
              "waba_id": "<BUSINESS_CUSTOMER_WABA_ID>",
              "owner_business_id": "<BUSINESS_CUSTOMER_BUSINESS_PORTFOLIO_ID>",
              "solution_id": "<SOLUTION_ID>",
              "solution_partner_business_ids": [<SOLUTION_BUSINESS_PORTFOLIO_IDS>]
            }
          },
          "field": "account_update"
        }
      ]
    }
  ],
  "object": "whatsapp_business_account"
}

Payload Properties


PlaceholderDescriptionExample

<BUSINESS_PORTFOLIO_ID>

Your business portfolio ID.

506914307656634

<BUSINESS_CUSTOMER_BUSINESS_PORTFOLIO_ID>

Onboarded customer's business portfolio ID.

6143763655652543

<BUSINESS_CUSTOMER_WABA_ID>

Onboarded customer's WhatsApp Business Account ID.

102290129340398

<EVENT>

If set to PARTNER_ADDED, indicates that the business customer has successfully completed the Embedded Signup flow.

PARTNER_ADDED

<SOLUTION_BUSINESS_PORTFOLIO_IDS>

Strings of business portfolio IDs of the Tech Provider (or Tech Partner) and Solution Partner associated with the solution.

"506914307656634","116133292427920"

<SOLUTION_ID>

Solution ID.

303610109049230

<TIMESTAMP>

UNIX timestamp indicating when the customer successfully completed the Embedded Signup flow.

1690592557

partner_solutions

{
  "entry": [
    {
      "id": "<BUSINESS_PORTFOLIO_ID>",
      "time": <TIMESTAMP>,
      "changes": [
        {
          "value": {
            "event": "SOLUTION_CREATED",
            "solution_id": "<SOLUTION_ID>",
            "solution_status": "INITIATED"
          },
          "field": "partner_solutions"
        }
      ]
    }
  ],
  "object": "whatsapp_business_account"
}

Payload Properties


PlaceholderDescriptionExample

<BUSINESS_PORTFOLIO_ID>

Your business portfolio ID.

506914307656634

<EVENT>

Event description. Values can be:

  • SOLUTION_CREATED — Solution created.
  • SOLUTION_UPDATED — The solution_status has changed.

SOLUTION_CREATED

<SOLUTION_ID>

Solution ID.

774485461512159

<SOLUTION_STATUS>

Solution status. Values can be:

  • ACTIVE — The solution partner has accepted the solution request and it can be used with Embedded Signup.
  • DEACTIVATED — The solution has been deactivated and cannot be used with Embedded Signup to onboard business customers.
  • DRAFT — Solution has been drafted but invitation has not been sent to the solution partner.
  • INITIATED — The solution partner has been invited to accept the solution, but has yet to accept or reject the request.
  • PENDING — The solution partner has yet to accept or reject the solution request.
  • PENDING_DEACTIVATION — The solution owner requested for an active solution to be deactivated but the solution partner has yet to accept the deactivation request.
  • REJECTED — The solution partner has rejected the solution request.

INITIATED

<TIMESTAMP>

UNIX timestamp indicating when the customer successfully completed the Embedded Signup flow.

1718143652

Editing or Deactivating Solutions

You can use the App Dashboard or API to edit or deactivate a solution.

When you request deactivation, the solution's status will change to Pending deactivation and your partner will be notified by email and Meta Business Suite notification. In addition, a partner_solutions webhook will be triggered with event set to SOLUTION_UPDATED and solution_status set to PENDING_DEACTIVATION. Your partner can then accept or reject your request.

Note that partner solutions can still be used to onboard customers until your partner accepts the deactivation request.

If the deactivation request is rejected, the solution will remain in an Active state and can continue to be used to onboard customers.

If the deactivation request is accepted, the solution status will be set to Deactivated and can no longer be used to onboard business customers, so make sure that neither you nor your partner are surfacing it to business customers.

Limitations

  • You can only edit solutions that were created by you.
  • You can request deactivation of any solutions that you create which are in an Active state.

Via App Dashboard

Use the App Dashboard > WhatsApp > Partner solutions panel to edit or deactivate a solution. Note that you can only edit solutions that were initiated by you.

StatePermitted actions

Active

You may edit the solution name, or deactivate the solution.

Deactivated

Solutions in this state cannot be edited.

Draft

You may edit the solution name.

Inactive

You may edit the solution name.

Pending

Solutions in this state cannot be edited until accepted or declined by your partner.

Pending deactivation

You may accept or decline the partner's deactivation request.

Via API

Send deactivation request

Use the POST /<SOLUTION_ID>/send_deactivation_request endpoint to send a solution deactivation request. You must be the solution owner in order to send this request.

Example request

curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/send_deactivation_request \
-H 'Authorization: Bearer EAAAT...'

Example response

Upon success:

{
    "success": true
}

Accept deactivation request

Use the POST /<SOLUTION_ID>/accept_deactivation_request endpoint to accept a solution deactivation request. You must be the solution owner in order to send this request.

Example request

curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/accept_deactivation_request \
-H 'Authorization: Bearer EAAAT...'

Example response

Upon success:

{
    "success": true
}

Reject deactivation request

Use the POST /<SOLUTION_ID>/reject_deactivation_request endpoint to reject a solution deactivation request. You must be the solution owner in order to send this request.

Example request

curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/reject_deactivation_request \
-H 'Authorization: Bearer EAAAT...'

Example response

Upon success:

{
    "success": true
}

Manually Checking for Onboarded Customers

As a fallback in case of webhook problems, you can manually check for onboarded customers using the GET /<BUSINESS_PORTFOLIO_ID>/client_whatsapp_business_accounts endpoint, which returns WABA IDs of all customers newly onboarded via the solution.

Request Syntax

GET /<BUSINESS_PORTFOLIO_ID>/client_whatsapp_business_accounts
  ?filtering=[
    {
      "field":"partners",
      "operator":"ALL",
      "value":[
        "<PARTNER_BUSINESS_PORTFOLIO_ID>"
      ]
    }
  ]

Replace <PARTNER_BUSINESS_PORTFOLIO_ID> with your partner's business portfolio ID.

Response

{
  "data": [
    {
      "id": "<CUSTOMER_WABA_ID>",
      "name": "<CUSTOMER_WABA_NAME>",
      "timezone_id": "<CUSTOMER_WABA_TIMEZONE_ID>",
      "business_type": "ent",
      "message_template_namespace": "<MESSAGE_TEMPLATE_NAMESPACE>"
    },
    ...
  ],
  "paging": {
    "cursors": {
      "before": "<BEFORE>",
      "after": "<AFTER>"
    },
    "next": "<NEXT>"
  }
}
PlaceholderDescriptionExample Value

<CUSTOMER_WABA_ID>

Customer WhatsApp Business Account ID.

102290129340398

<CUSTOMER_WABA_NAME>

Customer WhatsApp Business Account name.

Cool New Customer 2

<CUSTOMER_WABA_TIMEZONE_ID>

Customer WhatsApp Business Account timezone ID.

7

<MESSAGE_TEMPLATE_NAMESPACE>

Customer WhatsApp Business Account template namespace for On-Premises API. See Language Packs.

0add05f3_abbe_4a55_b6f5_e751fa4e1244

<BEFORE>

Paginated results cursor. See Paginated Results.

QVFIU...

<AFTER>

Paginated results cursor. See Paginated Results.

QVFIU...

<NEXT>

Paginated results link. See Paginated Results.

https://graph.facebook.com/v18.0/50691...

Example Request

curl -g 'https://graph.facebook.com/v20.0/506914307656634/client_whatsapp_business_accounts?filtering=[{%22field%22%3A%22partners%22%2C%20%22operator%22%3A%20%22ALL%22%2C%20%22value%22%3A%20[%22520744086200222%22]}]' \
-H 'Authorization: Bearer EAAJB...'

Example Response

{
  "data": [
    {
      "id": "102290129340398",
      "name": "Cool New Customer 2",
      "timezone_id": "7",
      "business_type": "ent",
      "message_template_namespace": "0add05f3_abbe_4a55_b6f5_e751fa4e1244"
    },
    {
      "id": "112077945305052",
      "name": "Cool New Customer 1",
      "timezone_id": "7",
      "business_type": "ent",
      "message_template_namespace": "b2d0c901_b542_46a0_ab99_5939b75267d8"
    },
    ...
  ],
  "paging": {
    "cursors": {
      "before": "QVFIU...",
      "after": "QVFIU..."
    },
    "next": "https://graph.facebook.com/v20.0/50691..."
  }
}

Getting Solution Data

Get fields on a solution

Use the GET /<SOLUTION_ID> endpoint to get default fields on a solution, or use the fields query string parameter to request specific fields.

Example Request

curl 'https://graph.facebook.com/v20.0/17602267745700?fields=name,status,partners' \
-H 'Authorization: Bearer EAAAT...'

Example Response

{
  "name": "Social OVD with Lucky Shrub",
  "status": "ACTIVE",
  "partners": {
    "data": [
      {
        "partner_app": {
          "link": "https://www.socialoverdrive.com/",
          "name": "Social Overdrive",
          "id": "637576208107267"
        },
        "status": "ACCEPTED",
        "id": "17602267745704"
      }
    ],
    "paging": {
      "cursors": {
        "before": "QVFIUmxnSE9LUFliNzlUTWdhTlYzQjBtekprSC0wQUdoZAGRYbFlzeUpDMG9yNkF1OHYyel9tcUlBbGhFckxJQ1Y3UFZA4dUkycEk0WDJwRGYzT2JYbVhEdFdB",
        "after": "QVFIUmxnSE9LUFliNzlUTWdhTlYzQjBtekprSC0wQUdoZAGRYbFlzeUpDMG9yNkF1OHYyel9tcUlBbGhFckxJQ1Y3UFZA4dUkycEk0WDJwRGYzT2JYbVhEdFdB"
      }
    }
  },
  "id": "17602267745700"
}

Get solutions associated with your app

Use the GET /<APP_ID>/whatsapp_business_solutions endpoint to get a list of solutions your app is associated with.

Example Request

curl 'https://graph.facebook.com/v20.0/21202248997039/whatsapp_business_solutions' \
-H 'Authorization: Bearer EAAAT...'

Example Response

{
  "data": [
    {
      "name": "Social OVD with Lucky Shrub",
      "status": "INITIATED",
      "status_for_pending_request": "PENDING_ACTIVATION",
      "id": "19702253086782"
    },
    {
      "name": "Social OVD with Social Brew",
      "status": "ACTIVE",
      "status_for_pending_request": "NONE",
      "id": "17602267745700"
    }
  ],
  "paging": {
    "cursors": {
      "before": "QVFIUkxlbkhTZA1VleGwyWHd3SmlSMnlnelhlbUVSSjVYQmU2aXVmb1YyWk9JTkx3b2gwNE9FS3J2ejMzNENxbmh1bWZAqSkZAJUzNfbmF4NmtPaFYxQldaaXR3",
      "after": "QVFIUlgyLTlQYWV0eTNGWXVhcTJnOEhzY1lvUDloVV8wUUxVQk9YMVJ5UGlBZAmx1Q1BjaEVwd0tWdmNvRU9jdGRiNnlrc193alRNaDV2SXZAfN1kybDBibEFR"
    }
  }
}

Get solutions that onboarded a WABA

Use the GET /<WABA_ID>/solutions endpoint to get a list of solutions that onboarded a specific WABA.

Example Request

curl 'https://graph.facebook.com/v20.0/102290129340398/solutions' \
-H 'Authorization: Bearer EAAAT...'

Example Response

{
  "data": [
    {
      "name": "Social OVD with Social Brew",
      "status": "ACTIVE",
      "status_for_pending_request": "NONE",
      "id": "17602267745700"
    }
  ],
  "paging": {
    "cursors": {
      "before": "QVFIUjZACTFNmWURVTHN2NFVaM2ZApd2RaOGIxOU5wenpQZADFkbVdtSEJDSGFDelhDOU5hT28xcmJLS05TM3U0UUFmdVNGUWFfdjdJb1o2OTVNY083ZAHYtc2x3",
      "after": "QVFIUjZACTFNmWURVTHN2NFVaM2ZApd2RaOGIxOU5wenpQZADFkbVdtSEJDSGFDelhDOU5hT28xcmJLS05TM3U0UUFmdVNGUWFfdjdJb1o2OTVNY083ZAHYtc2x3"
    }
  }
}

Get partners of a solution

Use the GET /<SOLUTION_ID>/partners endpoint to get a list of partners of a solution.

Example Request

curl 'https://graph.facebook.com/v20.0/17602267745700/partners' \
-H 'Authorization: Bearer EAAAT...'

Example Response

{
  "data": [
    {
      "partner_app": {
        "link": "https://www.socialoverdrive.com",
        "name": "Social Overdrive",
        "id": "637576208107267"
      },
      "status": "ACCEPTED",
      "id": "17602267745704"
    }
  ],
  "paging": {
    "cursors": {
      "before": "QVFIUmxnSE9LUFliNzlUTWdhTlYzQjBtekprSC0wQUdoZAGRYbFlzeUpDMG9yNkF1OHYyel9tcUlBbGhFckxJQ1Y3UFZA4dUkycEk0WDJwRGYzT2JYbVhEdFdB",
      "after": "QVFIUmxnSE9LUFliNzlUTWdhTlYzQjBtekprSC0wQUdoZAGRYbFlzeUpDMG9yNkF1OHYyel9tcUlBbGhFckxJQ1Y3UFZA4dUkycEk0WDJwRGYzT2JYbVhEdFdB"
    }
  }
}