Tracking delivery statuses allows you to monitor message deliverability, confirm customer engagement (read receipts), and detect messaging failures in real time. Wazapin pushes these status updates to your HTTPS endpoint via the message.status_update event.

Status transition flow

Outbound messages navigate through the following statuses:
  • queued: The message has been stored in Wazapin’s queue. (Returned immediately by the POST /v1/messages request).
  • sent: Meta/WhatsApp accepted the message.
  • delivered: The message was successfully delivered to the recipient’s phone (double checkmarks in WhatsApp).
  • read: The user opened the message (blue double checkmarks in WhatsApp).
  • failed: The message could not be sent or delivered.

Webhook payload structure

Unlike inbound message webhooks, message.status_update payloads contain the updated status directly in the webhook body. You do not need to call GET /v1/messages/{messageID} to extract the status. Here is an example payload:
message.status_update webhook body
{
  "message_id": "9f1fd66d-c37a-4b50-a8c2-b4dca523f9c8",
  "conversation_id": "0f89b0f9-74b4-44f9-b9b6-48f6d4de57aa",
  "status": "delivered",
  "organization_id": "org_123"
}

Code example

Here is how to catch the webhook and process the status transitions:
# If you miss a webhook, check the status via the API:
curl -X GET "https://api.wazapin.com/v1/messages/9f1fd66d-c37a-4b50-a8c2-b4dca523f9c8/status" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Accept: application/json"

Polling fallback

If your webhook receiver goes offline or you fail to receive a status update webhook, you can query the API directly as a fallback. Wazapin provides two endpoints for status checks:
  1. GET /v1/messages/: Retrieves the full message record including its current status.
  2. GET /v1/messages//status: A lightweight endpoint returning only the status metadata.

Troubleshooting

Status updates arrive out of order

Due to network concurrency, a read status webhook can occasionally arrive before a delivered webhook.
  • Always check the existing status in your database before writing an update.
  • Do not overwrite a terminal status (like read or failed) with an earlier status (like sent or delivered).

Handling failures

When a message status updates to failed, query the full message details using GET /v1/messages/{messageID}. The response will contain an error block (like error_code or failure_reason) explaining why the message could not be sent. Check the Error codes reference for details.