Skip to main content

WABA Webhooks

Agent Skill

Automate this endpoint with an AI agent using the 2chat-whatsapp-waba skill:

npx skills add 2ChatCo/agent-skills -s 2chat-whatsapp-waba

In here you can see what a WhatsApp Business API (WABA) webhook event has as payload.

Message Sent

Triggers when a new WhatsApp message is sent.

The sent_by field will be api when the message was sent via the API, or agent when sent through the 2Chat interface.

The to_number field is the phone number of the recipient.

{
"id": "MSG42c01a92-ace3-4de3-a5e9-2fbbf8b22d25",
"uuid": "MSG42c01a92-ace3-4de3-a5e9-2fbbf8b22d25",
"session_key": "WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"message": {
"text": "Hola Carlos desde API"
},
"created_at": "2026-02-18T18:01:35",
"remote_phone_number": "+595986541230",
"_2chat_link": "https://app.2chat.io/live-chat/STEc5ca017c-6e16-4e1a-9960-c180b1f51682/WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"channel_phone_number": "+16173518454",
"sent_by": "api",
"event": "whatsapp.waba.message.sent",
"channel": {
"uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"friendly_name": "2Chat Gupshup Integration",
"iso_country_code": "US",
"verified_name": "APPROVED",
"phone_number": "+16173518454",
"connection_status": "C",
"created_at": "2025-11-19 23:04:18",
"updated_at": "2026-02-02 19:41:12"
},
"to_number": "+595986541230",
"contact": {
"uuid": "CONc1f24408-ad5b-4168-89d1-3a258f784fbe",
"first_name": "Carlos",
"last_name": "Gimenez",
"name": "Carlos Gimenez",
"channel_uuid": null,
"profile_pic_url": "https://2chat-user-data.s3.amazonaws.com/ACC91be87af-5a29-4034-b599-342f2aeb5d52/pp/contacts/example.jpeg",
"last_updated": "2026-01-05T13:03:43Z"
}
}

Message Received

Triggers when a new WhatsApp message is received on your WABA number.

The sent_by field will be user because the message originates from the contact, and remote_phone_number is the phone number of the person who sent you the message.

{
"id": "MSG1e265247-8c72-5020-98ac-9bbdf562ad36",
"uuid": "MSG1e265247-8c72-5020-98ac-9bbdf562ad36",
"session_key": "WA-WAN7c43ea2d-f225-45d2-bda9-60f4746f1572-14085550176",
"message": {
"text": "Hello"
},
"created_at": "2026-07-28T19:25:23",
"remote_phone_number": "+14085550176",
"_2chat_link": "https://app.2chat.io/live-chat/STEc5ca017c-6e16-4e1a-9960-c180b1f51682/WA-WAN7c43ea2d-f225-45d2-bda9-60f4746f1572-14085550176",
"channel_phone_number": "+13024855297",
"sent_by": "user",
"contact": {
"first_name": null,
"last_name": null,
"profile_pic_url": null,
"friendly_name": "Carlos",
"device": null
}
}

Order Received

Triggers when a contact places an order from your catalog on your WABA number, by checking out the cart in the WhatsApp product catalog.

This event replaces whatsapp.waba.message.received for that message: an order fires whatsapp.waba.message.order.received only, so you never receive both for the same order.

The order itself travels inside message.order, and message.text carries the note the contact typed at checkout (often an empty string). The sent_by field is user because the order originates from the contact.

{
"id": "MSG0d47c1b8-3f92-4a51-b6c7-8e2d5a91f043",
"uuid": "MSG0d47c1b8-3f92-4a51-b6c7-8e2d5a91f043",
"session_key": "WA-WAN8f21cc03-5d7a-4e19-bb62-1a3f9e0d7c48-14085550176",
"message": {
"text": "Please deliver after 6pm",
"order": {
"catalog_id": "1284930175620394",
"text": "Please deliver after 6pm",
"currency": "USD",
"total": 511.0,
"products": [
{
"product_retailer_id": "SKU-BAG-001",
"name": "ADIDAS | CLASSIC BACKPACK | LEGEND INK MULTICOLOUR",
"price": 150.5,
"quantity": 2,
"currency": "USD",
"thumbnail_url": "https://2chat-user-data.s3.amazonaws.com/order/product/SKU-BAG-001.jpeg"
},
{
"product_retailer_id": "SKU-CAP-014",
"name": "SKU-CAP-014",
"price": 210.0,
"quantity": 1,
"currency": "USD"
}
]
}
},
"created_at": "2026-07-28T19:25:23",
"remote_phone_number": "+14085550176",
"_2chat_link": "https://app.2chat.io/live-chat/STE3a9f1c47-8b2e-4d61-9f03-6c5a4e21d8b7/WA-WAN8f21cc03-5d7a-4e19-bb62-1a3f9e0d7c48-14085550176",
"channel_phone_number": "+16195550143",
"sent_by": "user",
"contact": {
"first_name": null,
"last_name": null,
"profile_pic_url": null,
"friendly_name": "Carlos",
"device": null
},
"event": "whatsapp.waba.message.order.received",
"channel_uuid": "WAN8f21cc03-5d7a-4e19-bb62-1a3f9e0d7c48",
"message_uuid": "MSG0d47c1b8-3f92-4a51-b6c7-8e2d5a91f043"
}

The message.order object

FieldDescription
catalog_idThe identifier of the catalog the contact ordered from
textThe note the contact typed at checkout. Usually an empty string
currencyThe currency of the order, taken from the first product that reports one. null when no product carries a currency
totalThe sum of price × quantity across every product, rounded to 2 decimals
productsThe list of ordered products. See the table below

Each entry of products has these fields:

FieldDescription
product_retailer_idThe SKU (retailer ID) of the product as it exists in your catalog
nameThe product name. See the note below
priceThe unit price of the product
quantityHow many units of this product the contact ordered
currencyThe currency of the unit price
thumbnail_urlURL of the product image. Optional — see the note below
info

WhatsApp only reports the retailer ID, unit price, and quantity of each item. 2Chat resolves the rest against your Meta catalog to fill in name and thumbnail_url.

When that lookup cannot run — a coexistence number, whose catalog lives in the WhatsApp Business App, or a channel without a Meta access token — name falls back to the product_retailer_id and thumbnail_url is omitted, as shown for SKU-CAP-014 in the example above. Always treat thumbnail_url as optional.

Quick Reply

Triggers when a contact responds by tapping a quick reply button.

The message.quick_reply field is true to indicate the incoming message came from a quick reply button rather than free-form text, and message.text holds the label of the button the contact selected. The sent_by field is user because the message originates from the contact.

message.quick_reply_id holds the stable identifier of the button that was tapped. Route on this field rather than on message.text: the label is what the contact sees, so it changes with the template's language and can repeat across buttons. The identifier is the payload you set on the template's button, or the button's id for interactive messages and list replies.

{
"id": "MSG7b3e9a41-2c8d-4f6a-b1e0-9d4c5a2f83b1",
"uuid": "MSG7b3e9a41-2c8d-4f6a-b1e0-9d4c5a2f83b1",
"session_key": "WA-WAN8f21cc03-5d7a-4e19-bb62-1a3f9e0d7c48-14085550176",
"message": {
"text": "I want to learn more",
"quick_reply": true,
"quick_reply_id": "LEARN_MORE"
},
"created_at": "2026-07-02T13:22:03",
"remote_phone_number": "+14085550176",
"_2chat_link": "https://app.2chat.io/live-chat/STE3a9f1c47-8b2e-4d61-9f03-6c5a4e21d8b7/WA-WAN8f21cc03-5d7a-4e19-bb62-1a3f9e0d7c48-14085550176",
"channel_phone_number": "+16195550143",
"sent_by": "user",
"contact": {
"first_name": null,
"last_name": null,
"profile_pic_url": null,
"friendly_name": "Carlos",
"device": null
}
}

Message Receipt Sent

Triggers when a message you sent has been transmitted to the WhatsApp network and is on its way to the recipient.

{
"id": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"session_key": "WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"message": {
"text": "Hi Juan. We are writing you to ask you if you received our package with track-id 1. Please confirm."
},
"created_at": "2026-02-18T17:34:17",
"remote_phone_number": "+595986541230",
"_2chat_link": "https://app.2chat.io/live-chat/STEc5ca017c-6e16-4e1a-9960-c180b1f51682/WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"channel_phone_number": "+16173518454",
"sent_by": "agent",
"sent": true,
"received": false,
"read": false,
"event": "whatsapp.waba.message.receipt.sent",
"channel_uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"message_uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb"
}

Message Receipt Received

Triggers when a message you sent is received on the app of its intended receiver.

{
"id": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"session_key": "WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"message": {
"text": "Hi Juan. We are writing you to ask you if you received our package with track-id 1. Please confirm."
},
"created_at": "2026-02-18T17:34:17",
"remote_phone_number": "+595986541230",
"_2chat_link": "https://app.2chat.io/live-chat/STEc5ca017c-6e16-4e1a-9960-c180b1f51682/WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"channel_phone_number": "+16173518454",
"sent_by": "agent",
"sent": true,
"received": true,
"read": false,
"event": "whatsapp.waba.message.receipt.received",
"channel_uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"message_uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb"
}

Message Receipt Read

Triggers when the receiver reads a message you sent.

This one is not tied to the delivery receipt: it fires whenever the recipient actually opens the chat, which may be minutes or hours after whatsapp.waba.message.receipt.received. It only arrives if the recipient has read receipts enabled on their device.

{
"id": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"session_key": "WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"message": {
"text": "Hi Juan. We are writing you to ask you if you received our package with track-id 1. Please confirm."
},
"created_at": "2026-02-18T17:34:17",
"remote_phone_number": "+595986541230",
"_2chat_link": "https://app.2chat.io/live-chat/STEc5ca017c-6e16-4e1a-9960-c180b1f51682/WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"channel_phone_number": "+16173518454",
"sent_by": "agent",
"sent": true,
"received": true,
"read": true,
"event": "whatsapp.waba.message.receipt.read",
"channel_uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"message_uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb"
}

Message Failed

Triggers when WhatsApp could not deliver a message you sent.

errors is passed through from the provider untouched, so you can act on the specific code. wa_message_id is the provider's own message id (the Meta wamid), included when we know it, so you can correlate the failure with your data in WhatsApp Manager.

{
"id": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"session_key": "WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"message": {
"text": "Hi Juan. We are writing you to ask you if you received our package with track-id 1. Please confirm."
},
"created_at": "2026-02-18T17:34:17",
"remote_phone_number": "+595986541230",
"_2chat_link": "https://app.2chat.io/live-chat/STEc5ca017c-6e16-4e1a-9960-c180b1f51682/WA-WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7-595986541230",
"channel_phone_number": "+16173518454",
"sent_by": "agent",
"sent": false,
"received": false,
"read": false,
"event": "whatsapp.waba.message.failed",
"channel_uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"message_uuid": "MSG68e4fc6c-6a81-43aa-967e-4a71f11234eb",
"wa_message_id": "wamid.HBgLNTk1OTg2NTQxMjMwFQIAERgSQjNBRjczNkNBQjM0NUY5MUEyAA==",
"errors": [
{
"code": 131026,
"title": "Message undeliverable",
"message": "Message undeliverable",
"error_data": {
"details": "Receiver is incapable of receiving this message"
}
}
]
}

Template Created

Triggers when a new message template is submitted to WhatsApp through 2Chat — via Create WABA Template or from the web app. The creator already gets the result in the HTTP response; this event is for every other subscriber.

status is the initial status: usually PENDING, though some AUTHENTICATION templates are approved on the spot.

{
"event": "whatsapp.waba.template.created",
"channel_uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"timestamp": "2026-02-18T17:31:02.114000Z",
"payload": {
"template_uuid": "TMP1b44a079-c75c-4403-bc8f-a75c4ce5cd23",
"name": "order_shipped",
"language": "en",
"category": "UTILITY",
"status": "PENDING",
"previous_status": null,
"rejection_reason": null
}
}

Template Status Updated

Triggers when WhatsApp finishes reviewing a message template, or changes its status afterwards (for example pausing a template with poor feedback). Only APPROVED templates can be sent.

Use template_uuid directly as the template_uuid of Send WABA Message.

{
"event": "whatsapp.waba.template.status.updated",
"channel_uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"timestamp": "2026-02-18T17:34:17.221000Z",
"payload": {
"template_uuid": "TMP1b44a079-c75c-4403-bc8f-a75c4ce5cd23",
"name": "order_shipped",
"language": "en",
"category": "UTILITY",
"status": "APPROVED",
"previous_status": "PENDING",
"rejection_reason": null
}
}
FieldDescription
payload.template_uuidUUID of the template whose status changed
payload.statusNew status: APPROVED, REJECTED, PAUSED, DISABLED or DELETED
payload.previous_statusStatus the template had before this change
payload.rejection_reasonWhy WhatsApp rejected the template, when status is REJECTED

Template Deleted

Triggers when one of your message templates is deleted — through 2Chat (Delete WABA Template or the web app) or directly in WhatsApp Manager. The template can no longer be sent.

In every template event, status reflects the template's state on WhatsApp, never a 2Chat-internal state. Deleting a template is not instant on WhatsApp's side: it enters PENDING_DELETION and is retained for about 30 days before the definitive DELETED, so this event usually arrives with status: "PENDING_DELETION". On some carriers the template is removed immediately instead; in that case status comes directly as DELETED.

{
"event": "whatsapp.waba.template.deleted",
"channel_uuid": "WAN3ff9fb72-6ecd-4c2a-9055-4836d8ed33d7",
"timestamp": "2026-02-19T09:12:45.310000Z",
"payload": {
"template_uuid": "TMP1b44a079-c75c-4403-bc8f-a75c4ce5cd23",
"name": "order_shipped",
"language": "en",
"category": "UTILITY",
"status": "PENDING_DELETION",
"previous_status": "APPROVED",
"rejection_reason": null
}
}

If WhatsApp later reports a further transition (for example the final DELETED after the retention window), it arrives as a regular Template Status Updated event.