Skip to content

Concept map· 6 connected terms

Webhook Testing

Also called: Testing WhatsApp webhooks · Webhook replay · Local webhook testing · Test webhook payload

In one line
Exercising a webhook handler before go-live with dashboard test payloads, a local tunnel, signed replays of captured events and Meta's test number.

Reviewed

What is webhook testing?

Webhook testing is checking that your webhook endpoint does the right thing with real-shaped events before customers depend on it — not merely that it passes the verification handshake. A URL that echoes hub.challenge proves only that Meta can reach it; testing proves that it checks signatures, walks batched payloads, handles every message type and status you care about, ignores what it does not, and returns 200 quickly.

Each tool catches different bugs. From WhatsApp > Configuration in the App Dashboard you can send a test payload for a subscribed field — sample data, good for checking routing and parsing. The test business phone number Meta provides when you add WhatsApp to a developer app can message up to five verified recipient numbers, so you can trigger real inbound messages and statuses end to end. A local HTTPS tunnel exposes a laptop server during development, and replaying captured payloads — re-signed in X-Hub-Signature-256 with your app secret — reruns yesterday's bug in a unit test or against staging.

Testing differs from verification: the webhook verification request is a one-time GET proving the URL is yours, while testing exercises the POST path that carries every event afterwards. Meta also notes that some webhooks are not sent while an app is in Development mode, so a test that passes on a Dev-mode app can still miss events once real traffic flows.

Key takeaways

  • Webhook testing proves your endpoint handles real-shaped events correctly, not just that it passes the verification handshake.
  • The App Dashboard sends a sample payload for any subscribed field from WhatsApp > Configuration.
  • Meta's test business number can message up to five verified recipient numbers, enough for end-to-end tests.
  • Replays must be re-signed in X-Hub-Signature-256 over the raw stored bytes, or the signature check fails.
  • Test the failure paths too: duplicates, tampered signatures, a crashing handler and out-of-order statuses.

Replay a captured event against your endpoint

2 / 2
POSThttps://dev-7f3a.tunnel.example.com/webhooks/whatsapp

POST 200 in 240 ms

Request

3 headers · body
POST /webhooks/whatsapp HTTP/1.1
Host: dev-7f3a.tunnel.example.com
Content-Type: application/json
X-Hub-Signature-256: sha256=4f1c9e0b7a2d6c3e8f5a1b9d0c7e2f4a6b8d1c3e5f7a9b0c2d4e6f8a1b3c5d7e
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "102290129340398",
"changes": [
{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919876543210",
"phone_number_id": "106540352242922"
},
"statuses": [
{
"id": "wamid.HBgMOTE5ODEyMzQ1Njc4FQIAERgSMDQ0QjU3RkM2",
"status": "read",
"timestamp": "1760851200",
"recipient_id": "919812345678"
}
]
}
}
]
}
]
}

Response

200 OK
HTTP/1.1 200 OK
Content-Type: text/plain
OK
Try another response
Press Send to replay a signed status webhook at a development endpoint. Switch to the alternatives to see a tampered signature, a crashing handler and a wrong path — each one a delivery Meta would retry.

Response: 200 OK after 240 ms.

Why does webhook testing matter?

Webhook bugs are silent. A handler that crashes on a reaction message or a batched status does not page anyone — it returns 500 while Meta retries for days and customers wait for replies that never come. Testing the real shapes, including failures, duplicates and out-of-order statuses, costs an afternoon before launch; discovering after a campaign that a whole message type never reached the inbox costs far more.

How does webhook testing work?

  1. Unit-test with signed fixtures

    Save one sample payload per field and message type you support — text, interactive reply, media, statuses with errors — and run the handler against them in CI, signed with a test secret.

  2. Expose a development endpoint

    Run the handler behind an HTTPS tunnel or on a staging URL, and point a separate test app (or an override on a test number) at it — never a production app. Meta's docs also describe a throwaway endpoint that only logs payloads: if it shows events your code misses, the bug is in your code.

  3. Send dashboard test payloads

    From WhatsApp > Configuration, send a test payload for each subscribed field and confirm it is routed, logged and acknowledged with a 200.

  4. Run real traffic with the test number

    Message the test number from a verified recipient phone, reply from your app (a Postman collection for the Cloud API makes the outbound calls quick) and watch messages and statuses arrive — including a read that beats its delivered.

  5. Replay, duplicate and break things

    Replay a captured payload twice to prove deduplication, send a tampered body to prove the signature check returns 401, and stop the worker to see the queue absorb a burst.

Webhook testing in code

// replay.mjs — re-send a captured payload to a dev or staging endpoint, correctly signed
import crypto from "node:crypto";
import fs from "node:fs";
const [file, url] = process.argv.slice(2);
const body = fs.readFileSync(file); // raw bytes, exactly as captured
const signature = "sha256=" + crypto
.createHmac("sha256", process.env.APP_SECRET) // the secret your handler verifies with
.update(body)
.digest("hex");
const started = Date.now();
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json", "X-Hub-Signature-256": signature },
body,
});
console.log(res.status, `${Date.now() - started} ms`); // expect 200, fast

Sign the stored bytes, not a re-stringified object, or the signature will never match.

Example: Two bugs caught before launch day

Before launching WhatsApp support, a Bhopal insurance broker's two-person team captured a week of masked payloads from its staging number into fixtures. Replaying them in CI found two bugs: the handler threw on interactive button replies because it only expected text, and a step that re-serialised the body made every replayed signature fail. Both were fixed before go-live. On launch day the only surprise was a sticker message, which the handler logged as unhandled and acknowledged with a 200 — exactly as designed.

Common wrong turns

Common mistakes with webhook testing

  • Testing only the handshake

    A green verification check says nothing about POST handling. Exercise real payloads for every field you subscribe to.

  • Replaying re-serialised JSON

    Pretty-printing or re-stringifying a captured payload changes its bytes, so the signature no longer matches. Store and replay the raw body.

  • Fixtures full of customer data

    Captured payloads contain phone numbers, names and message text. Mask them before fixtures go into a repository or a ticket.

  • Pointing production at a laptop

    A tunnel URL saved on a production app or number sends real customers' messages to a dev machine. Use a separate test app, or an override on a test number only.

  • Never testing failure

    Happy-path tests miss the bugs that cause retry storms. Try a 500, a slow handler, a duplicate and an out-of-order status before launch.

Key facts at a glance

Webhook testing: key facts and limits

Dashboard test
Sample payload per field from WhatsApp > Configuration
Test phone number
Messages up to 5 verified recipient numbers
Replay signature
HMAC-SHA256 of the raw body with the app secret
Endpoint
Public HTTPS with a valid CA-signed certificate
App mode
Some webhooks are not sent in Dev mode
Expected answer
200 for every event, including unhandled types

Good practice

Best practices for webhook testing

  • Keep one fixture per message type and status, plus one batched payload with several entries.
  • Make the replay script part of incident response so you can rerun the exact payload that failed.
  • For load testing, replay captured payloads at several times your expected peak and watch queue depth.
  • Check logs for 'unhandled field' entries after every test run.

Webhook Testing FAQs

How do I test a WhatsApp webhook locally?+
Expose your local server through an HTTPS tunnel and point a test app at it. Meta must reach the endpoint over HTTPS with a valid certificate; unit tests with signed fixtures need no public URL at all.
Does the dashboard test payload come from a real conversation?+
No, it is sample data for the field you pick. Use it to test routing and parsing, then use the test phone number for real end-to-end messages and statuses.
How many people can I message from the test number?+
Up to five recipient numbers. Each one is verified with a code sent to it on WhatsApp before the test number can message it.
Why are my test webhooks not arriving?+
Usually the field is not subscribed, the WABA is not attached to the app, or the app is in Development mode. Meta warns some webhooks are not sent in Dev mode; also check the endpoint answers 200.

See InfiQ pricing

Try it on the official WhatsApp Business API

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.