Skip to main content

Public API for WhatsApp Cloud Integration

Introduction

The Public Integration API enables you to query certain info from your WhatsApp Cloud Integration, or perform certain actions without the need to operate in the platform UI.

API Endpoint

Please use the following Endpoint URL for the Public API:
https://api.whatsapp-cloud.woztell.sanuker.com/v1.1/api

Authorization

  1. In "Settings" -> "Channels", click "Edit" to enter the corresponding WhatsApp Cloud channel.
  1. In "Platform", head to the "Advanced Access".
  1. Click "Generate" to generate the access token.
  1. The access token has been generated. The existing access tokens can be managed in the below section.
  1. The access token should be passed as query parameter accessToken, for example:
curl --location --request GET 'https://api.whatsapp-cloud.woztell.sanuker.com/v1.1/api/whatsapp-message-templates?accessToken=${ACCESS_TOKEN}&wabaId=${WABA_ID}&first=10'


GET /waba-info

This API call could get the WABA-related info including WABA name, Phone Number, WABA Namespace, WABA ID of a channel.

Query Parameters

NameTypeDescriptionRequired
channelIdstringChannel IDeither this or wabaID
wabaIdstringWABA IDeither this or channelId

Request

curl --location --request GET '/waba-info?accessToken=${ACCESS_TOKEN}&channelId=${CHANNEL_ID}'

or

curl --location --request GET '/waba-info?accessToken=${ACCESS_TOKEN}&wabaId=${WABA_ID}'

Response

{
"ok": 1,
"result": {
"waId" : "11111111111",
"phoneNumberId" : "123124123232",
"wabaId" : "422126422872292",
"name" : "My Business",
"phoneNumber" : "85212345678",
"phoneNumberCC" : "1",
"formattedPhoneNumber" : "+1 111-111-1111",
"namespace" : "2dwsa4_e24e_42f8_6b5a_110232ae4d5",
"embeddedSignup" : true
}
}

GET /whatsapp-business-profile

This API call could get the business profile of a WhatsApp number.

Query Parameters

NameTypeDescriptionRequired
phoneNumberIdstringPhone number IDtrue

Request

curl --location --request GET '/whatsapp-business-profile?accessToken=${ACCESS_TOKEN}&phoneNumberId=${PHONE_NUMBER_ID}'

Response

{
"ok": 1,
"data": {
"about": "Hello this is John!",
"address": "ABC Building",
"description": "Testing 123",
"email": "testemail@woztell.com",
"profile_picture_url": "IMAGE_URL",
"websites": [
"https://woztell.com/"
],
"vertical": "PROF_SERVICES",
"messaging_product": "whatsapp"
}
}

PATCH /whatsapp-business-profile

This API call could update the business profile of a WhatsApp number.

Query Parameters

NameTypeDescriptionRequired
accessTokenstringAccess token generated from the WhatsApp Cloud channeltrue
phoneNumberIdstringPhone number IDtrue
profileobjectContent to be updated in the business profiletrue
Profile Object
NameTypeDescriptionRequired
messaging_productstringOnly accept whatsapptrue
aboutstringThe "About" textfalse
addressstringThe address of your businessfalse
descriptionstringThe "Description" textfalse
emailstringEmail address of the your businessfalse
verticalstringIndustry of the business, please refer to here for the accepted valuesfalse
websitearrayURL(s) to the website(s) of your business including http:// or https://;
2 websites max.
false
profile_picture_urlstringURL to the profile picturefalse

Request

{
"accessToken": "ACCESS_TOKEN",
"phoneNumberId": "123456890999",
"profile": {
"about": "This is the about text.",
"address": "Office",
"description": "Testing Text",
"email": "test999@woztell.com",
"profile_picture_url": "IMAGE_URL",
"websites": [
"https://woztell.com/blog/", "https://woztell.com/pricing/"
],
"vertical": "PROF_SERVICES",
"messaging_product": "whatsapp"
}
}

Response

{
"ok": 1
}

GET /whatsapp-message-templates

This API call could list out the WhatsApp message templates of a specific WABA with pagination and optional filters.

Query Parameters

NameTypeDescriptionRequired
wabaIdstringTarget WABA IDtrue
firstintegerNumber of messages templates; maximum 100true
afterstringCursor for getting pagination result of the next page; either "after" or "before" should be specifiedfalse
beforestringCursor for getting pagination result of the previous page. Either "after" or "before" should be specifiedfalse
statusstringArray of status to filter out; defaults to: ["APPROVED"], ["PENDING"], ["REJECTED"], ["PENDING_DELETION"], ["DELETED"] if not specifiedfalse
categorystringCategory of the message template: ["TRANSACTIONAL"], ["MARKETING"] or ["OTP"]false
quality_scoreStringQuality rating of the template: GREEN, YELLOW or REDfalse
languagearrayLanguage of message template; must be in array and in the supported language code such as en_US, es.false
namestringName search of the message templatefalse
contentContentContent search of the message templatefalse
name or contentstringName or content search of the message templatesfalse

Request

curl --location --request GET '/whatsapp-message-templates?accessToken=${ACCESS_TOKEN}&wabaId=${WABA_ID}&first=10&after=MAZDZD&status=["APPROVED"]'

Response

"ok": 1,
"data": [
{
"id": "363730401994967",
"name": "sample_flight_confirmation",
"category": "TICKET_UPDATE",
"languages": [
"pt_BR",
"es",
"id",
"en_US"
],
"statuses": [
{
"language": "pt_BR",
"status": "APPROVED"
},
{
"language": "es",
"status": "APPROVED"
},
{
"language": "id",
"status": "APPROVED"
},
{
"language": "en_US",
"status": "APPROVED"
}
],
"templates": [
{
"language": "pt_BR",
"status": "APPROVED",
"rejected_reason": "NONE",
"components": [
{
"type": "HEADER",
"format": "DOCUMENT"
},
{
"type": "BODY",
"text": "Esta é a sua confirmação de voo para {{1}}-{{2}} em {{3}}."
},
{
"type": "FOOTER",
"text": "Esta mensagem Γ© de uma empresa nΓ£o verificada."
}
],
"quality_score": {
"score": "UNKNOWN"
}
},
{
"language": "es",
"status": "APPROVED",
"rejected_reason": "NONE",
"components": [
{
"type": "HEADER",
"format": "DOCUMENT"
},
{
"type": "BODY",
"text": "Confirmamos tu vuelo a {{1}}-{{2}} para el {{3}}."
},
{
"type": "FOOTER",
"text": "Este mensaje proviene de un negocio no verificado."
}
],
"quality_score": {
"score": "UNKNOWN"
}
},
{
"language": "id",
"status": "APPROVED",
"rejected_reason": "NONE",
"components": [
{
"type": "HEADER",
"format": "DOCUMENT"
},
{
"type": "BODY",
"text": "Ini merupakan konfirmasi penerbangan Anda untuk {{1}}-{{2}} di {{3}}."
},
{
"type": "FOOTER",
"text": "Pesan ini berasal dari bisnis yang tidak terverifikasi."
}
],
"quality_score": {
"score": "UNKNOWN"
}
},
{
"language": "en_US",
"status": "APPROVED",
"rejected_reason": "NONE",
"components": [
{
"type": "HEADER",
"format": "DOCUMENT"
},
{
"type": "BODY",
"text": "This is your flight confirmation for {{1}}-{{2}} on {{3}}."
},
{
"type": "FOOTER",
"text": "This message is from an unverified business."
}
],
"quality_score": {
"score": "UNKNOWN"
}
}
]
}
],
"paging": {
"cursors": {
"before": "MAZDZD",
"after": "MAZDZD"
},
"hasNext": true,
"hasPrevious": false
}
}

PUT /whatsapp-message-template

This API call could create a brand new WhatsApp message template.

NOTE

Each WhatsApp Business account is allowed to create 100 message templates per hour.

Query Parameters

NameTypeDescriptionRequired
wabaIdstringWABA IDtrue
accessTokenstringAccess token generated from the WhatsApp Cloud channeltrue
namestringName of the message templatetrue
languagestringLanguage of the message templatetrue
categorystringCategory of the message template: TRANSACTIONAL, MARKETING or OTPtrue
componentsarrayContent of the message template. Please refer to here for the structure of the component.true
NOTES

By inserting the image URL into "example":{"header_handle":["IMAGE_URL"]}, this API will automatically upload the example while creating the message template for you.

Request

Sample Request (Image Header)

{
"wabaId": "190787529545503",
"accessToken": "ACCESS_TOKEN",
"name": "test_template",
"language": "en_US",
"category": "MARKETING"
"components": [
{
"type": "BODY",
"text": "Hi there! Are you interested in our latest promotional sale?"
},
{
"type": "HEADER",
"format": "IMAGE",
"example":{"header_handle":["IMAGE_URL"]}
}
]
}

Sample Request (Parameters, Footer and Call to Actions Buttons)

{
"wabaId": "190787529545503",
"accessToken": "ACCESS_TOKEN",
"name": "test_template",
"language": "en_US",
"category": "MARKETING"
"components": [
{
"type": "BODY",
"text": "hello {{1}} this is body template",
"example":{"body_text":[["Test"]]}
},
{
"type": "FOOTER",
"text": "this is footer template"
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "PHONE_NUMBER",
"text": "Call",
"phone_number":"+85212769072"
},
{
"type": "URL",
"text": "URL",
"url":"https://www.woztell.com/"
}
]
}
]
}

Sample Request (Parameters and Quick Reply Buttons)

{
"wabaId": "190787529545503",
"accessToken": "ACCESS_TOKEN",
"name": "test_template",
"language": "en_US",
"category": "MARKETING"
"components": [
{
"type": "BODY",
"text": "hello {{1}} this is body template",
"example":{
"body_text":[["Test"]]
}
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "yes"
},
{
"type": "QUICK_REPLY",
"text": "no"
}
]
}
]
}

Response

{
"ok": 1,
"id": "516723536625510",
"language": "en_US"
}

PATCH /whatsapp-message-template

This API call could edit an existing message template.

NOTE

A message template can only be edited once in a 24 hour window, and up to 10 times in a 30 day window.

Query Parameters

NameTypeDescriptionRequired
wabaIdstringWABA IDtrue
accessTokenstringAccess token generated from the WhatsApp Cloud channeltrue
messageTemplateNamestringName of the message templatetrue
messageTemplateLanguagestringLanguage of the message templatetrue
messageTemplateIdstringUnique ID of the message templatetrue
componentsarrayContent to be updated to the message templatetrue
NOTES

Each language version of a message template has its own ID. In order edit a message template with PATCH /whatsapp-message-templates, you will need to specify the language version of the template.

Normally, GET /whatsapp-message-templates will only return the ID of the most recent language. Therefore, you should first obtain the ID of a particular language by applying the language filter in GET /whatsapp-message-templates.

Request

{
"wabaId": "12986521265530",
"accessToken": "ACCESS_TOKEN",
"messageTemplateLanguage": "en_US",
"messageTemplateName": "test_template",
"messageTemplateId": "1748340935544945",
"components": [
{
"type": "BODY",
"text": "Winter's coming, it's time to check out our latest winter collection!"
}
]
}

Response

{
"ok": 1,
"success": true
}

DEL /whatsapp-message-template

This API call could delete an existing message template.

Query Parameters

NameTypeDescriptionRequired
wabaIdstringWABA IDtrue
accessTokenstringAccess token generated from the WhatsApp Cloud channeltrue
namestringName of the message templatetrue

Request

{
"wabaId": "12986521265530",
"accessToken": "ACCESS_TOKEN",
"name": "test_template"
}

Response

{
"ok": 1,
"success": true
}

PUT /media-id

This API call could upload a media file to WhatsApp server, in order to obtain a media ID.

NOTE

The uploaded media file will be kept in WhatsApp Cloud server for 30 days. After the expiration, users need to upload again to obtain another media ID.

Query Parameters

NameTypeDescriptionRequired
phoneNumberIdstringPhone number IDtrue
accessTokenstringAccess token generated from the WhatsAptrue
typestringimage, audio, video, filetrue
urlstringLink to the media filetrue

Request

{
"phoneNumberId": "123164329653069",
"accessToken": "ACCESS_TOKEN",
"type": "image",
"url": "MEDIA_URL",
}

Response

{
"ok": 1,
"mediaId": "5770270532993662",
"fileType": "image"
}

GET/conversation-analytics

This API is for retrieving the conversation analytics within the selected date range.

NOTES

GET/conversation-analytics is supported in https://api.whatsapp-cloud.woztell.sanuker.com/v1.2/api/

Authentication

To perform authentication for this Public Integration API, it is needed to utilize the corresponding Payload and SignedContext which is required by the integration.

  • Payload: a JSON stringify instance
  • SignedContext: (signature).{{base64(JSON.stringify(payload))}}
    1. Obtain the information related to the Inbox Integration by querying the installedIntegrations with Open API.

Request:

query {
apiViewer{
installedIntegrations{
appId
_id
signature
integrationId
}
}
}

Response:

{
"data": {
"apiViewer": {
"installedIntegrations": [
{
"appId": "62062c0b717195320192b18f7",
"_id": "6420fig28e65b466d4607ea2",
"signature": "mKq60mpKn/YzaP5123tWU+AWX65LqT6BHkBIfq9d3os=",
"integrationId": "inbox"
}
]
}
}
}
  1. Create Payload with in the following format:

    {"appIntegration":"appIntegrationId","app":"appId"}

Example Payload:

{"appIntegration":"6420fig28e65b466d4607ea2","app":"62062c0b717195320192b18f7"}
  1. Encode the Payload Base64 format

  2. Combine the encoded Payload and Signature in order to create the SignedContext in the following format:

    (signature).{{base64(JSON.stringify(payload))}}

Example SignedContext

WAIBCzM6tnzboIwkEPAVVyaVq7VGaIKBaQ/Q+gP6qdA=.eyJhcHAiOiI2MjA2MmMwYjcxNzE5NTMyMDE5MmIxOGY3IiwiYXBwSW50ZWdyYXRpb24iOiI2NDIwZmlnMjhlNjViNDY2ZDQ2MDdlYTIiLCJjaGFubmVsIjoiNzIxZjMyYWM0ZTEyMzYzZGUxMjBkMjlkIg==
  1. Add them to the header as the X-Woztell-Payload and X-Woztell-SignedContext.

Query Parameters

NameTypeDescriptionRequired
fromUNIX TimestampThe start date for the target date rangeYes
toUNIX TimestampThe end date for the target ate rangeYes
granularitystringThe granularity by which you would like to retrieve the analytics; HALF_HOUR, DAILY or MONTHLYYes
numbersarrayThe list of phone number(s) to get the analytics fromNo
metric_typesstringList of metrics to retrieve; COST and CONVERSATIONNo
conversation_typesstringList of conversation; FREE_ENTRY_POINT, FREE_TIER, REGULAR and UNKNOWNNo
conversation_directionsstringList of direction of initiating the conversation; business_initiated and uesr_initiatedNo
dimensionsstringList of breakdown to apply to the analytics; phone, country, conversation_type and conversation_reactionNo

Request

https://api.whatsapp-cloud.woztell.sanuker.com/v1.2/api/conversation-analytics?from=1651200978632&to=1851220649059&granularity=DAILY&numbers=14132521446&metric_types=COST,CONVERSATION&conversation_types=FREE_ENTRY_POINT,FREE_TIER,REGULAR,UNKNOWN&conversation_directions=business_initiated,user_initiated&dimensions=phone,country,conversation_type,conversation_direction

Response

{
"ok": 1,
"conversationAnalytics": {
"data_points": [
{
"start": 1672675200,
"end": 1672761600,
"conversation": 1,
"phone_number": "14132521446",
"country": "HK",
"conversation_type": "FREE_TIER",
"conversation_direction": "USER_INITIATED",
"cost": 0
},
{
"start": 1664899200,
"end": 1664985600,
"conversation": 1,
"phone_number": "14132521446",
"country": "HK",
"conversation_type": "FREE_TIER",
"conversation_direction": "BUSINESS_INITIATED",
"cost": 0
},
{
"start": 1676476800,
"end": 1676563200,
"conversation": 1,
"phone_number": "14132521446",
"country": "HK",
"conversation_type": "FREE_TIER",
"conversation_direction": "USER_INITIATED",
"cost": 0
}
]
}
}