Skip to content

Receiving messages

You expose one base URL. We append the platform path and POST JSON to it.

Every dispatch carries the shared token you configured:

x-webhook-token: whsec_…

Compare it against your own copy before you parse anything, and reject otherwise. This is the only thing that proves the request came from us.

app.post("/chat/whatsapp/receive", (req, res) => {
if (req.headers["x-webhook-token"] !== process.env.NEIKE_WEBHOOK_TOKEN) {
return res.sendStatus(401);
}
const { event, channel, contact, message } = req.body;
queue.add({ event, channel, contact, message }); // do the work off the request
res.sendStatus(200);
});

message.id is the provider’s message id — the wamid… on WhatsApp, the mid… on Instagram and Messenger. It is stable across retries, so use it as your deduplication key. We already deduplicate on our side, but a retry after a timeout can still reach you twice: your handler must be safe to run again.

As Meta confirms each step, we POST to {base}/chat/whatsapp/update with the provider message id and the new state:

{ "provider_message_id": "wamid.HBgNNTQ5MTEy…", "status": "delivered" }

States are sent, delivered, read and failed. A failed update carries the reason Meta gave. The path is the same for all three channels.

Failed dispatches are retried and recorded. What we tried, what your server answered and when is visible per channel in the console, and a failed event can be replayed once you are back — you do not need to ask us to resend.