Message body
WhatsApp events arrive as nested JSON:entry, changes, value, then messages.
Verification GET
When you set a deployed webhook URL, HookMyApp checks that your receiver can answer a verification request.Respond with
VERIFY_TOKEN and HTTP 200.Local listen commands skip this check because they send messages to your computer only while the command runs.
Signature verification
Every message delivery POST arrives withX-HookMyApp-Signature-256: sha256=<hex>.Compute HMAC-SHA256 over the raw request body using
WEBHOOK_HMAC_SECRET as the key.This is the HMAC signing secret from
hookmyapp channels env or hookmyapp sandbox env.It is not the
VERIFY_TOKEN.The
VERIFY_TOKEN is only echoed back on the ownership GET probe.Compare the computed value against the hex digest in the header. One POST is never signed: when you run
webhook set, HookMyApp sends an empty-body verification probe marked X-HookMyApp-Probe: webhook-verification (User-Agent HookMyApp-Webhook-Verifier).Answer it with any 2xx before checking signatures, or verification fails. For more detail, see Meta payload validation docs.
Acknowledge fast
Three ways to receive messages
- Listen in the sandbox:
hookmyapp sandbox listen --path /webhook/whatsapptells HookMyApp to send test WhatsApp messages to your local receiver.
Use this with the HookMyApp test number.
Keep the CLI running while you test. - Listen to your own number locally:
hookmyapp channels listen <channel>tells HookMyApp to send messages from your connected WhatsApp number to your local receiver.
Use this to test with your real WhatsApp number before you deploy.
Stop the CLI when you are done. - Your own number, your own URL:
hookmyapp channels webhook set <channel> --url <your-public-https-url>sends messages to your deployed receiver.
Use this after your receiver is live.
Next steps
- Webhook routing: Choose where incoming messages are delivered.
- WhatsApp quickstart: Skip the boilerplate and clone the reference receiver.