Webhook Event Stream

Consume a structured, high-signal stream of messaging, attachment, delivery, and lifecycle events in real time.

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 message automatically.
  • Delivery progression triggers event receipt automatically.
  • 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 POST for 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; use X-WA-Request-ID and payload.message_id for 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:// or https://), gateway sends directly to that URL.
  • Do not use malformed format such as /https://target.example/webhook; use https://target.example/webhook directly.

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 - currently HMAC-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

EventDescription
messageInbound or outbound message details.
receiptStatus updates for sent messages (for example server, delivered, read).
message_revokedMessage was revoked/deleted.
button_response, list_response, interactive_response, poll_responseInteractive reply payloads.
presence, chat_presencePresence and typing/media state updates.
device_qr_generated, device_connected, device_disconnected, device_destroyedDevice lifecycle events.
logout, warningSession and platform warnings.

Message Payload Reference

FieldDescription
directioninbound or outbound.
from, chatSender and conversation JID.
message_idWhatsApp message ID.
message_typetext, image, video, audio, document, sticker, contact, location.
textBody text or caption mirror.
mentionsInbound-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_forwardedForwarded-message metadata from WhatsApp ContextInfo. wa_forwarded is present when WhatsApp marks the message as forwarded; score fields are included when available.
media_pathDownload token/path for /media.
media_mime_type, media_size, media_filenameAttachment metadata when available.
is_view_onceView-once indicator.
contact_name, contact_vcard, contact, contactsContact message payload (single or multiple contacts).
latitude, longitude, location_name, location_addressLocation 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_id
  • attempt_number, status_code, latency_ms
  • response_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_path exists, 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_logs through the backend recovery tool instead of manually replaying WA Web messages.