WhatsApp Cloud API

Pass WhatsApp webhook verification on the first tryand debug every message after it

The Cloud API handshake fails if your endpoint doesn't echo hub.challenge back exactly. Hooklistener captures the verification request and the response you sent, then keeps recording every message and status update so you can replay them into local code.

24 hrs
Free-form reply window
HTTP 200
Handshake response required
Up to 10 KB
Response body captured

Full visibility into WhatsApp Cloud API webhooks

Meta delivers inbound messages, delivery statuses, and template updates to a single callback URL—but only after your endpoint survives a GET verification handshake and keeps answering with 200 over public HTTPS. One wrong byte in the hub.challenge echo and the App Dashboard rejects your URL with a vague error.

Hooklistener records both sides of every exchange: the request Meta sent and the exact status, headers, and body your endpoint returned. Inspect the nested entry[].changes[].value structure, separate real messages from read receipts, and replay production payloads against your local handler through a CLI tunnel.

Where WhatsApp webhook setups break

The verification handshake fails silently

Meta sends a GET with hub.mode, hub.verify_token, and hub.challenge. You must check the token and return the challenge as the raw response body with a 200—wrapping it in JSON or returning the wrong content fails verification. Hooklistener's response capture shows exactly what you echoed back.

X-Hub-Signature-256 mismatches

Each POST is signed with an HMAC-SHA256 of the raw request body using your App Secret. Frameworks that parse and re-serialize JSON change the bytes and break validation. Inspect the untouched body and signature header side by side to find the drift.

Status updates flood the endpoint

Every outbound message generates sent, delivered, and read callbacks on the same messages field as inbound traffic. Real customer messages get buried in value.statuses noise—Hooklistener lets you inspect and compare both shapes instantly.

Hooklistener for WhatsApp Cloud API developers

Response capture for the handshake

Hooklistener records the HTTP response sent for each captured webhook—status code, headers, and body—so you can confirm the hub.challenge echo character for character. A color-coded status column flags any non-200 reply at a glance.

CLI tunnels for local development

Meta requires a public HTTPS callback URL even during development. Point the App Dashboard at a persistent your-slug.hook.events subdomain and forward traffic to localhost—device-code login, outbound WebSocket, works behind firewalls.

Replay real message payloads

Capture a genuine entry[].changes[].value.messages[] payload once, then replay it with modified body or headers against dev, staging, or local code—no need to text your own number for every iteration.

WhatsApp workflows that benefit most

Customer support inboxes

Free-form replies are only allowed within 24 hours of the customer's last message. Replay captured message payloads with adjusted timestamps to verify your template-fallback logic before the window logic bites in production.

Order and delivery notifications

Track sent, delivered, read, and failed statuses for every outbound notification. Filter status callbacks from inbound messages and confirm your handler updates order state correctly.

Chatbots and interactive flows

Button and list replies arrive as interactive message types nested deep in the payload. Stream them through the Tunnel Traffic Inspector and step through branching logic locally in real time.

Frequently asked questions

Why does Meta say my callback URL couldn't be verified?

During setup Meta sends a GET request with hub.mode=subscribe, hub.verify_token, and hub.challenge query parameters. Your endpoint must confirm the verify token matches and return the hub.challenge value as the plain response body with a 200. Common failures: returning JSON instead of the raw challenge, comparing against the wrong token, or only handling POST. Hooklistener captures the handshake request and shows the exact response your endpoint sent.

Can I test WhatsApp webhooks locally?

Yes. Meta only accepts public HTTPS callback URLs, so point the App Dashboard at a Hooklistener CLI tunnel with a persistent your-slug.hook.events subdomain. Complete verification against the tunnel URL, then forward live messages and status updates straight to your local server—even behind a firewall.

How do I validate the X-Hub-Signature-256 header?

Compute an HMAC-SHA256 of the raw request body using your App Secret and compare it to the header value after the sha256= prefix. The raw bytes matter—middleware that parses and re-encodes JSON will break the comparison. Hooklistener stores the untouched body and headers so you can reproduce the calculation exactly.

How do I tell messages apart from status updates?

Both arrive on the messages webhook field: inbound texts live in entry[].changes[].value.messages[], while delivery receipts live in value.statuses[]. Capture a few of each in Hooklistener and compare them side by side—the AI comparison feature can surface the structural differences and suggest how to branch your handler.

Stop guessing what Meta sent—and what you answered

Capture the verification handshake, inspect nested message payloads, and replay real WhatsApp events into local code. Set up a free endpoint in minutes.