Webhooks are user-defined HTTP callbacks that are triggered by specific events. Whenever that trigger event occurs, the WhatsApp Business API client sees the event, collects the data, and immediately sends a notification (HTTP request) to the Webhook URL specified in the application settings updating the status of sent messages or indicating when you receive a message.

This document covers:

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:

It is important that your Webhook returns an HTTPS 200 OK response to notifications. Otherwise the WhatsApp Business API client will consider that notification as failed and try again after a delay.


To deploy a live Webhook that can receive Webhook events from the WhatsApp Business API, your code must have the following:

  • HTTPS support
  • A valid SSL certificate

For information about uploading and retrieving Webhooks CA Certificate, see the Certificates documentation.

Configure Notifications Settings

Following the instructions in the Application Settings documentation, configure the following settings for Webhooks notifications:

  • webhooks: Provide the URL for your Webhook. REQUIRED when you are using Webhooks. If the Webhook URL is not set, then callbacks will be dropped. See the Sample Testing App for a simple way to see and test your Webhooks.
  • sent_status: Specify if you want to receive notifications when a message is received by the server. By default, these notifications are set to off.
  • callback_persist: Select whether to store callbacks on disk until they are successfully acknowledged by the Webhook or not. Notifications that are not successful (no HTTPS 200 response) are retried indefinitely. Use this setting to configure the retry.

Sample Testing App

One way to see the messages sent to your Webhook is to create a cross-platform runtime environment (node.js) and run a server-side JavaScript application (server.js) to implement endpoint handler code to parse the JSON format. The handler will route inbound and outbound message notifications to your Webhook.

You can use any tool of your choosing to see your Webhook in action. We have provided a sample node.js application created in Glitch that you can replicate. Upon "remixing" the project, you will have a new project that uses Express to expose Webhook endpoints that the WhatsApp Business API Client can send to. Follow the steps below to see this in action!

  1. Click this Remix on Glitch button:
    Remix on Glitch
  2. Once the project is created, the URL will be in the form of https://<project-name>.glitch.me (or simply click Show App at the top to navigate to the URL).
  3. Select server.js in the left navigation pane to see the Webhook endpoint implementation.
  4. Click on the Status button in the left navigation pane. You will see that your app is listening on a specific port.
  5. Use the Application Settings to set the Webhook URL to point to your newly created project (Step 2 above). Append /webhook to the project URL as that is the endpoint being exposed (i.e., https://<project-name.glitch.me/webhook).
  6. Send a message or send yourself a test message to see the notification. The following example of the log shows a received text message with a body of "Hi" and a sent message with updated status of sent, then delivered, then read.
    Incoming webhook: {"messages":[{"from":"1234567890","id":"ABGGhSkIc2B_Ago-sDy5BNm-1gI5","text":{"body":"Hi"},"timestamp":"1529381066","type":"text"}]}
    Incoming webhook: {"statuses":[{"id":"gBGGhSkIc2B_AgkXDygfSDwgG5s","recipient_id":"1234567890","status":"sent","timestamp":"1529381072"}]}
    Incoming webhook: {"statuses":[{"id":"gBGGhSkIc2B_AgkXDygfSDwgG5s","recipient_id":"1234567890","status":"delivered","timestamp":"1529381072"}]}
    Incoming webhook: {"statuses":[{"id":"gBGGhSkIc2B_AgkXDygfSDwgG5s","recipient_id":"1234567890","status":"read","timestamp":"1529381076"}]}

General Format of a Webhook

A Webhook will have a top level array field indicating what is being communicated. The members of the array will be JSON objects with detailed fields relevant to the Webhook.

NameObject contents


Inbound message notifications


Message status updates


Serious out-of-band errors

Wherever possible names are kept constant across functions. For example, all timestamps are called timestamp.

Format of the Notifications Webhook

All possible fields of the notifications webhook are shown below. As discussed in the Sample Testing App, you will create a endpoint handler that is triggered by the sending or receiving of a message. As detailed above, full documentation is available here for the two main webhooks: inbound notifications and message statuses. See below for errors.

  "contacts": [ {
    "profile": {
        "name": "sender-profile-name"
    "wa_id": "wa-id-of-contact"
  } ],
  "messages": [
    "context": {
         "from": "sender-wa-id-of-context-message",
         "group_id": "group-id-of-context-message",
         "id": "message-id-of-context-message",
         "mentions": [ "wa-id1", "wa-id2" ]
    "from": "sender-wa-id",
    "group_id": "group-id",
    "id": "message-id",
    "timestamp": "message-timestamp",
    "type": "audio | document | image | location | system | text | video | voice",

    # If there are any errors the errors field (array) will be present.
    # The errors field can be returned as part of any callback event.
    "errors": [ { ... } ],
    "audio": {
        "file": "absolute-filepath-on-coreapp",
        "id": "media-id",
        "link": "link-to-audio-file",
        "mime_type": "media-mime-type",
         "sha256": "checksum"

    "document": {
        "file": "absolute-filepath-on-coreapp",
        "id": "media-id",
        "link": "link-to-document-file",
        "mime_type": "media-mime-type",
        "sha256": "checksum",
        "caption": "document-caption"

    "image": {
        "file": "absolute-filepath-on-coreapp",
        "id": "media-id",
        "link": "link-to-image-file",
        "mime_type": "media-mime-type",
        "sha256": "checksum",
        "caption": "image-caption"

    "location": {
        "address": "1 Hacker Way, Menlo Park, CA, 94025",    
        "latitude": latitude,
        "longitude": longitude,
        "name": "location-name"
    "system": {
        "body": "system-message-content"
    "text": {
        "body": "text-message-content"

    "video": {
        "file": "absolute-filepath-on-coreapp",
        "id": "media-id",
        "link": "link-to-video-file",
        "mime_type": "media-mime-type",
        "sha256": "checksum"
    "voice": {
        "file": "absolute-filepath-on-coreapp",
        "id": "media-id",
        "link": "link-to-audio-file",
        "mime_type": "media-mime-type",
        "sha256": "checksum"

Notifications Errors

When there are any out-of-band errors that occur in the normal operation of the application, the errors array will provide a description of the error. This type of error can be caused by transient network connectivity errors, invalid credentials, management controllers in unavailable status, etc.



    "errors": [ {
       "code": <error-code>,
       "title": "<error-title>",
       "details": "<error-description>",
       "href": "location for error detail"

The errors Object

The errors object contains the following parameters:

Field NameDescriptionType


Error code



Error title



Optional. Error details provided, if available/applicable



Optional. Location for error detail.


Transition Path From Legacy Format

If you used the old API webcallbacks, use this information to transition to the REST API Webhooks.

The Coreapp will decide whether to use the legacy format or the new format based on the webhook: url application setting. If webhook: url is specified, the new format will be used and callbacks will be sent to the configured single Webhook URL. If it is unset and the webcallbacks are set, the application will send to the legacy webcallbacks in the legacy format. Note that if you are using the new REST APIs, only the new REST API Webhooks will be supported.

To transition to new Webhook format, follow this transition path:

  1. Configure the new single Webhook handler and implement code to parse the new JSON data formats described below.
  2. Set the URL to this Webhook handler in the application settings and leave the legacy webcallback settings intact.
  3. Monitor your legacy callback endpoint handlers until they stop getting requests.
  4. Once your legacy callback endpoint handlers have stopped getting requests, disable the legacy style callbacks permanently by removing the callbacks settings using the application settings and take down your legacy callback endpoint handlers.