WhatsApp Webhooks
WhatsApp Webhooks
WhatsApp webhooks integration allows for real-time notifications of message status updates and WhatsApp user engagement.
Go to WhatsApp > Accounts in the left hand menu in your SMSPortal account, click the numbers tab and select webhooks from the actions button where you can configure your Status and Replies per number.
Technical Details
All WhatsApp webhooks are sent as HTTP POST requests with static JSON bodies. Your system must respond with a valid 2xx HTTP response code for us to deem a webhook as successful. The response body is not read or stored by our system.
All failed webhooks are retried up to 5 times with exponential backoff.
NOTE: We will not make breaking changes to our webhook bodies by removing fields, renaming fields, or changing the JSON structure without notice. However, new fields may be added without notice, and we expect all webhook integrations to use robust JSON parsing that can successfully parse and ignore new fields.
All webhooks include the following predefined HTTP headers. Additional custom webhook headers can be configured on the webhook.
Fixed Webhook Headers
| Header | Value | Description |
|---|---|---|
Content-Type | application/json; charset=utf-8 | Indicates the request body is JSON encoded in UTF-8. |
Content-Length | Computed per request | Size of the request body in bytes. |
User-Agent | SMSPortal Webhook Engine | SMSPortal webhook engine user agent. |
Webhook-Engine-Key-Id | Identifier of the signing key used | Specifies which signing key generated the request signature. |
Webhook-Engine-Signature | Signature for this request | Cryptographic signature to verify authenticity. |
Webhook-Engine-Timestamp | When the webhook was signed | Timestamp used for signature validation. |
Webhook-Engine-Retries | Number of retry attempts | Indicates how many times the webhook has been attempted. |
Performance
All webhooks you receive must be processed out of band from the main webhook request/response flow.
Best practice is to:
- Place the received webhook onto an internal queue in your system.
- Immediately respond to the webhook request (~250ms) before starting additional processing.
- Process the webhook data asynchronously afterward.
If our servers do not receive a 2xx response code before we time the request out, we will assume the webhook failed and retry based on the retry scheme.
Webhook Security
There are two ways to improve webhook security:
- IP whitelisting
- Signature validation
Originating IP Addresses
All webhook messages originate from one of the following IP addresses:
105.29.233.2102.205.164.49102.205.166.49
Signature Validation
Signature validation requires an active signature setup via our control panel.
To verify a webhook signature please go through the following steps:
-
Concatenate the
Webhook-Engine-Timestampand the request body as follows:v1:{Timestamp}|{RequestBody} -
Compute the
HMAC-SHA256hash of the previous step, using the key secret as the key for the algorithm. -
The output from the previous step should match the hexadecimal formatted value in the
Webhook-Engine-Signature.
The Webhook-Engine-Signature contains the signature version and the algorithm used to compute the request hash, for example:
v1,hmac_sha256=<signature>
NOTE: If the
Webhook-Engine-Signatureheader equalsv1,hmac_sha256=CANNOT SIGN REQUEST WITHOUT SECRET KEY!
then the account does not have a signature key configured.
Outbound Message States
There are 5 states a WhatsApp message can be in once submitted and accepted by our platform:
-
Submitted
We have received the message and passed it on to Meta for final termination
(There is no webhook for this. the successful response from our rest API is the signal for this state.) -
Sent
This is sent when we are notified by Meta that the message has been sent out to the WhatsApp user and a delivery is expected. -
Delivered
The message has been successfully delivered to the WhatsApp user. -
Read
The message has been read by the WhatsApp user. Not all WhatsApp users have read receipts enabled so not all delivered messages will result in a read status. -
Failed
The message is unable to be delivered. The error code will indicate what the reason for failure was.
Note: If the WhatsApp user has the chat open you may not receive a
Deliveredstatus and only receive aReadstatus, in which case theReadstatus implies the message has beenDelivered.
Webhook Types
All webhooks are sent in batches. Each message in the batch must be handled individually.
Batches cannot partially succeed. Batches cannot succeed partially and if a 2xx response code is received it is assumed the whole batch has been successfully received.
Status Webhooks
Status webhooks notify you when a message has changed status.
All status webhooks are sent as HTTP POST requests with a static JSON body, see the below example.
Example
[
{
"Wamid": "wamid.HBgLMjc3OTkzNDAwMzYVAgARGBJDN0RFMUFDMjlGQkVBNDg5MUEA",
"MessageId": 123456,
"CustomerId": "ed3622cc-91c6-4413-a258-32676b98508c",
"BusinessPhoneNumberId": "891234567890123",
"BusinessDisplayNumber": "27000000001",
"DestinationNumber": "27000000002",
"Status": "Delivered",
"ErrorCode": "",
"ErrorDetail": "No error",
"Timestamp": 1763999491
}
]Fields
| Field | Type | Not Null | Description |
|---|---|---|---|
Wamid | string | ❎ | WhatsApp message ID, only generated after Meta accept the message. |
MessageId | long | ✅ | Smsportal ID, only generated after we accept the message. |
CustomerId | string | ❎ | Optional customer provided ID. |
BusinessPhoneNumberId | string | ✅ | The ID of the business phone number that sent the message. |
BusinessDisplayNumber | string | ✅ | The business phone number shown to the WhatsApp user. |
DestinationNumber | string | ✅ | WhatsApp user's number. |
Status | string | ✅ | Status of the message, one of: Sent, Delivered, Read or Error |
ErrorCode | string | ❎ | Error code (see Outbound Error Codes). |
ErrorDetail | string | ❎ | Error code description. |
Timestamp | long | ✅ | Timestamp of the status update as a UNIX timestamp (the number of seconds that have elapsed since January 1, 1970, midnight UTC/GMT) |
Outbound Error Codes
| Error Code | Description |
|---|---|
Message.Rejected | The message was valid, but was rejected by WhatsApp. |
Message.Invalid | The message failed validation. |
Message.Invalid.Template | The message failed template validation. |
Message.Undeliverable | The message was not delivered to the recipient. |
Message.Undeliverable.RateLimit | The message was not delivered due to rate limiting. |
WabaError | Something on your account is preventing the message from being sent. |
UnknownError | An unknown error occurred, please contact support. |
Reply Webhooks
Reply webhooks notify you when a WhatsApp user has engaged with your WhatsApp Business number.
Examples include:
- A user sends you a message
- A User reacts to a message in the chat
- A user interacts with a template message option you have sent them.
All reply webhooks are sent as HTTP POST requests with a static JSON body.
Note: Responses containing media (images, videos, documents, stickers, voice notes, and audio) will have an ID and a link to download the media content included in the webhook, but the actual media will not be included in the webhook. The link requires the same authentication used to send messages.
Example
[
{
"Wamid": "wamid.HBgLMjc3OTkzNDAwMzYVAgARGBJDN0RFMUFDMjlGQkVBNDg5MUEA",
"BusinessPhoneNumberId": "891234567890123",
"BusinessDisplayNumber": "27000000001",
"SourceNumber": "27000000002",
"ContentType": "text",
"Content": "The reply body",
"ButtonPayload": "OrderId=123",
"PreviousMessage": {
"Wamid": "wamid.HBgLMjc3OTkzNDAwMzYVAgARGBJDN0RFMUFDMjlGQkVBNDg5MUEA",
"Explicit": false
},
"Timestamp": 1763999491,
"Attachments": {
"Media": {
"MediaId": 69000123,
"MimeType": "image/jpeg",
"Link": "https://rest.smsportal.com/whatsapp/media/6900013/download"
},
"Contacts": [
{
"Name": {
"FormattedName": "Joe Soap"
},
"Phones":[
{
"Number": "27810496640",
"Type": "MOBILE"
}
]
}
],
"Location": {
"Latitude": 56.1235,
"Longitude": 12.1231
}
}
}
]Fields
| Field | Type | Not Null | Description |
|---|---|---|---|
Wamid | string | ✅ | Meta message ID. |
BusinessPhoneNumberId | string | ✅ | Meta business phone number ID. |
BusinessDisplayNumber | string | ✅ | Display phone number (the "to" number). |
SourceNumber | string | ✅ | WhatsApp user's phone number (the "from" number). |
ContentType | string | ✅ | Type of the reply, one of: text, reaction, button, location, contact or media. |
Content | string | ✅ | The reply content or the caption of a media message (if it was provided). |
ButtonPayload | string | ❎ | Optional additional data attached to quick reaction message buttons. |
PreviousMessage | object | ❎ | Context information about the previous message being replied to, e.g. the message that was reacted to or explicilty replied to. |
PreviousMessage.Wamid | string | ❎ | The message ID (wamid) of the context message. |
PreviousMessage.Explicit | boolean | ❎ | Indicates whether the reply targeted a specific message. |
Timestamp | long | ✅ | Timestamp of the status update as a UNIX timestamp (the number of seconds that have elapsed since January 1, 1970 midnight UTC/GMT). |
| Attachments | object | ❎ | Rich content attached to the message. |
| Attachments.Media | object | ❎ | Details of the attached Media, used for images, videos, stickers, documents and audio. |
| Attachments.Media.MediaId | long | ❎ | The Id of received media, required to download the media. |
| Attachments.Media.MimeType | string | ❎ | The MIME type of the media. |
| Attachments.Media.Link | string | ❎ | The URL to download the media from (authentication is required). |
| Attachments.Contacts | list | ❎ | A list of contacts attached to the message. |
| Attachments.Contacts.Name | object | ❎ | The details of the name for the contact. |
| Attachments.Contacts.Name.FormattedName | string | ❎ | The formatted name of the contact. |
| Attachments.Contacts.Phones | list | ❎ | A list of phone numbers for the contact. |
| Attachments.Contacts.Phones.Type | string | ❎ | The type of number e.g. CELL or WORK. |
| Attachments.Contacts.Phones.Number | string | ❎ | The phone number. |
| Attachments.Location | object | ❎ | The location attached to the message. |
| Attachments.Location.Latitude | double | ❎ | The latitude of the location pin. |
| Attachments.Location.Longitude | double | ❎ | The longitude of the location pin. |
Updated 1 day ago
