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:
For information about uploading and retrieving Webhooks CA Certificate, see the Certificates documentation.
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.https://url?auth='[shared_secret]'
.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.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!
https://<project-name>.glitch.me
(or simply click Show App at the top to navigate to the URL).server.js
in the left navigation pane to see the Webhook endpoint implementation./webhook
to the project URL as that is the endpoint being exposed (i.e., https://<project-name.glitch.me/webhook
).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"}]}
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.
Name | Object 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
.
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", "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" } ] }
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.
POST / { "errors": [ { "code": <error-code>, "title": "<error-title>", "details": "<error-description>", "href": "location for error detail" }, { ... } ] }
errors
ObjectThe errors
object contains the following parameters:
Field Name | Description | Type |
---|---|---|
| Error code | Numeric |
| Error title | String |
| Optional. Error details provided, if available/applicable | String |
| Optional. Location for error detail. | String |
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 will retry the webhook delivery. We will continue retrying delivery with increasing delays up to a certain timeout (typically 24 hours, though this may vary), or until the delivery succeeds.
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.
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.