Message Status Event
Triggered when the delivery status of a message changes. Use this to track message delivery, read receipts, and playback status.
Event Type
message-status
Payload Structure
{
"event": "message-status",
"instanceId": "instance-uuid",
"data": {
"timestamp": 1702500000,
"messageId": "3EB0...",
"status": "READ",
"chat": {
"id": "chat-id",
"jid": "5511888888888@s.whatsapp.net",
"lid": null,
"profilePictureUrl": "https://...",
"name": "John Doe",
"isGroup": false,
"isLid": false
},
"sender": {
"id": "sender-id",
"jid": "5511888888888@s.whatsapp.net",
"lid": null,
"name": "John Doe",
"profilePictureUrl": "https://..."
},
"instanceId": "instance-uuid",
"connectedNumber": "5511999999999"
}
}
Data Fields
| Field | Type | Description |
|---|---|---|
timestamp | number | Unix timestamp of the status change |
messageId | string | WhatsApp message ID |
status | string | New message status |
chat | object | Chat information |
sender | object | Sender information |
instanceId | string | Instance ID |
connectedNumber | string | Connected phone number |
Chat Object
| Field | Type | Description |
|---|---|---|
id | string | Internal chat ID |
jid | string | null | WhatsApp JID (phone@s.whatsapp.net) |
lid | string | null | WhatsApp LID (local identifier) |
profilePictureUrl | string | null | Profile picture URL |
name | string | null | Chat name |
isGroup | boolean | Whether this is a group chat |
isLid | boolean | Whether using LID identifier |
Sender Object
| Field | Type | Description |
|---|---|---|
id | string | Internal sender ID |
jid | string | null | WhatsApp JID |
lid | string | null | WhatsApp LID |
name | string | null | Sender name |
profilePictureUrl | string | null | Profile picture URL |
Status Values
| Status | Description |
|---|---|
UNKNOWN | Status could not be determined |
ERROR | Message failed to send |
PENDING | Message is queued for sending |
SENT | Message sent to WhatsApp servers |
RECEIVED | Message delivered to recipient's device |
READ | Message read by recipient |
PLAYED | Audio/video message played by recipient |
Status Flow
PENDING → SENT → RECEIVED → READ/PLAYED
↓
ERROR
tip
The PLAYED status is only sent for audio and video messages when the recipient plays them.
Example: Tracking Delivery
app.post('/webhook', (req, res) => {
const { event, data } = req.body;
if (event === 'message-status') {
const { messageId, status } = data;
switch (status) {
case 'SENT':
console.log(`Message ${messageId} sent to server`);
break;
case 'RECEIVED':
console.log(`Message ${messageId} delivered`);
break;
case 'READ':
console.log(`Message ${messageId} read by recipient`);
break;
case 'ERROR':
console.log(`Message ${messageId} failed to send`);
break;
}
}
res.status(200).send('OK');
});