message.received
A customer sent the business a message. Sent once per WhatsApp message (wamid).
message is Meta's message object, unchanged. PaalChat keeps it, encrypted, in the
conversation history (365 days by default - see the FAQ). Also opens the
24-hour window for free-form replies to from.
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 message.received.
occurred_at
string
Format date-time.
business
object
external_id
string
business.external_id
data
object
message_id
integer
data.message_id
wamid
string
data.wamid
contact_id
integer | null
data.contact_id
conversation_id
integer | null
data.conversation_id
from
string
data.from
profile_name
string | null
data.profile_name
phone_number_id
string | null
data.phone_number_id
type
string
data.type
Example text.
media_id
integer | null
data.media_id
PaalChat's copy of the attachment (pending until media.updated); null without media, or when media is not enabled.
timestamp
string | null
data.timestamp
Unix seconds as a string (Meta's).
message
object
data.message
Meta's message object, unchanged (text.body, button, interactive, image.id, context.id...).