conversation.updated
A conversation's status, priority, tags or assignee changed, or the contact reopened it (change says which). New messages alone arrive as message.received and message.status, not here.
Verify every callback
Check X-PaalChat-Signature on the raw body, reject timestamps older than 5 minutes, and de-duplicate on X-PaalChat-Delivery. Answer 2xx within 10 seconds. See Webhooks and callbacks.
Headers
X-PaalChat-Event
string
X-PaalChat-Delivery
string
Unique per event (equals body id). De-duplicate on it.
Format uuid.
X-PaalChat-Signature
string
t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>. Reject if invalid or older than 300 seconds.
Pattern ^t=\d+,v1=[a-f0-9]{64}$.
Body
id
string
Equals X-PaalChat-Delivery.
Format uuid.
sandbox
boolean
true for sandbox businesses (test keys) - nothing reached WhatsApp.
event
any
Always conversation.updated.
occurred_at
string
Format date-time.
business
object
external_id
string
business.external_id
data
object
change
string
data.change
created, reopened, status_changed, priority_changed, assigned, unassigned, tag_added or tag_removed.
conversation
object
data.conversation
id
integer
data.conversation.id
contact
object
data.conversation.contact
id
integer
data.conversation.contact.id
external_id
string | null
data.conversation.contact.external_id
name
string | null
data.conversation.contact.name
phone
string | null
data.conversation.contact.phone
phone_number_id
string | null
data.conversation.phone_number_id
The business number it happens on.
status
string
data.conversation.status
open = needs the business; pending = waiting for the customer (a conversation the business started); an incoming message reopens pending, resolved and snoozed conversations; after closed, the next message starts a new conversation.
One of: open, pending, resolved, closed, snoozed.
priority
string
data.conversation.priority
One of: low, normal, high, urgent.
unread_count
integer
data.conversation.unread_count
window_open
boolean
data.conversation.window_open
Free-form replies are possible (the contact wrote in the last 24 hours).
last_message_at
string | null
data.conversation.last_message_at
Format date-time.
last_incoming_at
string | null
data.conversation.last_incoming_at
Format date-time.
snoozed_until
string | null
data.conversation.snoozed_until
Format date-time.
assignee
object | null
data.conversation.assignee
The inbox member working it.
external_id
string
data.conversation.assignee.external_id
name
string
data.conversation.assignee.name
tags
array of strings
data.conversation.tags
created_at
string
data.conversation.created_at
Format date-time.