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.

It is important that your Webhook 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.

Understanding Webhooks

You can use these webhooks in two ways:

If a webhook event isn't delivered for any reason (e.g., the client is offline) or if the webhook request returns a HTTP status code other than 200, we retry the webhook delivery. We continue retrying delivery with increasing delays up to a certain timeout (typically 24 hours, though this may vary), or until the delivery succeeds.


WhatsApp Business API Client Webhooks have a top level array field indicating what is being communicated. The members of the array are JSON objects with detailed fields relevant to the Webhook:

NameObject Description


Used to notify you when you get a new message and what is in the new message.


Used to notify you when there's a status change in a message you sent.


When there are any out-of-band errors that occur in the normal operation of the application, the errors array provides 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. See Errors and Status Messages for more information.

See Components for all available webhook objects.

Get Started


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:

Settings OptionDescription


Required when you are using Webhooks.

Provide the URL for your Webhook. If the Webhook URL is not set, then callbacks are dropped. See the Sample Testing App for a simple way to see and test your Webhooks.

You can validate Webhook events by specifying a shared secret as a query parameter when you set the Webhook URL. Example: https://url?auth='[shared_secret]'.


Specify if you want to receive notifications when a message is received by the server. By default, these notifications are set to off.


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.

Network Rules

The WhatsApp Business API Client sends the Webhook callbacks to you via the Coreapp container. Therefore, your Webhook endpoint needs to be configured to accept inbound requests from the Coreapp.

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"}]}


Inbound Notification

  "contacts": [ {
    "profile": {
        "name": "sender-profile-name"
    "wa_id": "wa-id-of-contact"
  } ],
  "messages": [
    "context": {
         "from": "sender-wa-id-of-context-message",
         "id": "message-id-of-context-message",
         "mentions": [ "wa-id1", "wa-id2" ],
         "forwarded": true | false,
         "frequently_forwarded": true | false
    "from": "sender-wa-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"

For more examples, see Inbound Webhook Notifications.

Message Status Notification

    "id": "ABGGFlA5FpafAgo6tHcNmNjXmuSf",
    "recipient_id": "16315555555",
    "status": "sent"|"delivered"|"read"|"failed"|"deleted",
    "timestamp": "1518694700"

For more examples, see Message Status Notifications.

Error Notification


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


If a Webhook fails to send a callback, the callback is put into a retry queue. Any callbacks sent after the initial callback failure will not be received. It is only after the initial failed callback succeeds that the rest will follow.

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 dedup-ing Webhook messages based on the message ID.

Double-check your pass_through application setting. You won't receive any read status callbacks if you have enabled pass_through with WhatsApp Business API client v2.29.1 or higher.

If you'd like to receive the read status callback, disable the pass_through application setting. Note that by disabling pass_through, your database storage could grow quickly. See the Database Management documentation for more information on managing your database.