Event types
Every event an endpoint can subscribe to. Each request body is an event, and data.object is the same resource the API returns.
message.*5
message.receivedObject: messageA customer sent a message to one of your numbers. data.object is the inbound message.
{
"id": "evt_01j9x7q8r9s0t1v2w3x4y5z6a7",
"object": "event",
"type": "message.received",
"version": "2",
"created_at": "2026-10-01T09:29:12Z",
"livemode": true,
"workspace_id": "ws_12",
"data": {
"object": {
"id": "imsg_88213",
"object": "message",
"livemode": true,
"direction": "inbound",
"channel": "whatsapp",
"from": "+966501234567",
"to": "+966112345678",
"type": "text",
"text": {
"body": "مرحبا، أين طلبي؟"
},
"status": "received",
"error": null,
"reference": null,
"conversation_id": null,
"provider_message_id": "wamid.HBgMOTY2NTAxMjM0NTY3FQIAEhgUM0E",
"contact": {
"name": "Sara"
},
"context": null,
"created_at": "2026-10-01T09:29:10Z",
"updated_at": "2026-10-01T09:29:12Z"
}
}
}message.sentObject: messageWhatsApp sent your message. data.previous_attributes.status is the status before.
message.deliveredObject: messageYour message reached the customer's phone.
{
"id": "evt_01j9x7r2m3n4p5q6r7s8t9v0w1",
"object": "event",
"type": "message.delivered",
"version": "2",
"created_at": "2026-10-01T09:30:04Z",
"livemode": true,
"workspace_id": "ws_12",
"data": {
"object": {
"id": "msg_48213",
"object": "message",
"livemode": true,
"direction": "outbound",
"channel": "whatsapp",
"from": "+966112345678",
"to": "+966501234567",
"type": "text",
"text": {
"body": "أهلًا سارة! طلبك جاهز للاستلام 🎉"
},
"status": "delivered",
"error": null,
"reference": "order-10482",
"conversation_id": "conv_311",
"provider_message_id": "wamid.HBgMOTY2NTAxMjM0NTY3FQIAERgSMEM4",
"created_at": "2026-10-01T09:30:00Z",
"updated_at": "2026-10-01T09:30:04Z"
},
"previous_attributes": {
"status": "sent"
}
}
}message.readObject: messageThe customer opened your message. Only sent when the customer shares read receipts.
message.failedObject: messageYour message could not be delivered. data.object.error carries WhatsApp's code and reason (e.g. 131026 undeliverable, 131047 outside the 24-hour window).
contact.*5
contact.createdObject: contactA WhatsApp contact was added, from the portal, an import, a flow or the API. data.object is the contact with its tags and custom fields.
{
"id": "evt_01j9x8a1b2c3d4e5f6g7h8j9k0",
"object": "event",
"type": "contact.created",
"version": "2",
"created_at": "2026-10-01T10:02:03Z",
"livemode": true,
"workspace_id": "ws_12",
"data": {
"object": {
"id": "ct_1052",
"object": "contact",
"phone": "+966501234567",
"email": "sara@example.com",
"first_name": "سارة",
"last_name": "القحطاني",
"language": "ar",
"country": "SA",
"city": "الرياض",
"gender": null,
"birth_date": null,
"notes": null,
"opted_in": true,
"consent": {
"source": "website_form",
"captured_at": "2026-10-01T10:02:00Z"
},
"opted_out_at": null,
"bot_enabled": true,
"tags": [
{
"id": "tag_12",
"name": "عملاء VIP"
}
],
"fields": {
"loyalty_points": "120"
},
"created_at": "2026-10-01T10:02:00Z",
"updated_at": "2026-10-01T10:02:00Z"
}
}
}contact.updatedObject: contactA contact's details, tags or custom fields changed. Several quick changes to one contact arrive as one event carrying the final state.
contact.deletedObject: contactA contact was deleted. data.object is {id, object: "contact", deleted: true}: the details are gone, so delete your copy too.
{
"id": "evt_01j9x8b1c2d3e4f5g6h7j8k9m0",
"object": "event",
"type": "contact.deleted",
"version": "2",
"created_at": "2026-10-02T08:00:00Z",
"livemode": true,
"workspace_id": "ws_12",
"data": {
"object": {
"id": "ct_1052",
"object": "contact",
"deleted": true
}
}
}contact.opted_outObject: contactA contact asked to stop receiving business messages (they sent STOP, or someone opted them out). Queued campaign messages to them are cancelled; stop messaging them from your systems too.
contact.opted_inObject: contactA contact who had opted out agreed again to business messages (they sent START, or their consent was recorded). consent.source says how.
template.*1
template.status_changedObject: templateWhatsApp approved, rejected, paused or disabled one of your templates. data.object is the template; data.previous_attributes.status is where it was; rejection_reason says why when WhatsApp gave a reason.
campaign.*6
campaign.startedObject: campaignA campaign started sending, or was scheduled to. data.object is the campaign.
campaign.pausedObject: campaignA campaign was held, for example because Meta limited the sending number. hold_reason says why; resume it with POST /v1/campaigns/{id}/resume once the cause is fixed. data.object is the campaign.
campaign.resumedObject: campaignA held campaign is sending again. data.object is the campaign.
campaign.completedObject: campaignA campaign finished: every recipient was sent to or failed. stats has the final numbers. data.object is the campaign.
campaign.failedObject: campaignA campaign could not be sent, for example because Meta blocked delivery for a billing reason. data.object is the campaign.
campaign.cancelledObject: campaignA campaign was cancelled; its unsent messages will not go out. data.object is the campaign.
flow.*5
flow.run.startedObject: flow_runA flow started for a customer, from the API, a trigger or the inbox. data.object is the flow_run.
flow.run.handed_offObject: flow_runA flow handed the customer to your team; the conversation now needs a person. data.object is the flow_run.
flow.run.completedObject: flow_runA flow reached its end for a customer. variables holds everything it collected. data.object is the flow_run.
flow.run.expiredObject: flow_runA flow stopped waiting for a customer who did not answer in time. data.object is the flow_run.
flow.responseObject: flow_responseA customer submitted a WhatsApp Flow form. answers holds what they entered. data.object is the flow_response.
conversation.*5
conversation.createdObject: conversationA customer started a new conversation with the workspace. data.object is the conversation.
conversation.needs_agentObject: conversationA conversation is waiting for a person, because the bot handed it over or the customer asked for someone. Page your team, or assign it with POST /v1/conversations/{id}/assign.
{
"id": "evt_01j9x9c1d2e3f4g5h6j7k8m9n0",
"object": "event",
"type": "conversation.needs_agent",
"version": "2",
"created_at": "2026-10-01T09:29:15Z",
"livemode": true,
"workspace_id": "ws_12",
"data": {
"object": {
"id": "conv_311",
"object": "conversation",
"channel": "whatsapp",
"customer": {
"contact_id": "ct_1052",
"address": "+966501234567",
"name": "سارة القحطاني"
},
"number_id": "num_3",
"state": "needs_agent",
"open": true,
"assignee": null,
"unread": true,
"label": null,
"last_customer_message_at": "2026-10-01T09:29:10Z",
"last_agent_message_at": null,
"reply_window_expires_at": "2026-10-02T09:29:10Z",
"resolved_at": null,
"snoozed_until": null,
"created_at": "2026-10-01T09:28:00Z",
"updated_at": "2026-10-01T09:29:12Z"
}
}
}