Zernio
Zernio
OverviewWebhooksPost webhooksInbox webhooksAutomation webhooksSupport run webhooksAccount webhooksAnalytics webhooksAds webhooksCall webhooksWhatsApp webhooksPhone number webhooksSMS registration webhooksBranded Calling webhooks
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources
Webhooks

WhatsApp webhooks

Receive an event when Meta reviews a WhatsApp template or display name, changes a number's quality or messaging limit, restricts or alerts on the account, when a contact's WhatsApp identity changes, and when Meta detects a lead or purchase in a Click-to-WhatsApp conversation.


WhatsApp events cover template and display-name reviews, account health (quality rating, messaging limit, restrictions and Meta alerts), contact identity changes, and Meta's automatic lead and purchase detection in Click-to-WhatsApp conversations. Number lifecycle events are on phone number webhooks. Subscribe with POST /v1/webhooks/settings and the event names below (first event); delivery, retries and signatures are the same for every event (how webhooks behave).

Events

EventDescription
whatsapp.template.status_updatedMeta finished reviewing or re-reviewing a WhatsApp Business template on a connected WABA.
whatsapp.template.category_updatedMeta reclassified a template's category, as a 24-hour advance notice and again when applied.
whatsapp.account.name_status_updatedMeta finished reviewing a display-name change on a connected number.
whatsapp.account.quality_updatedA connected number's quality rating or messaging limit tier changed.
whatsapp.account.status_updatedMeta restricted, disabled, deleted or reinstated the WhatsApp Business Account.
whatsapp.account.alert_receivedMeta sent an account alert (for example a messaging limit increase was deferred).
whatsapp.contact.identity_changedA WhatsApp user changed phone number or Meta regenerated their business-scoped user id.
whatsapp.automatic_eventMeta's automatic event identification detected a lead or purchase in a Click-to-WhatsApp conversation.

How it behaves

Zernio forwards Meta's review outcomes as they land

Zernio forwards Meta's message_template_status_update field as whatsapp.template.status_updated and template_category_update as whatsapp.template.category_updated, on the WhatsApp Business Account. Meta includes neither the previous status nor the template's category in a status update. A display-name change fires whatsapp.account.name_status_updated only for a review outcome; a name applied without review produces no event.

Category changes arrive twice

Zernio sends whatsapp.template.category_updated with template.changeType: "scheduled" for Meta's 24-hour advance notice and again with "applied" when the change takes effect. template.category is always the category right now. The category decides Meta's per-delivery rate for the template (WhatsApp rates) and the delivery window it can carry; Meta clears a custom window when it recategorises a template, so read message_send_ttl_seconds back after an applied change.

Account health events fire on change, once per number

whatsapp.account.quality_updated fires only when the quality rating or the messaging limit tier differs from the value Zernio held, and carries both the previous and the new value of each. A tier change Meta applies to the whole business portfolio fires once per connected number. When Meta flags a number, Zernio reads the live quality_rating from Meta, so quality.qualityRating is Meta's current value (GREEN, YELLOW, RED), not a guess from the flag.

whatsapp.account.status_updated mirrors Meta's account_update restriction, violation, disable, delete and reinstatement events. They apply to the whole WhatsApp Business Account, so every connected number on it receives one event. status.restrictions lists what Meta restricted (for example RESTRICTED_BIZ_INITIATED_MESSAGING) and when each restriction lifts. The same status is on the account as platformStatus.

whatsapp.account.alert_received forwards Meta's account_alerts as is (alert.type, alert.severity, alert.description). An alert about one number goes to that number's account; a business-level alert goes to every connected number on the WABA.

Identity changes carry old and new identifiers

whatsapp.contact.identity_changed fires when Meta reports a WhatsApp user under a new identifier: a new phone number (reason: "user_changed_number"), a new business-scoped user id (user_changed_user_id, user_identity_changed or user_id_update). previous and current carry the phone number, BSUID, parent BSUID and username, so you can re-key records you stored against the old value. Zernio has already moved the inbox conversation and the contact by the time the event arrives; conversationId and contactId point at them, or are null when there was none.

Automatic events carry the Conversions API match key

Zernio delivers ctwaClid on whatsapp.automatic_event. Meta omits that clid on a minority of referrals, on any number, most often WhatsApp Status placements; this event can supply it there. Zernio also writes the clid back onto the conversation, so POST /v1/whatsapp/conversions becomes usable for the conversation.

Detection is not available for EU, UK and JP businesses, and elsewhere the business owner opts into it inside Meta's Embedded Signup flow when the number is connected. There is no Zernio field for it and no way to subscribe your way into it: an endpoint subscribed to whatsapp.automatic_event on a number whose owner did not opt in receives nothing.


whatsapp.template.status_updated

Meta finished reviewing or re-reviewing a WhatsApp Business template on a connected WABA. Branch on template.status (APPROVED, REJECTED, PENDING, PAUSED, DISABLED, IN_APPEAL, PENDING_DELETION); template.reason is Meta's free-form reason or "NONE".


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for the whatsapp.template.status_updated event. Fired when Meta completes (re)review of a template attached to a connected WABA. Maps Meta's message_template_status_update field onto our event envelope.

Response Body

Example Requests

Webhook payload for the whatsapp.template.status_updated event. Fired when Meta completes (re)review of a template attached to a connected WABA. Maps Meta's message_template_status_update field onto our event envelope.

POST/whatsapp.template.status_updated


whatsapp.template.category_updated

Meta reclassified a template's category. template.changeType is scheduled or applied; template.category is the current category.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for the whatsapp.template.category_updated event. Fired when Meta reclassifies a template's category attached to a connected WABA. Maps Meta's template_category_update field onto our event envelope.

Response Body

Example Requests

Webhook payload for the whatsapp.template.category_updated event. Fired when Meta reclassifies a template's category attached to a connected WABA. Maps Meta's template_category_update field onto our event envelope.

POST/whatsapp.template.category_updated


whatsapp.account.name_status_updated

Meta finished reviewing a WhatsApp display-name change on a connected number. Branch on name.status (APPROVED, DECLINED, PENDING_REVIEW; Meta's DEFERRED maps to PENDING_REVIEW, the review is still open); name.requestedName and name.rejectionReason are Meta's values or null.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for the whatsapp.account.name_status_updated event. Fired when Meta finishes reviewing a WhatsApp display-name change on a connected number. Maps Meta's phone_number_name_update WABA webhook field onto our event envelope. Fires only for a review outcome (APPROVED, DECLINED, PENDING_REVIEW); a name applied without review reports name_status: AVAILABLE_WITHOUT_REVIEW on the phone node instead, and Meta never sends this webhook field for that case.

Response Body

Example Requests

Webhook payload for the whatsapp.account.name_status_updated event. Fired when Meta finishes reviewing a WhatsApp display-name change on a connected number. Maps Meta's phone_number_name_update WABA webhook field onto our event envelope. Fires only for a review outcome (APPROVED, DECLINED, PENDING_REVIEW); a name applied without review reports name_status: AVAILABLE_WITHOUT_REVIEW on the phone node instead, and Meta never sends this webhook field for that case.

POST/whatsapp.account.name_status_updated


whatsapp.account.quality_updated

A connected number's quality rating or messaging limit tier changed. quality.source says which Meta signal reported it; compare quality.previousQualityRating with quality.qualityRating and quality.previousMessagingLimitTier with quality.messagingLimitTier.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for whatsapp.account.quality_updated. Fired when a connected number's quality rating or messaging limit tier differs from the value Zernio held. Tier changes that Meta applies to the whole portfolio fire once per connected number.

Response Body

Example Requests

Webhook payload for whatsapp.account.quality_updated. Fired when a connected number's quality rating or messaging limit tier differs from the value Zernio held. Tier changes that Meta applies to the whole portfolio fire once per connected number.

POST/whatsapp.account.quality_updated


whatsapp.account.status_updated

Meta restricted, flagged a violation on, disabled, deleted or reinstated the WhatsApp Business Account. Branch on status.status (restricted or active) and status.metaEvent.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for whatsapp.account.status_updated. Fired when Meta restricts, flags a violation on, disables, deletes or reinstates the WhatsApp Business Account. The same status is also exposed on the account as platformStatus.

Response Body

Example Requests

Webhook payload for whatsapp.account.status_updated. Fired when Meta restricts, flags a violation on, disables, deletes or reinstates the WhatsApp Business Account. The same status is also exposed on the account as platformStatus.

POST/whatsapp.account.status_updated


whatsapp.account.alert_received

Meta sent an account alert. alert.severity is CRITICAL, WARNING or INFORMATIONAL; alert.type is Meta's alert type.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for whatsapp.account.alert_received, forwarded from Meta's account_alerts webhook. Alerts about a specific number go to that number's account; business-level alerts go to every connected number on the WABA.

Response Body

Example Requests

Webhook payload for whatsapp.account.alert_received, forwarded from Meta's account_alerts webhook. Alerts about a specific number go to that number's account; business-level alerts go to every connected number on the WABA.

POST/whatsapp.account.alert_received


whatsapp.contact.identity_changed

A WhatsApp user is now known by a different identifier. previous and current carry the phone number, BSUID, parent BSUID and username.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for the whatsapp.contact.identity_changed event. Fired when Meta reports that a WhatsApp user is now known by a different identifier: a system message of type user_changed_number, user_changed_user_id or user_identity_changed, or a user_id_update webhook (BSUID regenerated). Zernio re-keys the inbox conversation and contact channel before firing.

Response Body

Example Requests

Webhook payload for the whatsapp.contact.identity_changed event. Fired when Meta reports that a WhatsApp user is now known by a different identifier: a system message of type user_changed_number, user_changed_user_id or user_identity_changed, or a user_id_update webhook (BSUID regenerated). Zernio re-keys the inbox conversation and contact channel before firing.

POST/whatsapp.contact.identity_changed


whatsapp.automatic_event

Meta's automatic event identification detected a lead or purchase in a Click-to-WhatsApp conversation. Branch on eventName (LeadSubmitted or Purchase); Purchase events may carry the detected amount in customData (currency, value).


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.automatic_event

Related

  • Webhooks: create an endpoint, retries, signatures.
  • WhatsApp templates: create the templates these reviews are about.
  • Click-to-WhatsApp: ads and conversions.
  • Phone number webhooks: number activation, suspension and release.
  • Inbox webhooks: the messages themselves.
Was this page helpful?

Call webhooks

Receive an event when a call rings, ends or fails on a phone or WhatsApp number, and when a WhatsApp user answers a call-permission request.

Phone number webhooks

Receive an event at each step of a provisioned number's life, from KYC submission and review to activation, suspension and release.

On this page

EventsHow it behavesZernio forwards Meta's review outcomes as they landCategory changes arrive twiceAccount health events fire on change, once per numberIdentity changes carry old and new identifiersAutomatic events carry the Conversions API match keywhatsapp.template.status_updatedwhatsapp.template.category_updatedwhatsapp.account.name_status_updatedwhatsapp.account.quality_updatedwhatsapp.account.status_updatedwhatsapp.account.alert_receivedwhatsapp.contact.identity_changedwhatsapp.automatic_eventRelated
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event*"whatsapp.template.status_updated"

Value in

  • "whatsapp.template.status_updated"
account*
template*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event*"whatsapp.template.category_updated"

Value in

  • "whatsapp.template.category_updated"
account*
template*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event*"whatsapp.account.name_status_updated"

Value in

  • "whatsapp.account.name_status_updated"
account*
name*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event*"whatsapp.account.quality_updated"

Value in

  • "whatsapp.account.quality_updated"
account*
quality*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event*"whatsapp.account.status_updated"

Value in

  • "whatsapp.account.status_updated"
account*
status*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event*"whatsapp.account.alert_received"

Value in

  • "whatsapp.account.alert_received"
account*
alert*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event*"whatsapp.contact.identity_changed"

Value in

  • "whatsapp.contact.identity_changed"
account*
reason*string

Which Meta signal reported the change. user_changed_number: new phone number. user_changed_user_id and user_id_update: new BSUID.

Value in

  • "user_changed_number"
  • "user_changed_user_id"
  • "user_identity_changed"
  • "user_id_update"
previous*
current*
contactId*|

Zernio contact id matched on the new identity, null when none exists yet.

conversationId*|

Zernio inbox conversation that was re-keyed, null when there was none.

changedAt*string

When Meta reported the change.

Formatdate-time
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id?string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

event?"whatsapp.automatic_event"

Value in

  • "whatsapp.automatic_event"
timestamp?string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
accountId?string

SocialAccount id of the WhatsApp number whose conversation was flagged.

conversationId?string

Zernio conversation id, when the thread could be resolved.

platformMessageId?string

The wamid of the message Meta's analysis flagged.

eventName?string

Meta-detected event: LeadSubmitted | Purchase.

ctwaClid?string

Meta's CTWA click id, the Conversions API match key.

customData?

Purchase events may carry the detected amount.

detectedAt?string
Formatdate-time