Operations
Communication
WordPress Plugins
WhatsApp for WordPress
WooCommerce ↔ Relayno Stock
SoonReservations for WordPress
SoonSocial
Facebook Auto-Posting
SoonInstagram Auto-Posting
SoonERP
Odoo Stock Management
SoonREST APIs
WhatsApp API
Stock API
SoonHMS API
SoonCompany
About
Careers
Contact
Relayno forwards all Meta webhook events to your endpoint with HMAC-SHA256 signature verification. Use webhooks to receive incoming messages and delivery receipts in real time.
Register your webhook URL in the Meta Developer Portal under your WhatsApp Business App → Webhooks.
Meta calls GET /webhooks to verify your endpoint (see Endpoint verification below).
Relayno gateway receives POST /webhooks from Meta, verifies the HMAC, then forwards the raw payload to your backend.
Your backend re-verifies the signature and processes the event.
https://api.relayno.com/webhooksMeta hub verification
https://api.relayno.com/webhooksIncoming events
When you register your webhook URL, Meta sends a GET request with a challenge token. Your endpoint must echo back the challenge value as plain text with HTTP 200.
# Meta calls this to verify your webhook endpoint:
GET https://api.relayno.com/webhooks?hub.mode=subscribe&hub.verify_token=YOUR_VERIFY_TOKEN&hub.challenge=abc123
# Gateway forwards to your backend, which responds with hub.challenge
# If the response is not hub.challenge (plain text), Meta rejects the endpoint.Every POST carries an X-Hub-Signature-256 header — HMAC-SHA256 of the raw body signed with your META_APP_SECRET. Always verify before processing.
Read the raw bytes before parsing JSON. Parsers may canonicalize the body, changing whitespace and breaking the signature. Always compute HMAC on the unparsed request body.
# The gateway adds X-Hub-Signature-256 to every POST:
POST /webhooks HTTP/1.1
X-Hub-Signature-256: sha256=abc123...
Content-Type: application/json
{"object":"whatsapp_business_account","entry":[...]}All events follow the Meta Webhooks envelope. Check entry[].changes[].value for message and status data.
// Message received event
{
"object": "whatsapp_business_account",
"entry": [{
"id": "BUSINESS_ACCOUNT_ID",
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": { "display_phone_number": "15551234567", "phone_number_id": "12345" },
"contacts": [{ "profile": { "name": "Alice" }, "wa_id": "212600000000" }],
"messages": [{
"from": "212600000000",
"id": "wamid.xxx",
"timestamp": "1718000000",
"text": { "body": "Hi there!" },
"type": "text"
}]
},
"field": "messages"
}]
}]
}// Delivery status update
{
"object": "whatsapp_business_account",
"entry": [{
"id": "BUSINESS_ACCOUNT_ID",
"changes": [{
"value": {
"statuses": [{
"id": "wamid.xxx",
"recipient_id": "212600000000",
"status": "delivered", // "sent" | "delivered" | "read" | "failed"
"timestamp": "1718000005",
"conversation": { "id": "CONV_ID", "expiration_timestamp": "1718086400" }
}]
},
"field": "messages"
}]
}]
}sentMessage accepted by WhatsApp servers.
deliveredMessage delivered to the recipient's device.
readRecipient opened the message (read receipts enabled).
failedDelivery failed. Check errors[] in the payload for details.
Respond with HTTP 200 immediately — do heavy processing in a background queue. Meta retries events for up to 24 hours if your endpoint returns non-200.
Deduplicate by message ID. Meta may deliver the same event more than once.
Never trust the payload without verifying the HMAC signature.
Use idempotent handlers — a message may arrive multiple times in rare cases.
Set a short response timeout (< 5 s). Long-running handlers cause retry storms.