Skip to main content
All webhook payloads use v2 format with phone_number_id at the top level.

Payload structure

Webhook payloads separate message data from conversation data:
  • message.kapso - Message-scoped only: direction, status, processing_status, statuses (raw status history), origin, has_media, content (text representation), transcript (for audio), media helpers (media_data, media_url, message_type_data)
  • conversation - Top-level identifiers such as id, phone_number, phone_number_id, and, when available, business_scoped_user_id, parent_business_scoped_user_id, and username. Optional conversation.kapso contains summary metrics (counts, last-message metadata, timestamps)
  • phone_number_id - Included at top level for routing
Do not assume phone_number, from, to, or wa_id are always present.

WhatsApp webhook events

Sent only to phone-number webhooks (/whatsapp/phone_numbers/{phone_number_id}/webhooks).

Message received

whatsapp.message.receivedFired when a new WhatsApp message is received from a customer. Supports message buffering for batch delivery.

Message sent

whatsapp.message.sentFired when a message is successfully sent to WhatsApp

Message delivered

whatsapp.message.deliveredFired when a message is successfully delivered to the recipient’s device

Message read

whatsapp.message.readFired when the recipient reads your message

Message failed

whatsapp.message.failedFired when a message fails to deliver

Conversation created

whatsapp.conversation.createdFired when a new WhatsApp conversation is initiated

Conversation ended

whatsapp.conversation.endedFired when a WhatsApp conversation ends (agent action, manual closure, or 24-hour inactivity)

Conversation inactive

whatsapp.conversation.inactiveFired when no messages (inbound/outbound) for configured minutes (1-1440, default 60)

Payload structures

Kapso sends the event name in the X-Webhook-Event header. The examples below show unbuffered request bodies. If buffering is enabled for whatsapp.message.received, the request body uses a batch envelope with type, batch: true, data: [...], and batch_info; each data item has the same shape as the unbuffered whatsapp.message.received payload below. See Batched webhook format for a full batched payload example.

whatsapp.message.received

whatsapp.message.sent

whatsapp.message.delivered

whatsapp.message.failed

whatsapp.conversation.created

whatsapp.conversation.ended

whatsapp.conversation.inactive

Multiple inactivity timeouts

Create separate webhooks for different timeout thresholds:
Each webhook fires independently when its threshold is reached.

Message origin

The message.kapso.origin field indicates how the message entered the system:
  • cloud_api - Sent via Kapso API (outbound jobs, flow actions, API calls)
  • business_app - Echoed from WhatsApp Business App (when using the Business App)
  • history_sync - Backfilled during message history imports (only if project ran sync)

Status history

The message.kapso.statuses array contains the complete history of raw Meta status events for a message, ordered chronologically. Each entry is the unmodified payload from Meta’s webhook.

Status object structure

Each status object in the array follows Meta’s webhook format:
See Meta’s status webhook reference for the complete schema. Use this field to track the full lifecycle of outbound messages and understand failure causes. The array only appears when status events have been recorded.

Message types

The message.type field can be one of:
  • text - Plain text message
  • image - Image attachment
  • video - Video attachment
  • audio - Audio/voice message
  • document - Document attachment
  • location - Location sharing
  • template - WhatsApp template message
  • interactive - Interactive message (buttons, lists)
  • reaction - Message reaction
  • contacts - Contact card sharing

Message type-specific data

Media messages (image/video/document)

Audio messages

Location messages

Template messages

Interactive messages

Reaction messages

Contact messages

When you send a request contact info CTA and the user taps it, WhatsApp sends a contacts message. It includes the user’s phone number and keeps BSUID identity when available.
If the user shares a contact directly from WhatsApp instead, origin is other and the payload can include a vCard.