Webhooks and events
Webhook events: scan.whatsapp and meta.whatsapp
There are two webhook event types, named in the X-Whatsappx-Event header: scan.whatsapp for numbers linked by QR code and meta.whatsapp for Cloud API numbers.
What does scan.whatsapp contain?
Sent for each new incoming message on a number linked by QR code, as soon as it arrives. Messages you send, and the history synced right after linking, are not sent.
| Field | Type | Description |
|---|---|---|
event | string | Always message.inbound. |
channel | string | Always scan. |
workspace_id | uuid | Workspace that received the message. |
conversation_id | uuid | Conversation in whatsappx.si; use it with the conversation and message endpoints. |
whatsapp_message_id | string | WhatsApp message id. Use it to deduplicate. |
chat_jid | string | WhatsApp id of the chat (…@s.whatsapp.net for a person, …@g.us for a group). |
sender_jid | string | WhatsApp id of the sender (differs from chat_jid in groups). |
sender_name | string | Sender’s display name, when known (may be empty). |
content | string | Message text, or the caption of an image or document. |
message_type | string | text, image or document. |
media_url | string | Path of the stored media file (/api/media/<workspace>/<file>), or empty. |
mime_type | string | MIME type of the media, or empty. |
file_name | string | Document file name, or empty. |
file_size | integer | Media size in bytes, or 0. |
timestamp | string | When the message was sent, RFC 3339 in UTC. |
is_group | boolean | true for group messages. |
chat_name | string | Contact or group name, when known. |
chat_phone | string | Phone number of a one-to-one chat (digits), when known. |
Example scan.whatsapp delivery
POST /whatsappx/webhook HTTP/1.1
Content-Type: application/json
User-Agent: Whatsappx-Webhook-Forwarder/1.0
X-Whatsappx-Event: scan.whatsapp
X-Hub-Signature-256: sha256=5d2c…
{
"event": "message.inbound",
"channel": "scan",
"workspace_id": "8d0f6c2e-3b1a-4c55-9a7e-2f4b6d1e9c30",
"conversation_id": "6a1f3c52-8e0b-4d7a-b1f2-93c4d5e6f708",
"whatsapp_message_id": "3EB0A1B2C3D4E5F60718",
"chat_jid": "15550100123@s.whatsapp.net",
"sender_jid": "15550100123@s.whatsapp.net",
"sender_name": "Jordan Lee",
"content": "Is my order ready for pickup?",
"message_type": "text",
"media_url": "",
"mime_type": "",
"file_name": "",
"file_size": 0,
"timestamp": "2026-10-02T14:31:07Z",
"is_group": false,
"chat_name": "Jordan Lee",
"chat_phone": "15550100123"
}What does meta.whatsapp contain?
For Cloud API numbers, whatsappx.si forwards Meta’s webhook payload unchanged: the same JSON your own Meta app would receive (object, entry[].changes[].field and value). Use Meta’s WhatsApp Cloud API webhook reference to parse it.
- It is forwarded only after Meta’s own signature on the request has been checked.
- It covers the
messagesfield (incoming messages and anything else Meta sends in that field) and themessage_template_status_updateandmessage_template_quality_updatefields. - A payload is forwarded once per workspace, even when it contains several changes.
- The
X-Hub-Signature-256header you receive is whatsappx.si’s signature with your webhook secret, not Meta’s.
Example meta.whatsapp delivery (shortened)
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "102345678901234",
"changes": [
{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "15550100999",
"phone_number_id": "109876543210987"
},
"contacts": [
{
"profile": {
"name": "Jordan Lee"
},
"wa_id": "15550100123"
}
],
"messages": [
{
"from": "15550100123",
"id": "wamid.HBgL…",
"timestamp": "1790951467",
"type": "text",
"text": {
"body": "Is my order ready for pickup?"
}
}
]
}
}
]
}
]
}