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

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.


Phone number events follow a number provisioned through Zernio from KYC submission through review, activation, suspension and release. The names carry a whatsapp. prefix for legacy reasons and fire for every provisioned number. 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.number.kyc_submittedAn end customer completed a hosted KYC share link; the number enters review under your account.
whatsapp.number.activatedA number you provisioned finished setup and is ready to connect.
whatsapp.number.declinedA regulated number order was declined in review and no number was activated.
whatsapp.number.action_requiredThe regulator asked for more information on a placed order; the order stays pending until you provide it.
whatsapp.number.verification_requiredA regulated number needs end-user ID verification; carries the link to forward.
whatsapp.number.suspendedAn active number was suspended, for example after a failed payment; carries a reason.
whatsapp.number.reactivatedA suspended number is usable again.
whatsapp.number.releasedA number was released and is no longer usable (terminal); carries a reason.
phone_number.stock_availableAn out-of-stock country you watch has deliverable numbers again; once per watch.

How it behaves

Events fire on status transitions

Every number carries a status you can read back with Get phone number. Zernio fires an event on each transition; the diagram labels drop the whatsapp.number. prefix:

One event on this page hangs off nothing in that diagram. phone_number.stock_available belongs to a stock watch, not to a number: it fires from the 6-hourly stock sweep before you own a number in that country at all, once per watch, and the watch is then consumed (availability). Every other event on this page reports a transition of a number you already hold.

Polling can also catch short-lived transit statuses the events skip: pending_payment, provisioning, verifying (provisioned and awaiting confirmation, not billed until active) and releasing.

Instant numbers skip the review states

Zernio moves a number in an instant-provisioning country straight to active, so the first event you see is whatsapp.number.activated. The review states apply only to regulated (KYC) countries.

kyc_submitted fires only for hosted share links

Zernio sends whatsapp.number.kyc_submitted when your customer finishes a white-labeled KYC form. When you submit KYC over the API you already know the moment of submission, so no event fires.

action_required and verification_required leave the status unchanged

Zernio keeps the number at pending_regulatory while the regulator waits on you. These events say the review is blocked, not that the state changed.

regulatory_declined can be remediated

Resubmit corrected details and the number returns to pending_regulatory: the same number, no new billing. Zernio never bills a number that was declined.

released is the only terminal state

Zernio recovers suspended numbers with reactivated, but a suspension left unresolved ends in release.


whatsapp.number.kyc_submitted

An end customer completed a hosted KYC share link. The number enters regulatory review (pending_regulatory) under your account; whatsapp.number.activated or whatsapp.number.declined follows once the provider rules on it. Update your own UI from this event instead of polling.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.kyc_submitted

whatsapp.number.activated

A number you provisioned through Zernio finished setup and is ready to connect. For regulated (non-US) numbers this can take 1 to 3 business days after the order is approved.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.activated

whatsapp.number.declined

A regulated number order was declined in regulatory review and no number was activated. The order never activates and you are never billed for it.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.declined

whatsapp.number.action_required

The regulator reviewing a placed number order asked for more information, for example a certificate of company incorporation. Nothing was rejected: the order stays pending and does not progress until you provide the information. reason carries the regulator's request verbatim when available. Provide the missing details from the dashboard's phone-numbers page or re-submit the relevant fields through the remediation endpoint; the review resumes automatically.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.action_required

whatsapp.number.verification_required

A regulated number requires the end user to complete an identity check, for example Australian mobile numbers. The payload carries a one-time verificationUrl to forward to the person whose ID is on file; the order completes once they pass.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.verification_required

whatsapp.number.suspended

An active number was suspended, for example after a failed payment. The number stops working until the issue is resolved, then whatsapp.number.reactivated follows. reason is a value such as payment_failed or subscription_ended.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.suspended

whatsapp.number.reactivated

A suspended number was reactivated, for example after the payment recovered, and is usable again.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.reactivated

whatsapp.number.released

A number was released and is no longer usable, whether you released it, a billing cleanup released it, or an admin did. This is terminal. reason is a value such as user_requested or cleanup_suspended.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/whatsapp.number.released

phone_number.stock_available

An out-of-stock country you watch with Create stock watch has deliverable numbers again. It fires once per watch and the watch is consumed. stock.country is the watched country and stock.types[] lists each number type that has stock with its availableCount at sweep time. Numbers are first come, first served, so purchase promptly.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for phone_number.stock_available events

Response Body

Example Requests

Webhook payload for phone_number.stock_available events

POST/phone_number.stock_available

Related

  • Webhooks: create an endpoint, retries, signatures.
  • Phone numbers: purchase, KYC and availability.
  • Get phone number: read status on demand.
  • Remediate a number: fix a declined order.
  • WhatsApp webhooks: template and display-name reviews.
Was this page helpful?

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.

SMS registration webhooks

Receive an event when a US SMS registration changes status or starts waiting on you, instead of polling it.

On this page

EventsHow it behavesEvents fire on status transitionsInstant numbers skip the review stateskyc_submitted fires only for hosted share linksaction_required and verification_required leave the status unchangedregulatory_declined can be remediatedreleased is the only terminal statewhatsapp.number.kyc_submittedwhatsapp.number.activatedwhatsapp.number.declinedwhatsapp.number.action_requiredwhatsapp.number.verification_requiredwhatsapp.number.suspendedwhatsapp.number.reactivatedwhatsapp.number.releasedphone_number.stock_availableRelated
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?string

Value in

  • "whatsapp.number.kyc_submitted"
  • "verification.approved"
  • "verification.failed"
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
number?
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.number.activated"

Value in

  • "whatsapp.number.activated"
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
number?
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.number.declined"

Value in

  • "whatsapp.number.declined"
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
number?
reason?string|null
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.number.action_required"

Value in

  • "whatsapp.number.action_required"
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
reason?string
requirements?array<>

Every requirement on the order with the reviewer's current verdict. Omitted when the order's requirements could not be read.

reviewedAt?string

When the reviewer last commented on the order. Omitted when there is no reviewer comment.

Formatdate-time
number?
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.number.verification_required"

Value in

  • "whatsapp.number.verification_required"
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
number?
verificationUrl?string
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.number.suspended"

Value in

  • "whatsapp.number.suspended"
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
number?
reason?string|null
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.number.reactivated"

Value in

  • "whatsapp.number.reactivated"
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
number?
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.number.released"

Value in

  • "whatsapp.number.released"
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
number?
reason?string|null
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*"phone_number.stock_available"

Value in

  • "phone_number.stock_available"
stock*
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