This document explains how to set up Multi-Partner Solutions ("solutions") and how to use them with Embedded Signup.
Multi-Partner Solutions 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.
Once created and accepted via API or App Dashboard, the solution's ID can be used to customize the Embedded Signup flow. Any customers onboarded via the customized flow can grant asset access to all of the solution's partners.
Note that solutions can also be set up via an embedded button that triggers 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.
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:
Use the App Dashboard > WhatsApp > Partner Solutions panel to create, accept, and manage solutions.
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 ID to customize the Embedded Signup flow and onboard business customers.
Solutions states are displayed in the Partner solutions panel. Solutions can have the following states:
State | Description |
---|---|
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. |
Tech Providers who are part of a 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 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.
Customers onboarded via Embedded Signup configured with a solution ID share the credit line of the Solution Partner associated with the solution.
Contact your potential partner and work together to determine:
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.
If you are creating the 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. As part of the creation flow you can designate which solution partner apps can be used by onboarded business customers to send messages (Only me, Only my partner).
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.
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.
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 its ID to configure Embedded Signup.
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.
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}
curl -g 'https://graph.facebook.com/v21.0
/795033096057724&fields=name,owner_permissions,partners{partner_permissions,partner_app}' \
-H 'Authorization: Bearer EAAAT...'
{ "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.
curl -X POST 'https://graph.facebook.com/v21.0
/795033096057724/accept' \
-H 'Authorization: Bearer EAAAT...'
curl -X POST 'https://graph.facebook.com/v21.0
/795033096057724/reject' \
-H 'Authorization: Bearer EAAAT...'
Upon success:
{ "success": true }
Assign the solution ID to the solutionID
property in the extras.setup
object within the launch method and callback registration portion of the Embedded Signup code.
// 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: { solutionID" '<SOLUTION_ID>' // add solution ID here }, featureType: '', sessionInfoVersion: '3', } }); }
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.
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.
If you are a Solution Partners, share your line of credit with any business customers newly onboarded via the partner solution.
**Note: If you are trying to add a user to a WhatsApp Business Account that is shared with you via a Multi-Partner Solution you would have to use MANAGE_USERS
permission task to add the user to that account.
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" }
Placeholder | Description | Example |
---|---|---|
| Your business portfolio ID. |
|
| Onboarded customer's business portfolio ID. |
|
| Onboarded customer's WhatsApp Business Account ID. |
|
| If set to |
|
| Strings of business portfolio IDs of the Tech Provider (or Tech Partner) and Solution Partner associated with the solution. |
|
| Solution ID. |
|
| UNIX timestamp indicating when the customer successfully completed the Embedded Signup flow. |
|
When a Multi-Partner Solution is created or modified, a partner_solutions webhook describing the change will be triggered.
{ "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" }
Placeholder | Description | Example |
---|---|---|
| Your business portfolio ID. |
|
| Event description. Values can be:
|
|
| Solution ID. |
|
| Solution status. Values can be:
|
|
| UNIX timestamp indicating when the customer successfully completed the Embedded Signup flow. |
|
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.
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.
State | Permitted 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. |
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.
curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/send_deactivation_request \ -H 'Authorization: Bearer EAAAT...'
Upon success:
{ "success": true }
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.
curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/accept_deactivation_request \ -H 'Authorization: Bearer EAAAT...'
Upon success:
{ "success": true }
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.
curl -X POST 'https://graph.facebook.com/v20.0/795033096057724/reject_deactivation_request \ -H 'Authorization: Bearer EAAAT...'
Upon success:
{ "success": true }
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.
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.
{ "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>" } }
Placeholder | Description | Example Value |
---|---|---|
| Customer WhatsApp Business Account ID. |
|
| Customer WhatsApp Business Account name. |
|
| Customer WhatsApp Business Account timezone ID. |
|
| Customer WhatsApp Business Account template namespace for On-Premises API. See Language Packs. |
|
| Paginated results cursor. See Paginated Results. |
|
| Paginated results cursor. See Paginated Results. |
|
| Paginated results link. See Paginated Results. |
|
curl -g 'https://graph.facebook.com/v21.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...'
{
"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/v21.0
/50691..."
}
}
Use the GET /<SOLUTION_ID> endpoint to get default fields on a solution, or use the fields
query string parameter to request specific fields.
curl 'https://graph.facebook.com/v21.0
/17602267745700?fields=name,status,partners' \
-H 'Authorization: Bearer EAAAT...'
{ "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" }
Use the GET /<APP_ID>/whatsapp_business_solutions endpoint to get a list of solutions your app is associated with.
curl 'https://graph.facebook.com/v21.0
/21202248997039/whatsapp_business_solutions' \
-H 'Authorization: Bearer EAAAT...'
{ "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" } } }
Use the GET /<WABA_ID>/solutions endpoint to get a list of solutions that onboarded a specific WABA.
curl 'https://graph.facebook.com/v21.0
/102290129340398/solutions' \
-H 'Authorization: Bearer EAAAT...'
{ "data": [ { "name": "Social OVD with Social Brew", "status": "ACTIVE", "status_for_pending_request": "NONE", "id": "17602267745700" } ], "paging": { "cursors": { "before": "QVFIUjZACTFNmWURVTHN2NFVaM2ZApd2RaOGIxOU5wenpQZADFkbVdtSEJDSGFDelhDOU5hT28xcmJLS05TM3U0UUFmdVNGUWFfdjdJb1o2OTVNY083ZAHYtc2x3", "after": "QVFIUjZACTFNmWURVTHN2NFVaM2ZApd2RaOGIxOU5wenpQZADFkbVdtSEJDSGFDelhDOU5hT28xcmJLS05TM3U0UUFmdVNGUWFfdjdJb1o2OTVNY083ZAHYtc2x3" } } }
Use the GET /<SOLUTION_ID>/partners endpoint to get a list of partners of a solution.
curl 'https://graph.facebook.com/v21.0
/17602267745700/partners' \
-H 'Authorization: Bearer EAAAT...'
{ "data": [ { "partner_app": { "link": "https://www.socialoverdrive.com", "name": "Social Overdrive", "id": "637576208107267" }, "status": "ACCEPTED", "id": "17602267745704" } ], "paging": { "cursors": { "before": "QVFIUmxnSE9LUFliNzlUTWdhTlYzQjBtekprSC0wQUdoZAGRYbFlzeUpDMG9yNkF1OHYyel9tcUlBbGhFckxJQ1Y3UFZA4dUkycEk0WDJwRGYzT2JYbVhEdFdB", "after": "QVFIUmxnSE9LUFliNzlUTWdhTlYzQjBtekprSC0wQUdoZAGRYbFlzeUpDMG9yNkF1OHYyel9tcUlBbGhFckxJQ1Y3UFZA4dUkycEk0WDJwRGYzT2JYbVhEdFdB" } } }
If you are not hosting Embedded Signup but want to get an onboarded business customer's business integration system user access token ("business token"), you can get their token using the business portfolio ID and solution ID contained in the account_update webhook that was triggered when the customer completed the Embedded Signup flow.
Use the GET /<SOLUTION_ID>/access_token endpoint and request the business_id
parameter to get an onboarded business customer's business token.
curl 'https://graph.facebook.com/<API_VERSION>/<SOLUTION_ID>/access_token?business_id=<CUSTOMER_BUSINESS_PORTFOLIO_ID>' \ -H 'Authorization: Bearer <SYSTEM_TOKEN>'
Placeholder | Description | Example Value |
---|---|---|
| Optional. Graph API version. | v21.0 |
| Required. The onboarded business customer's business portfolio ID. This is included in account_update webhooks when the business customer completes Embedded Signup. |
|
| Required. Your Multi-Partner Solution ID. |
|
| Required. Your system user access token. |
|
Upon success:
{ "data": [ { "access_token": "<CUSTOMER_BUSINESS_TOKEN>" } ] }
You have several options for migrating business customer assets to and from Multi-Partner Solutions. See Migrating business customer assets.