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
Parameter | Type | Description | Optional |
---|---|---|---|
WABAID | string | WABA ID of the business account. | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
WABAID | string | WABA ID of the business account. | No |
PhoneNumber | string | Phone number to be linked without + sign. E.g. 91XXXXXXXXXX | No |
Language | string | Language code | Yes |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneID | string | Unique Identifier for a Phone number | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneID | string | Unique Identifier for a Phone number | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneID | string | Unique Identifier for a Phone number | No |
PhoneNumber | string | Phone number to be linked without + sign. E.g. 91XXXXXXXXXX | No |
Method | string | OTP request method. Possible values: “SMS”, “VOICE” | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneID | string | Unique Identifier for a Phone number | No |
PhoneNumber | string | Phone number to be linked without + sign. E.g. 91XXXXXXXXXX | No |
Code | string | OTP received via SMS or Call | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneID | string | Unique Identifier for a Phone number | No |
PhoneNumber | string | Phone number to be linked without + sign. E.g. 91XXXXXXXXXX | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneNumber | string | Phone number to be linked without + sign. E.g. 91XXXXXXXXXX | No |
SourceWabaID | string | Waba ID of the account the number currently belongs to | No |
DestinationWabaID | string | Waba ID of the account the number needs to be ported to | No |
CountryCode | string | Numerical country code of the number | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneID | string | Unique identifier for a phone | No |
IsEnabled | bool | Bool flag for Cart enabled | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
PhoneID | string | Unique identifier for a phone | No |
IsEnabled | bool | Bool flag for Catalog enabled | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
ClientID | string | Client ID that the number belongs to | No |
Template | object | template body | No |
Template Parameters
Parameter | Type | Description | Optional |
---|---|---|---|
name | string | Template name. Max 512 characters | No |
category | string enum | Template Category. Possible values: AUTHENTICATION, MARKETING, UTILITY | No |
allow_category_change | bool | Set to true to allow us to automatically assign a category. If omitted, the template may be rejected due to miscategorization. | Yes |
language | string enum | Template language and locale code | No |
components | array of objects | Components for Template. Refer Meta docs | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
Limit | string | The maximum number of templates you want returned in each page of results | Yes |
Offset | string | Value of offset cursor in case you’re making a paginated request | Yes |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
ID | string | Template ID | No |
Name | string | Template name | No |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
Start | string(UNIX Timestamp) | The start date for the date range you are retrieving analytics for | No |
End | string(UNIX Timestamp) | The end date for the date range you are retrieving analytics for | No |
Granularity | string | Granularity by which you want to retreive the data. Possible values: “HALF_HOUR”, “DAILY”, “MONTHLY” | No |
PhoneNumbers | array of strings | An 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 |
MetricTypes | array of string | List 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 |
ConversationCategories | array of string | Filter using Conversation categories. Possible values “AUTHENTICATION”, “MARKETING”, “SERVICE”, “UTILITY” | Yes |
ConversationTypes | array of string | Filter 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 |
ConversationDirections | array of string | List of conversation directions. Possible Values: “BUSINESS_INITIATED”, “USER_INITIATED” | Yes |
Dimentions | array of string | List 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 |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
Start | string(UNIX Timestamp) | The start date for the date range you are retrieving analytics for | No |
End | string(UNIX Timestamp) | The end date for the date range you are retrieving analytics for | No |
Granularity | string | Granularity by which you want to retreive the data. Possible values: “HALF_HOUR”, “DAILY”, “MONTHLY” | No |
PhoneNumbers | array of strings | An 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 |
ProductTypes | array of string | The 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 together | Yes |
ConversationCategories | array of string | Filter using Conversation categories. Possible values “AUTHENTICATION”, “MARKETING”, “SERVICE”, “UTILITY” | Yes |
CountryCodes | array of string | The 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 |
ClientID | string | Client ID that the number belongs to | No |
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
Parameter | Type | Description | Optional |
---|---|---|---|
messaging_product | string | Allowed value: “whatsapp” | No |
recipient_type | string | Allowed values: “individual” | No |
to | string | Phone number to send message to | No |
type | string | Allowed values: “text”, “image”, “document”, “audio”, “video”, “location”, “sticker”, “contacts”, “template”, “interactive”, “reaction” | No |
Types
Type | Link |
---|---|
Text | Refer Text message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#text-messages |
Image | Document |
Interactive | Refer Interactive message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#interactive-messages |
Contacts | Refer Contacts message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#contacts-messages |
Location | Refer Location message meta: https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#location-messages |
Template | Refer 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:
- Generate a SHA256 signature using the payload and your latest SystemUserToken.
- 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",
}
}
}
]
}
]
}