Skip to content

Outgoing webhooks — get WhatsApp events in your app

🛠️ Developer APILevel: Advanced⏱ 7 min

🎯 Goal

Have MeAPI notify your system the moment a customer writes, a message is delivered or read, or someone opts out.

🧰 What you need

  • An https URL on your server that accepts POST requests
Event Sent when
message.received A customer sends a message
message.status A message you sent is sent, delivered, read or failed. Campaign messages count only when the campaign shows them in the inbox
contact.opted_out A customer opts out (STOP)
contact.opted_in A customer opts in again (START)

A new webhook has the first three ticked; tick opted in too if you need it.

  1. Open Developer → Webhooks. Under Add a webhook URL, paste your URL (https, public address) and tick the events.
  2. Copy the signing secret (copy it now, it will not be shown again). New secret makes a new one later.
  3. Click Send test to check your server answers.
  4. On your server, verify every request (below), answer 2xx within 10 seconds, then process it.
  5. Check the Delivery log (Last 50 deliveries): event, status, tries and response. The round arrow retries a delivery by hand.
  6. Switch a webhook Off to pause it without deleting it.
The Developer page. Open the Webhooks tab to see Add a webhook URL with the URL and the events to send.
  • The Developer page. Open the Webhooks tab to see Add a webhook URL with the URL and the events to send.
  • Each webhook has an On/Off switch, Send test, New secret and delete.
  • Delivery log: the last 50 deliveries with event, status, tries and response, and a retry button.

Every request carries these headers:

  • X-MeAPI-Event: the event name,
  • X-MeAPI-Delivery: stable across retries, so deduplicate on it,
  • X-MeAPI-Timestamp,
  • X-MeAPI-Signature: sha256= + HMAC-SHA256 of timestamp + "." + raw body with your secret.
Node.js (Express)
const crypto = require('crypto');
app.post('/meapi', express.raw({ type: 'application/json' }), (req, res) => {
const ts = req.get('X-MeAPI-Timestamp');
const expected = 'sha256=' + crypto.createHmac('sha256', process.env.MEAPI_WEBHOOK_SECRET)
.update(`${ts}.${req.body}`).digest('hex');
const got = req.get('X-MeAPI-Signature') || '';
if (got.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) return res.sendStatus(401);
res.sendStatus(200);
const event = JSON.parse(req.body); // handle it after answering
});

© 2026 MeAPI by TheWebStore028 · RADHAMADHAV WEBSTORE LLP · GSTIN 27ABJFR6148J1ZO · Contact us ·Cookie settings