Webhooks

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.

Requirements

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

messages

Inbound message notifications

statuses

Message status updates

errors

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.

POST /
    
{
  "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. See Errors and Status Messages for more information on any errors you receive.

Example

POST /

{
    "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

code

Error code

Numeric

title

Error title

String

details

Optional. Error details provided, if available/applicable

String

href

Optional. Location for error detail.

String