1. Home
  2. Partner
  3. WhatsApp Partner APIs
  • User Guide
  • Developer Docs
Frequently visited sections What is verloop?, FAQ Overview?

WhatsApp Partner APIs

Contents

This document lists all the APIs supported by Verloop for the partners to manage their whatsapp clients, send messages etc. The APIs are categorised into Management APIs and Messaging APIs. Each would require different types of authorization token to be added in the headers.

Note: The path suffixes are to be added to the base root url https://partners.verloop.io/api/v2/whatsapp. The only exception being https://partners.verloop.io/auth to get the auth token.

Authorization

Management APIs

Management APIs can be authorized using system user tokens, these tokens can be generated using /auth endpoint. Which generates a new token if the token isn’t present for a user or returns a previously generated token for the user. The token is set to never expire.

Example Request –

curl --request POST \
    --url https://partners.verloop.io/api/v2/auth \
    --header 'Authorization: '
    --header 'Content-Type: application/json'
    --data '{ "username": "[email protected]", "password": "yourPassH3r3!" }'

Example Response

{
    "system_user_token": "some-uuid"
}

Messaging APIs

Messaging APIs are used to send Messages and Templates using a phone number. For these APIs, you’ll need a phone number token. Phone number token can be generated using /get_phone_token endpoint. The API, just like /auth, either creates a token or returns a previously generated token. In the authorization header, system user token needs to be set.

Example Request –

curl --location 'https://partners.dev.verloop.io/api/v2/whatsapp/get_phone_token?client_id=ClientID&phone_id=SomePhoneID' \
--header 'Accept: application/json' \
--header 'Authorization: system_auth_token' \
--header 'Content-Type: application/json'

Example Response

{
    "token": "some-uuid"
}

Management APIs

These APIs can be used by the partners to manage clients. System auth token is needed to authorize these endpoints.

1. List Clients (GET /list_clients)

List all clients belonging to a partners.

Example Request –

curl --request GET \
  --url https://partners.verloop.io/api/v2/whatsapp/list_clients \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \

Example Response –

{
    "Resp": {
        "Clients": [
            {
                "ClientID": "id"
                "Name": "name"
                "Email": "email"
                "FullName": "full_name"
                "PhoneNumber": "phone_number"
                "OnboardingStatus": "onboarding_status"
                "WabaID": "waba_id"
                "WabaNumbers": ["waba_numbers"]
            },
            {
                "ClientID": "id2"
                "Name": "name2"
                "Email": "email2"
                "FullName": "full_name2"
                "PhoneNumber": "phone_number2"
                "OnboardingStatus": "onboarding_status2"
                "WabaID": "waba_id2"
                "WabaNumbers": ["waba_numbers"]
            }
        ]
    }
}

2. Get Phone Numbers (GET /list_waba_phone_numbers)

List all phone numbers for a WABAID.

List Phone Number parameters

ParameterTypeDescriptionOptional
WABAIDstringWABA ID of the business account.No
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request GET \
  --url https://partners.verloop.io/api/v2/whatsapp/list_waba_phone_numbers?client_id=<client_id>&waba_id=<waba_id> \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json'

Example Response –

{
    "ListWabaPhoneNumbersResponse": {
        "WabaId": "000000000000000",
        "WabaPhoneNumberDetails": [
            {
                "VerifiedName": "Verfied business name",
                "NumberVerificationStatus": 1,
                "DisplayPhoneNumber": "911234567890",
                "PhoneID": "111112222233333",
                "NumberStatus": 1
            }
        ]
    }
}

3. Create Number For Waba (POST /create_number_for_waba)

Once the number is added in the WABA using Meta dashboard, partners can use this API to link the phone number to their verloop app in order to verify and register the number.

Create number parameters

ParameterTypeDescriptionOptional
WABAIDstringWABA ID of the business account.No
PhoneNumberstringPhone number to be linked without + sign. E.g. 91XXXXXXXXXXNo
LanguagestringLanguage codeYes
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/create_number_for_waba \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "WABAID" : "12345678910",
    "PhoneNumber": "911234567899",
    "Language": "EN"
  }'

Example Response –

{
    Success: true
}

4. Get Phone Number (GET /get_phone_number)

Get phone number details for a PhoneID.

Get Phone Number parameters

ParameterTypeDescriptionOptional
PhoneIDstringUnique Identifier for a Phone numberNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request GET \
  --url https://partners.verloop.io/api/v2/whatsapp/get_phone_number?client_id=<client_id>&phone_id=<phone_id> \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json'

Example Response –

{
    "WabaPhoneNumberDetails": {
        "VerifiedName": "Test Number",
        "NumberVerificationStatus": 2,
        "DisplayPhoneNumber": "+1555-XXX-XXXX",
        "PhoneID": "12345678910",
        "NumberStatus": 8,
        "MessagingLimitTier": 3,
        "IsPinEnabled": true,
        "NameStatus": 1
    }
}

5. Delete Phone Number (DELETE /delete_phone_number)

Delete phone number details for a PhoneID.
Note: This only deletes the number from Verloop’s DB. To delete the number from Meta, you’ll need to go to Meta dashboard and manually delete it.

Delete Phone Number parameters

ParameterTypeDescriptionOptional
PhoneIDstringUnique Identifier for a Phone numberNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request DELETE \
  --url https://partners.verloop.io/api/v2/whatsapp/delete_phone_number?phone_id=<phone_id>&client_id=<client_id> \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json'

Example Response –

{
    Success: true
}

6. Get Waba Business Account (GET /get_waba_business_account)

Get WABA details for the WABAID linked to the client Account.

Get Waba Business Account parameters

ParameterTypeDescriptionOptional
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request GET \
  --url https://partners.verloop.io/api/v2/whatsapp/get_waba_business_account?client_id=<client_id> \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json'

Example Response –

{
    "WabaID": "102828102583215",
    "BusinessAccountName": "Test WhatsApp Business Account",
    "AccountStatus": "APPROVED",
    "OnBehalfOfBusinessInfo": {
        "Name": "Verloop",
        "BusinessId": "647311512300466",
        "Status": "APPROVED"
    },
    "TimeZoneID": "America/Los_Angeles"
}

7. Request OTP for Phone Verification (POST /request_otp)

Once the number is added to partner’s client, partner can preoceed with phone number verification. Here’s how to request an OTP for phone number verification.

Request OTP parameters

ParameterTypeDescriptionOptional
PhoneIDstringUnique Identifier for a Phone numberNo
PhoneNumberstringPhone number to be linked without + sign. E.g. 91XXXXXXXXXXNo
MethodstringOTP request method. Possible values: “SMS”, “VOICE”No
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/request_otp \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "PhoneID" : "12345678910",
    "PhoneNumber" : "911234567890",
    "Method": "SMS",
    "ClientID": "client_id"
  }'

Example Response –

{
    Success: true
}

8. Verify OTP for Phone Verification (POST /verify_otp)

Verify OTP request

Verify OTP parameters

ParameterTypeDescriptionOptional
PhoneIDstringUnique Identifier for a Phone numberNo
PhoneNumberstringPhone number to be linked without + sign. E.g. 91XXXXXXXXXXNo
CodestringOTP received via SMS or CallNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/verify_otp \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "PhoneID" : "12345678910",
    "PhoneNumber" : "911234567890",
    "Code": "1234",
    "ClientID": "client_id"
  }'

Example Response –

{
    Success: true
}

9. Register Phone Number (POST /register_number)

In order to make a phone number usable after successful verification, we need to register it.
Not just that, after any change in the phone number, it needs to be registered. These changes include:

  • Display name change

Register Phone Number parameters

ParameterTypeDescriptionOptional
PhoneIDstringUnique Identifier for a Phone numberNo
PhoneNumberstringPhone number to be linked without + sign. E.g. 91XXXXXXXXXXNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/register_number \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "PhoneID" : "12345678910",
    "PhoneNumber" : "911234567890",
    "ClientID": "client_id"
  }'

Example Response –

{
    Success: true
}

10. Migrate Phone Number (POST /migrate_number)

Migrate Number endpoint can be used to move a phone number from one WABA to another

Migrate Phone Number parameters

ParameterTypeDescriptionOptional
PhoneNumberstringPhone number to be linked without + sign. E.g. 91XXXXXXXXXXNo
SourceWabaIDstringWaba ID of the account the number currently belongs toNo
DestinationWabaIDstringWaba ID of the account the number needs to be ported toNo
CountryCodestringNumerical country code of the numberNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/migrate_number \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "CountryCode" : "91",
    "PhoneNumber" : "911234567890",
    "SourceWabaID" : "911234567890",
    "DestinationWabaID" : "911234567890",
    "ClientID": "client_id"
  }'

Example Response –

{
    Success: true
}

11. Set Cart for Phone number (POST /set_cart)

Set Cart enabled/diabled for a Phone number

Set Cart parameters

ParameterTypeDescriptionOptional
PhoneIDstringUnique identifier for a phoneNo
IsEnabledboolBool flag for Cart enabledNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/set_cart \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "PhoneID" : "12345678900012",
    "IsEnabled" : true,
    "ClientID": "client_id"
  }'

Example Response –

{
    Success: true
}

12. Set Catalog for Phone number (POST /set_catalog)

Set Catalog enabled/diabled for a Phone number

Set Catalog parameters

ParameterTypeDescriptionOptional
PhoneIDstringUnique identifier for a phoneNo
IsEnabledboolBool flag for Catalog enabledNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/set_catalog \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "PhoneID" : "12345678900012",
    "IsEnabled" : true,
    "ClientID": "client_id"
  }'

Example Response –

{
    Success: true
}

13. Templates APIs

Message Templates are used to send Template messages or initate conversations with users. There APIs provide means to manage templates for a WABA.

Points to remember

  • Message Template Names: Keep your message template names concise – they can’t be longer than 512 characters.
  • Message Template Content: Make sure your message content is clear and to the point – it’s limited to 1024 characters.
  • Editing Templates: You can only edit templates that are currently approved, rejected, or paused. Additionally, you can only edit a template once per day, with a maximum of 10 edits per month.
  • Template Creation Limits: WhatsApp Business Accounts have a limit of creating 100 message templates per hour.
  • Desktop Viewing Limitations: Templates with 4 or more buttons, or a combination of a quick reply button and other buttons cannot be viewed on WhatsApp desktop clients. – Users will be prompted to switch to their phone to see these messages.

13.1 Create Template (POST /create_template)

Create Template Parameters
ParameterTypeDescriptionOptional
ClientIDstringClient ID that the number belongs toNo
Templateobjecttemplate bodyNo
Template Parameters
ParameterTypeDescriptionOptional
namestringTemplate name. Max 512 charactersNo
categorystring enumTemplate Category. Possible values: AUTHENTICATION, MARKETING, UTILITYNo
allow_category_changeboolSet to true to allow us to automatically assign a category. If omitted, the template may be rejected due to miscategorization.Yes
languagestring enumTemplate language and locale codeNo
componentsarray of objectsComponents for Template. Refer Meta docsNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/create_template \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "ClientID": "client_id",
    "Template": {
        "name": "seasonal_promotion",
        "language": "en_US",
        "category": "MARKETING",
        "components": [
            {
            "type": "HEADER",
            "format": "TEXT",
            "text": "Our {{1}} is on!",
            "example": {
                "header_text": [
                "Summer Sale"
                ]
            }
            },
            {
            "type": "BODY",
            "text": "Shop now through {{1}} and use code {{2}} to get {{3}} off of all merchandise.",
            "example": {
                "body_text": [
                [
                    "the end of August","25OFF","25%"
                ]
                ]
            }
            },
            {
            "type": "FOOTER",
            "text": "Use the buttons below to manage your marketing subscriptions"
            },
            {
            "type":"BUTTONS",
            "buttons": [
                {
                "type": "QUICK_REPLY",
                "text": "Unsubscribe from Promos"
                },
                {
                "type":"QUICK_REPLY",
                "text": "Unsubscribe from All"
                }
            ]
            }
        ]
    }
  }'

Example Response –

{
    "Resp": {
        "id": "572279198452421",
        "status": "PENDING",
        "category": "MARKETING"
    }
}

13.2 List Templates (GET /list_templates)

List templates for the linked WABA

List Template Params
ParameterTypeDescriptionOptional
LimitstringThe maximum number of templates you want returned in each page of resultsYes
OffsetstringValue of offset cursor in case you’re making a paginated requestYes
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request GET \
  --url https://partners.verloop.io/api/v2/whatsapp/list_templates?client_id=<client_id>&limit=<limit>&after=<after> \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json'

Example Response –

{
    "Resp": {
        "data": [
            {
            "name": "seasonal_promotion_text_only",
            "status": "APPROVED",
            "id": "564750795574598"
            },
            {
            "name": "seasonal_promotion_video",
            "status": "PENDING",
            "id": "1252715608684590"
            }
        ],
        "paging": {
            "cursors": {
            "before": "MAZDZD",
            "after": "MgZDZD"
            }
        }
    }
}

13.3 Delete Template (POST /delete_template)

Delete template for the linked WABA. The API requires both ID and Name of the template needed to be deleted since deleting with only Name is not a unique identifier in a template namespace.

Notes
If you delete a template that has been sent in a template message but has yet to be delivered (e.g. because the customer's phone is turned off), the template's status will be set to PENDING_DELETION and we will attempt to deliver the message for 30 days. After this time you will receive a "Structure Unavailable" error and the customer will not receive the message.
Names of an approved template that has been deleted cannot be used again for 30 days.
Delete Template parameters
ParameterTypeDescriptionOptional
IDstringTemplate IDNo
NamestringTemplate nameNo
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request DELETE \
  --url https://partners.verloop.io/api/v2/whatsapp/delete_templates?id=<id>&name=<template_name> \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json'

Example Response –

{
    "Success": true
}

14. Analytics APIs

You can get messaging and conversation analytics with the below 2 APIs. Note that only metrics for business phone numbers associated with your WABA at the time of the request will be included in responses.

14.1 Get Conversation Analytics (POST /get_conversation_analytics)

The conversation_analytics API provides cost and conversation information for a specific WABA.

Get Conversation Analytics parameters
ParameterTypeDescriptionOptional
Startstring(UNIX Timestamp)The start date for the date range you are retrieving analytics forNo
Endstring(UNIX Timestamp)The end date for the date range you are retrieving analytics forNo
GranularitystringGranularity by which you want to retreive the data. Possible values: “HALF_HOUR”, “DAILY”, “MONTHLY”No
PhoneNumbersarray of stringsAn array of phone numbers for which you would like to retrieve analytics. If not provided, all phone numbers added to your WABA are included.Yes
MetricTypesarray of stringList of metrics you would like to receive. If you send an empty list, we return results for all metric types. Possible Values: “COST”, “CONVERSATION”Yes
ConversationCategoriesarray of stringFilter using Conversation categories. Possible values “AUTHENTICATION”, “MARKETING”, “SERVICE”, “UTILITY”Yes
ConversationTypesarray of stringFilter using Conversation types. Possible Values: FREE_ENTRY(Conversations originating from a free entry point), FREE_TIER(Conversations within the monthly free tier), REGULAR(Any conversations that did not originate from a free entry point or are above the monthly free tier allotment)Yes
ConversationDirectionsarray of stringList of conversation directions. Possible Values: “BUSINESS_INITIATED”, “USER_INITIATED”Yes
Dimentionsarray of stringList of breakdowns you would like to apply to your metrics. If you send an empty list, we return results without any breakdowns. Possible values: “CONVERSATION_CATEGORY”, “CONVERSATION_DIRECTION”, “CONVERSATION_TYPE”, “COUNTRY”, “PHONE”Yes
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/get_conversation_analytics \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
  "Start": "1685602800",
  "End": "1688194800",
  "Granularity": "MONTHLY",
  "PhoneNumbers": [],
  "Dimentions": ["CONVERSATION_CATEGORY","CONVERSATION_TYPE","COUNTRY","PHONE"],
  "ClientID": "client",
    }'

Example Response –

{
    "Resp": {
        "conversation_analytics": {
            "data": [
            {
                "data_points": [
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 1558,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "REGULAR",
                    "conversation_direction": "UNKNOWN",
                    "conversation_category": "AUTHENTICATION",
                    "cost": 15.58
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 2636,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "REGULAR",
                    "conversation_category": "MARKETING",
                    "cost": 26.36
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 2238,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "REGULAR",
                    "conversation_category": "SERVICE",
                    "cost": 22.38
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 1782,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "REGULAR",
                    "conversation_category": "UTILITY",
                    "cost": 17.82
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 1568,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "FREE_TIER",
                    "conversation_category": "AUTHENTICATION",
                    "cost": 15.68
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 2716,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "FREE_TIER",
                    "conversation_category": "MARKETING",
                    "cost": 27.16
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 2180,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "FREE_TIER",
                    "conversation_category": "SERVICE",
                    "cost": 21.8
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 1465,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "FREE_TIER",
                    "conversation_category": "UTILITY",
                    "cost": 14.65
                },
                {
                    "start": 1685602800,
                    "end": 1688194800,
                    "conversation": 1433,
                    "phone_number": "15550458206",
                    "country": "US",
                    "conversation_type": "FREE_ENTRY_POINT",
                    "conversation_category": "SERVICE",
                    "cost": 14.33
                }
                ]
            }
            ]
        },
        "id": "102290129340398",
    }
}

14.2 Get Message Analytics (POST /get_message_analytics)

The message_analytics API provides the number and type of messages sent and delivered by the phone numbers associated with a specific WABA

Get Message Analytics parameters
ParameterTypeDescriptionOptional
Startstring(UNIX Timestamp)The start date for the date range you are retrieving analytics forNo
Endstring(UNIX Timestamp)The end date for the date range you are retrieving analytics forNo
GranularitystringGranularity by which you want to retreive the data. Possible values: “HALF_HOUR”, “DAILY”, “MONTHLY”No
PhoneNumbersarray of stringsAn array of phone numbers for which you would like to retrieve analytics. If not provided, all phone numbers added to your WABA are included.Yes
ProductTypesarray of stringThe types of messages (notification messages and/or customer support messages) for which you want to retrieve notifications. Provide an array and include 0 for notification messages, and 2 for customer support messages. If not provided, analytics will be returned for all messages togetherYes
ConversationCategoriesarray of stringFilter using Conversation categories. Possible values “AUTHENTICATION”, “MARKETING”, “SERVICE”, “UTILITY”Yes
CountryCodesarray of stringThe countries for which you would like to retrieve analytics. Provide an array with 2 letter country codes for the countries you would like to include. If not provided, analytics will be returned for all countries you have communicated with.Yes
ClientIDstringClient ID that the number belongs toNo

Example Request –

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/get_message_analytics \
  --header 'Accept: application/json' \
  --header 'Authorization: system_user_token' \
  --header 'Content-Type: application/json' \
  --data '{
  "Start": "1685602800",
  "End": "1688194800",
  "Granularity": "MONTHLY",
  "ClientID": "client",
    }'

Example Response –

{
    "Resp": {
        "analytics": {
            "phone_numbers": [
            "16505550111",
            "16505550112",
            "16505550113"
            ],
            "country_codes": [
            "US",
            "BR"
            ],
            "granularity": "DAY",
            "data_points": [
            {
                "start": 1543543200,
                "end": 1543629600,
                "sent": 196093,
                "delivered": 179715
            },
            {
                "start": 1543629600,
                "end": 1543716000,
                "sent": 147649,
                "delivered": 139032
            },
            {
                "start": 1543716000,
                "end": 1543802400,
                "sent": 61988,
                "delivered": 58830
            },
            {
                "start": 1543802400,
                "end": 1543888800,
                "sent": 132465,
                "delivered": 124392
            }
            # more data points
            ]
        },
        "id": "102290129340398"
    }
}

Messaging APIs

Send Message API

Send messages using Verloop WhatsApp Business API

Send Message Parameters

ParameterTypeDescriptionOptional
messaging_productstringAllowed value: “whatsapp”No
recipient_typestringAllowed values: “individual”No
tostringPhone number to send message toNo
typestringAllowed values: “text”, “image”, “document”, “audio”, “video”, “location”, “sticker”, “contacts”, “template”, “interactive”, “reaction”No
Types
TypeLink
TextRefer Text message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#text-messages
ImageDocument
InteractiveRefer Interactive message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#interactive-messages
ContactsRefer Contacts message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#contacts-messages
LocationRefer Location message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#location-messages
TemplateRefer Template message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-message-templates

Example Send Message Request

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/send_message \
  --header 'Accept: application/json' \
  --header 'Authorization: phone_number_token' \
  --header 'Content-Type: application/json' \
  --data '{
  "messages": [
    {
      "messaging_product": "whatsapp",
      "recipient_type": "individual",
      "to": "string",
      "type": "text",
      "text": {},
      "image": {},
      "document": {},
      "audio": {},
      "video": {},
      "location": {},
      "sticker": {},
      "contact": {},
      "template": {},
      "interactive": {}
    }
  ]
}'

Example Response

{
  "SuccessMessages": [
    {
      "ID": "string",
      "Message": "string"
    }
  ],
  "ErrorMessages": [
    {
      "Error": "string",
      "Message": "string"
    }
  ]
}

Note: Send Template also uses the same send messages API with Type set to Template. Here’s an example of a send template request

curl --request POST \
  --url https://partners.verloop.io/api/v2/whatsapp/send_message \
  --header 'Accept: application/json' \
  --header 'Authorization: phone_number_token' \
  --header 'Content-Type: application/json' \
  --data '{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "12245554792",
  "type": "template",
  "template": {
    "name": "order_delivery_update",
    "language": {
      "code": "en_US"
    },
    "components": [
      {
        "type": "header",
        "parameters": [
          {
            "type": "location",
            "location": {
              "latitude": "37.483307",
              "longitude": "122.148981",
              "name": "Pablo Morales",
              "address": "1 Hacker Way, Menlo Park, CA 94025"
            }
          }
        ]
      },
      {
        "type": "body",
        "parameters": [
          {
            "type": "text",
            "text": "Pablo"
          },
          {
            "type": "text",
            "text": "566701"
          }
        ]
      }
    ]
  }
}'

Webhooks

Messaging/Template Webhooks

You can receive messaging webhooks on the Callback URL specified in the settings page on partners app dashboard.

Once a message is sent to Meta, partner can receive webhook events to get status updates on the messages. Please refer to Meta’s webhook payload docs for details on payload fields.

Validating Payloads

We sign all webhook payloads with a SHA256 signature and include the signature in the request’s X-Partner-Signature-256 header, preceded with sha256=. You don’t have to validate the payload, but you should.

To validate the payload:

  1. Generate a SHA256 signature using the payload and your latest SystemUserToken.
  2. Compare your signature to the signature in the X-Hub-Signature-256 header (everything after sha256=). If the signatures match, the payload is genuine.

Example Incoming Message Webhook event

{
  "object": "whatsapp_business_account",
  "entry": [{
      "id": "WHATSAPP_BUSINESS_ACCOUNT_ID",
      "changes": [{
          "value": {
              "messaging_product": "whatsapp",
              "metadata": {
                  "display_phone_number": PHONE_NUMBER,
                  "phone_number_id": PHONE_NUMBER_ID
              },
              "contacts": [{
                  "profile": {
                    "name": "NAME"
                  },
                  "wa_id": PHONE_NUMBER
                }],
              "messages": [{
                  "from": PHONE_NUMBER,
                  "id": "wamid.ID",
                  "timestamp": TIMESTAMP,
                  "text": {
                    "body": "MESSAGE_BODY"
                  },
                  "type": "text"
                }]
          },
          "field": "messages"
        }]
  }]
}

Example Message Status Webhook event

{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "WHATSAPP_BUSINESS_ACCOUNT_ID",
      "changes": [
        {
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "BUSINESS_DISPLAY_PHONE_NUMBER",
              "phone_number_id": "BUSINESS_PHONE_NUMBER_ID"
            },
            "statuses": [
              {
                "id": "WHATSAPP_MESSAGE_ID",
                "status": "sent",
                "timestamp": "TIMESTAMP",
                "recipient_id": "CUSTOMER_PHONE_NUMBER",
                "conversation": {
                  "id": "CONVERSATION_ID",
                  "expiration_timestamp": "CONVERSATION_EXPIRATION_TIMESTAMP",
                  "origin": {
                    "type": "user_initiated"
                  }
                },
                "pricing": {
                  "billable": true,
                  "pricing_model": "CBP",
                  "category": "service"
                }
              }
            ]
          },
          "field": "messages"
        }
      ]
    }
  ]
}

Template webhook events cover Message Template Status Updates. Please refer to Meta’s template webhook docs to get details about payload fields.

Example Template Webhook Event

{
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "time": <TIMESTAMP>,
      "changes": [
        {
          "value": {
            "event": "APPROVED",
            "message_template_id": <TEMPLATE_ID>,
            "message_template_name": "<TEMPLATE_NAME>",
            "message_template_language": "<LANGUAGE_AND_LOCALE_CODE>",
            "reason": "NONE"
          },
          "field": "message_template_status_update"
        }
      ]
    }
  ],
  "object": "whatsapp_business_account"
}

Message Template Status Update

Status updates on templates.

Template Approved
{
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "time": <TIMESTAMP>,
      "changes": [
        {
          "value": {
            "event": "APPROVED",
            "message_template_id": <TEMPLATE_ID>,
            "message_template_name": "<TEMPLATE_NAME>",
            "message_template_language": "<LANGUAGE_AND_LOCALE_CODE>",
            "reason": "NONE"
          },
          "field": "message_template_status_update"
        }
      ]
    }
  ],
  "object": "whatsapp_business_account"
}
Template Rejected
{
  "object": "whatsapp_business_account"
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "time": <TIMESTAMP>,
      "changes": [
        {
          "value": {
            "event": "REJECTED",
            "message_template_id": <TEMPLATE_ID>,
            "message_template_name": "<TEMPLATE_NAME>",
            "message_template_language": "<LANGUAGE_AND_LOCALE_CODE>",
            "reason": "<REJECTION_REASON>"
          },
          "field": "message_template_status_update"
        }
      ]
    }
  ]
}
Template Scheduled for Disabling
{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "WHATSAPP-BUSINESS-ACCOUNT-ID",
      "time": TIMESTAMP,
      "changes": [
        {
          "field": "message_template_status_update",
          "value": { 
              "event": "FLAGGED",
              "message_template_id": TEMPLATE-ID, 
              "message_template_name": "My message template",
              "message_template_language": "en-US",
              "reason": null,
              "disable_info": {
                  "disable_date": "DATE",
              }
         }
       }
      ]
    }
  ]
}
Updated on April 26, 2024
Was this article helpful?
Not what you are looking for?
Click the link below to submit a support ticket
Submit Ticket
Schedule a demo

Get Started with Verloop.io