Delivery status webhook
Register a URL and Wamafy calls it whenever a message you sent over the API is delivered, read, clicked or fails. If you would rather ask than be told, use Get message status instead.
Set it up
In the dashboard, go to Settings, Integrations, API Access, Status webhook, enter your URL and save. A signing secret is shown once; keep it to check each call is genuine. It covers templates and replies sent with your API keys. Messages sent from the dashboard, broadcasts and chatbots are not included.
What we send
POST to your URL
{
"event": "message.status",
"messageId": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU",
"to": "919876543210",
"templateName": "order_update",
"status": "delivered",
"errorCode": null,
"errorMessage": null,
"occurredAt": "2026-10-07T10:00:02.000Z"
}Headers include Content-Type: application/json and X-Wamafy-Signature.
| Field | Meaning |
|---|---|
event | Always message.status. Ignore any other value rather than failing on it. |
messageId | The id the send returned. Match on this. |
to | The recipient, digits only. |
templateName | The template that was sent, or null for a reply. |
status | delivered, read, failed or clicked. There is no call for sent; the send response already told you. |
errorCode, errorMessage | WhatsApp's code and reason when status is failed. See Errors for the common ones. |
occurredAt | When Wamafy made this call. Close to the event, but not the exact moment of delivery. |
Handling the calls
- Reply with any
2xxquickly, then do your own work. A call that fails is not sent again. - Calls can arrive out of order (
readbeforedelivered) and can repeat. Store the statuses you have seen for eachmessageIdrather than treating them as a sequence. clickedcomes at most once per message, when a tracked link is first tapped. It is separate fromread.- No
readdoes not mean unread. WhatsApp only reports reads for people with read receipts on.
If your endpoint was down, catch up with Get message status for the messages you are unsure about.