Links

Receiving messages via Webhook

This documentation describes how to setup webhooks for the WhatsApp Business API.

Introduction

Webhooks is a mechanism which enables applications to communicate with each other programmatically. It allows you to send real-time data from one application to another whenever a given event occurs. You can use the webhook to determine which endpoint we should forward the real-time data (aka Notifications). Whenever a specific event occurs, the WhatsApp Business API Client sees the event, collects the data, and immediately sends a notification (user-defined HTTP callbacks) to the webhook URL specified.
There are 3 main objects you can receive via webhooks:
  • messages: Used to notify you when you get a new message and what is in the new message.
  • statuses: Used to notify you when there's a status change in a message you sent.
  • errors: When there are any out-of-band errors that occur in the normal operation of the application, this array provides a description of the error.
It is essential that your Webhook URL returns an HTTPS 200 OK response to notifications. Otherwise, the WhatsApp Business API client considers that notification as failed and tries again after a delay.
To deploy a live webhook that can receive events from the WhatsApp Business API client, your code must have HTTPS support and a valid SSL certificate.
Only use asynchronous handling of webhooks
Do not process incoming messages and notifications in the webhook handler; acknowledge immediately after receiving the webhook (with status 200), then you can process the data.
All incoming messages will automatically show as delivered (two grey ticks). To make them appear as read (two colored ticks), you have to mark the messages as read.

Recommendations

For stable functioning of WABA it is recommended make the webhook performance as fast as possible. That means:
  • Design your service to respond as quickly, and as close to your network speed as possible.
  • Respond with a 200 status code immediately after receiving a notification and storing it. The callback's payload should not be processed before responding as this can lead to unacceptable delays; instead, send the response first then (asynchronously) process the payload.
  • Reduce network latency by setting up your webhook server closer to 360dialog's datacenters (Central and Eastern Europe).
  • Sending one message as opposed to getting one causes up to three callback notifications (sent, delivered and read). It means that the speed of processing concurrent requests should increases in accordance with the load of the number. In addition to a direct increase in the speed of processing notifications, we recommend to make your webhook process as many parallel requests as possible. Otherwise, this can lead to the occurrence and overflow of the message queue.

Set Webhook URL

The webhook URL is a resource address to which the WhatsApp Servers sends notifications, which are triggered by specific events. A suitable webhook URL must be supplied by you or by your Partner Software Provider / ISV.
You only need to set your Webhook URL once. Although you can update it or remove it at any time.
If you generate a new API-KEY, the webhook URL for that number will be removed. So you must reset it using the new API-KEY.

Example setting webhook with Basic Auth:

If the webhook URL needs to be authorized by user, USER and PASS should be provided in the header Authorization that contains Basic base64(USER:PASS).
Request body example for USER=testuser and PASS=testpass
Body
{
"url": "https://www.example.com/webhook",
"headers": {
"Authorization": "Basic dGVzdHVzZXI6dGVzdHBhc3M="
}
}

If there is at least one number using Cloud API in this WABA

Webhooks for Cloud API are configured at the WABA level. This webhook URL will receive callbacks for all Cloud API numbers associated with that WABA, but not for any On-premise numbers on the same WABA.
If there is more than one number using Cloud API in a WABA, the webhook must be configured. We strongly suggest that you use it even if there is only one Cloud API number in this WABA.
After using the waba_webhook endpoint, the https://waba-v2.360dialog.io/configs/webhookendpoint (which only configures a webhook per phone number) will be entirely deprecated for all Cloud API numbers associated with the specific WABA. It will still work for On-Premise numbers.
Use the endpoint below to set a Webhook for the whole WABA as soon as a number is onboarded with Cloud API or is moved from On-premise to Cloud API.

Schema

post
https://waba-v2.360dialog.io
/waba_webhook
Set WABA Webhook URL
Webhook URLs for Cloud API do not support "_"(underscore) or ":xxxx"(port)in (sub)domain names. Invalid webhook URL: https://your_webhook.example.com Valid webhook URL: https://yourwebhook.example.com Invalid webhook URL:https://subdomain.your_webhook.example.com:3000 Valid webhook URL: https://subdomain.yourwebhook.example.com
A typical inbound notification for WABA Webhook looks like the following:
{
"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"
},
# Additional arrays and objects
"contacts": [{...}]
"errors": [{...}]
"messages": [{...}]
"statuses": [{...}]
},
"field": "messages"
}]
}]
}
Components (contacts, errors, messages, statuses) are inside entry.changes.value.

Important Information regarding the /waba_webhook endpoint

Only one webhook URL can be configured per WABA, which means that all Cloud API numbers associated with that WABA will receive their webhooks to this specific URL. To differentiate between the webhooks corresponding to different numbers, it's needed to process the data based on the payload.
Once a number moves to Cloud API and the webhook is set using the waba_webhook logic, reverting to the previous On-premise logic (one webhook for each phone number) will not supported.
Example: A business uses the waba_webhook endpoint with the API_KEY#1 for PHONE_NUMBER#1 linked to WABA_ID#1 to set the webhook URL as WABA_WEBHOOK#1. In this case, all Cloud API numbers under WABA_ID#1 will receive their webhook callbacks at WABA_WEBHOOK#1.
From this point onward, any changes to the webhook URL configurations for this WABA should be executed by calling waba_webhook. This applies even to numbers with a different API key under the same WABA (for example, API KEY #2), and it will work identically to the calls made with API_KEY#1.
After the /waba_webhook endpoint is operated, attempts to (v1/config/webhook) for Cloud API will result in the error 400.
All other endpoints (unrelated to webhook configuration) still work exactly the same as before.

Get WABA Webhook URL

Use the GET endpoint below to check the current webhook URL:
get
https://waba-v2.360dialog.io/
waba_webhook
GET Webhook URL for multiple/single Cloud phone number in a WABA

If the phone number is using On-premise API

If you are using On-premise hosting, webhooks are configured at the Phone Number level. The endpoint below will set up the webhook for a specific phone number only.
post
https://[base-url]
/v1/configs/webhook
Set Webhook URL
Request
{
"url": URL,
"headers": {
"header_1": string,
"header_2": string
}
}
If you are using On-Premise hosting, use the base-url waba.360dialog.io.

Get phone number Webhook URL

If the webhook URL is already set, make a GET request to retrieve the existing resource.
get
http://waba.360dialog.io
/v1/configs/webhook
GET phone number Webhook URL

Example

Request
Response
D360-API-KEY: adafABC43
Content-Type: application/json
{
"url": "https://www.example.com/webhook",
"headers": {
"Authorization": "Basic dGVzdHVzZXI6dGVzdHBhc3M="
}
}

Receiving notifications for incoming messages

When a customer sends you a message, the WhatsApp Business API client will send an HTTP POST request notification to the webhook URL with the details that are described in the following documents:
Make sure to check out the Best Practices docs for more information.

Via WABA

After a Webhook is set, you will be able to receive the following events:
  • phone_number_name_update"
  • "phone_number_quality_update"
  • "account_update"
  • "account_review_update"
  • "message_template_status_update"
  • "business_capability_update"
  • "template_category_update"
  • "payment" (if eligible)

Error scenarios

  • 302-redirect: Redirects are not followed by the webhook gateway Please ensure that there is always HTTPS 200 as a response code.
  • SSL-errors: Please ensure that the callback-URLs are using SSL/TLS, and that the certificates are valid and that the certificate chain is complete.
  • You start processing in the callback thread. Please do only acknowledge messages and notifications and start processing in a separate thread.
  • Callbacks will be terminated after a defined timeout and there will be a retry.
  • Duplicates messages can be sent to a WhatsApp webhook as the only guarantee provided is that messages will be received at least once (as opposed to exactly once). If this is affecting how messages are processed on your end, then we suggest deduping webhook messages based on the message_id.