Webhook events and payloads — Vatli Help | Ixoric

Webhook events and payloads

All 21 events — messages, contacts, flows, broadcasts, templates and Click-to-WhatsApp leads — with the envelope and example payloads.

Updated 8 Oct 2026

Events

Messages

EventFires when
message.receivedA contact sent you a message
message.sentWhatsApp accepted a message you sent
message.deliveredYour message reached the contact’s phone
message.readThe contact read your message
message.failedYour message couldn’t be delivered — includes WhatsApp’s error code and reason
message.status_updatedAny delivery status change (older catch-all — prefer the four above)
conversation.createdA new conversation was opened

Contacts

EventFires when
contact.createdA contact was added
contact.updatedA contact’s details changed — includes which fields
contact.tag_addedA tag was applied
contact.tag_removedA tag was removed
contact.opted_outA contact replied STOP or was marked opted out

Flows

EventFires when
flow.triggeredA flow started for a contact
flow.completedA flow finished or handed off to an agent
flow.failedA flow hit an error it couldn’t recover from
flow.exitedA contact left a flow early — timed out or an agent stepped in

Broadcasts: broadcast.started, broadcast.completed, broadcast.failed
Templates: template.approved, template.rejected (with the reason)
Ads: ad_lead.received — someone messaged you from a Click-to-WhatsApp ad

Contact, template, broadcast, flow and ad-lead events fire however the change was made — the inbox, an import, an automation, the API or Meta.

The envelope

{
  "id": "evt_4f1c9a0b2e7d4c3a8b6e5f1d2c3b4a59",
  "type": "contact.tag_added",
  "workspace_id": "6b2f…",
  "created_at": "2026-09-14T10:30:00.000Z",
  "api_version": "2026-09-01",
  "data": { }
}
  • id is unique and stable — a retry or resend has the same id. Store handled ids and skip repeats.
  • Events can arrive more than once and out of order. Use created_at and your own dedupe.

data by event

// message.received
{ "conversation_id": "…", "contact_id": "…", "whatsapp_message_id": "wamid.…",
  "content_type": "text", "text": "Hi, is this still available?" }

// message.sent | message.delivered | message.read | message.failed
{ "whatsapp_message_id": "wamid.…", "conversation_id": "…",   // null for a broadcast send
  "contact_id": "…", "broadcast_id": null,                     // set for a broadcast send
  "status": "failed", "occurred_at": "2026-09-14T10:30:02.000Z",
  "error": { "code": 131026, "title": "Message undeliverable",   // message.failed only
             "message": "(#131026) Message undeliverable" } }

// contact.created | contact.opted_out
{ "contact": { "id": "…", "phone": "+14155550123", "name": "Asha", "email": null,
               "company": null, "opted_out": false, "opted_out_at": null,
               "created_at": "…", "updated_at": "…" },
  "source": "stop_keyword" }                                   // contact.opted_out only

// contact.updated
{ "contact": { … }, "changed": ["name", "email"] }

// contact.tag_added | contact.tag_removed
{ "contact": { … }, "tag": { "id": "…", "name": "Hot lead" } }

// flow.*
{ "flow_run": { "id": "…", "flow_id": "…", "contact_id": "…", "conversation_id": "…",
                "status": "handed_off", "node_key": "ask_budget", "end_reason": null,
                "started_at": "…", "ended_at": "…" } }

// broadcast.*
{ "broadcast": { "id": "…", "name": "Diwali offer", "template_name": "diwali_2026",
                 "status": "sent", "total_recipients": 1200, "sent_count": 1180,
                 "delivered_count": 1102, "read_count": 640, "failed_count": 20 } }

// template.approved | template.rejected
{ "template": { "id": "…", "name": "order_update", "language": "en_US",
                "category": "UTILITY", "status": "REJECTED",
                "rejection_reason": "INVALID_FORMAT" } }

// ad_lead.received
{ "contact": { … }, "conversation_id": "…",
  "referral": { "ctwa_clid": "ARAkL…", "source_id": "120211…", "source_type": "ad",
                "source_url": "https://fb.me/…", "headline": "Book a free demo",
                "body": "…", "media_type": "image" },
  "whatsapp_message_id": "wamid.…", "occurred_at": "…" }

source_id is the Meta ad ID and ctwa_clid is Meta’s click ID — present only when Ads attribution is on.

Headers

HeaderValue
X-Vatli-Signaturet=<unix seconds>,v1=<hex HMAC-SHA256>
X-Vatli-Event-IdThe event’s id
X-Vatli-EventThe event’s type
X-Vatli-Webhook-IdWhich of your endpoints it was sent to
X-Vatli-Delivery-IdThis delivery
X-Vatli-Delivery-Attempt1, then 2, 3… on retries