Webhook Envelope Schema
Configure webhook path and webhook secret from Dashboard Mantap! (project settings). WA Gateway then delivers events automatically whenever new message and lifecycle events happen.
{
"event": "message",
"device_id": "uuid",
"app_id": "uuid",
"timestamp": "2026-04-22T15:00:00Z",
"request_id": "uuid",
"payload": { ... }
}
When Delivery Happens Automatically
- New inbound or outbound message triggers event
messageautomatically. - Delivery progression triggers event
receiptautomatically. - Device and session lifecycle updates (for example connect, disconnect, logout, warning) are also pushed automatically.
- Delivery is asynchronous so messaging runtime is not blocked by webhook processing.
- Delivery transport for events is always HTTP POST with JSON body (no GET fallback in event pipeline).
Delivery Method and Retry Contract
- Method is fixed to
POSTfor all event deliveries. - Request body is always JSON using
Content-Type: application/json. - Gateway retries on network error, timeout, response read error, and HTTP non-2xx.
- Retry schedule is fixed:
10s,30s,90s. - Delivery stops immediately after first HTTP 2xx response.
- Return HTTP 2xx only after the receiver has durably accepted the event; return non-2xx when persistence or enqueueing fails so retry can run.
- Webhook attempts are stored in
mantap_webhook_logs; useX-WA-Request-IDandpayload.message_idfor reconciliation.
Delivery Preconditions
- If webhook path is empty, payload is not sent to external URL and no delivery failure is recorded.
- If webhook path is relative (starts with
/), base URL must exist (project domain URL or server WEBHOOK_BASE_URL). - If webhook path is full URL (starts with
http://orhttps://), gateway sends directly to that URL. - Do not use malformed format such as
/https://target.example/webhook; usehttps://target.example/webhookdirectly.
Headers You Should Validate
X-WA-Request-ID- unique request ID for tracing and idempotency logs; reused across retries for the same root event.X-WA-Timestamp- UTC RFC3339 timestamp string used in signature generation.X-WA-Signature-sha256=...HMAC signature.X-WA-Signature-Alg- currentlyHMAC-SHA256.
Secret Handling Model
- Webhook secret is never sent as plain value in request headers or body.
- Gateway uses the secret only to generate
X-WA-Signature. - Receiver validates signature using the same secret stored on receiver side.
Event Taxonomy
| Event | Description |
|---|---|
message | Inbound or outbound message details. |
receipt | Status updates for sent messages (for example server, delivered, read). |
message_revoked | Message was revoked/deleted. |
button_response, list_response, interactive_response, poll_response | Interactive reply payloads. |
presence, chat_presence | Presence and typing/media state updates. |
device_qr_generated, device_connected, device_disconnected, device_destroyed | Device lifecycle events. |
logout, warning | Session and platform warnings. |
Message Payload Reference
| Field | Description |
|---|---|
direction | inbound or outbound. |
from, chat | Sender and conversation JID. |
message_id | WhatsApp message ID. |
message_type | text, image, video, audio, document, sticker, contact, location. |
text | Body text or caption mirror. |
mentions | Inbound-only array included when WhatsApp mention metadata exists. Each item includes jid, optional lid, optional display, and start/end offsets into text. |
wa_forwarded, wa_forwarding_score, wa_frequently_forwarded | Forwarded-message metadata from WhatsApp ContextInfo. wa_forwarded is present when WhatsApp marks the message as forwarded; score fields are included when available. |
media_path | Download token/path for /media. |
media_mime_type, media_size, media_filename | Attachment metadata when available. |
is_view_once | View-once indicator. |
contact_name, contact_vcard, contact, contacts | Contact message payload (single or multiple contacts). |
latitude, longitude, location_name, location_address | Location payload fields. |
Mention Metadata Example
When an inbound WhatsApp message contains mentions, the webhook includes explicit metadata so receivers do not need to infer mentions from normalized LID text.
{
"event": "message",
"device_id": "9a0538e6-2b83-4240-aa6f-3553cc60b9c5",
"app_id": "a0ac60b3-6ae4-481e-aecc-36fa6cf3de9c",
"timestamp": "2026-04-29T06:33:42Z",
"request_id": "uuid",
"payload": {
"message_id": "ACDEBCEA391166BCE28A627CE5D3840D",
"chat": "120363426240756992@g.us",
"chat_lid": "120363426240756992@g.us",
"from": "150873745412279@lid",
"from_lid": "150873745412279@lid",
"is_group": true,
"direction": "inbound",
"message_type": "text",
"text": "@257814572359721 test1",
"mentions": [
{
"jid": "257814572359721:74@lid",
"lid": "257814572359721:74@lid",
"display": "Bricki by Brick",
"start": 0,
"end": 16
}
]
}
}
Forward Metadata Example
When WhatsApp marks a message as forwarded, the webhook payload includes explicit metadata so receivers can render attribution without parsing message text.
{
"event": "message",
"device_id": "9a0538e6-2b83-4240-aa6f-3553cc60b9c5",
"app_id": "a0ac60b3-6ae4-481e-aecc-36fa6cf3de9c",
"timestamp": "2026-06-20T03:00:00Z",
"request_id": "uuid",
"payload": {
"message_id": "3EB0FORWARDED123",
"chat": "6285177840342@s.whatsapp.net",
"from": "6281234567890@s.whatsapp.net",
"direction": "inbound",
"message_type": "text",
"text": "Forwarded test message",
"wa_forwarded": true,
"wa_forwarding_score": 1,
"wa_frequently_forwarded": false
}
}
Signature Verification Pattern
signed_payload = X-WA-Timestamp + "." + raw_request_body
expected = "sha256=" + HMAC_SHA256_HEX(webhook_secret, signed_payload)
Reject old timestamps and compare signatures in constant time to reduce replay and tampering risk. Parse timestamp as RFC3339 UTC.
Observability Fields per Delivery Attempt
webhook_url,method,request_id,event,device_id,message_idattempt_number,status_code,latency_msresponse_body(truncated to max 500 chars),error(when present)
Network Allowlist Clarification
- Internal host and IP whitelist in WA service is for internal device-control routes only.
- Webhook callback receiver should enforce source filtering at ingress or reverse proxy when needed.
- Always keep signature validation enabled even on internal VPN traffic.
Consumer Design Best Practices
- Persist message and webhook IDs for idempotent processing.
- Treat webhook ordering as eventually consistent.
- If
media_pathexists, fetch media immediately or queue for retry. - Return a fast 2xx response after enqueueing work; do not block webhook delivery on heavy downstream processing.
- For Mantap Customer Support / Chatwoot gaps, reconcile from
mantap_webhook_logsthrough the backend recovery tool instead of manually replaying WA Web messages.