Webhooks Lifecycle

This page describes what happens between the moment an event occurs inside Sent and the moment your endpoint receives (or stops receiving) a webhook delivery. Everything below is observable from your side, through the request itself or the delivery history in the Sent Dashboard.

Delivery Lifecycle

The diagram below shows the full lifecycle of a single webhook delivery: from event generation, through HTTP delivery to your endpoint, including retries and the conditions under which a webhook can be auto-disabled.

The same flow drives both message events and template events; only the envelope contents differ. Filtering by event_types and event_filters is evaluated when the event is generated. Webhooks whose subscription doesn't match the event's sub-type don't receive a delivery attempt.

Each retry uses exponential backoff between attempts. After your configured retry budget is exhausted, the delivery is marked FAILED, and too many consecutive failed delivery attempts auto-disable the webhook. You re-enable it from the Sent Dashboard. The retry schedule, retry budget, and auto-disable threshold are stated canonically in Delivery Statuses & Retries.

End-to-end Message Event Flow

The diagram below shows how a single outbound message moves through its sub-types and the points at which it can branch into message.failed. Inbound events are shown separately because they don't share the outbound state machine.

Not every message travels the whole pipeline. A send held for the recipient's quiet hours surfaces message.scheduled while it waits, a routing policy such as a recipient opt-out finalizes it as message.filtered, and an account-level gate such as insufficient balance finalizes it as message.blocked. FILTERED and BLOCKED are policy decisions rather than delivery failures, so neither counts against your deliverability rate. See Trust & Safety for the gates behind each one.

Not every send produces every event. Channels and carriers vary in how many intermediate statuses they report. For example, some SMS carriers skip straight from routed to delivered. Treat the sub-types as a partial order: if you receive message.delivered, you can safely assume the message was queued, routed, and sent.

Events at a Glance

Sent emits two parent event categories, message and templates, and a handful of sub-types under each. The tables below summarise every webhook event, what triggers it, the direction it travels, and where in the lifecycle it can fail.

Message events

Message EventsDirectionSMSWhatsAppRCSWhat it meansWhere it can go wrong
QUEUEDOutboundYesYesYesSent has accepted the request and is queueing it for routing.Validation errors (bad number, missing template params) reject the request before this event is emitted.
ROUTEDOutboundYesYesYesThe message has been assigned to a carrier or channel provider.Routing can fail if there is no available route to the destination country/channel, which emits message.failed.
SENTOutboundYesYesYesThe carrier or provider has accepted the message for delivery.Carrier rejects the payload (for example, content policy or a blocked number), which emits message.failed.
DELIVEREDOutboundYesYesYesThe message reached the recipient's device.Handset offline, number unreachable, or carrier delivery receipt missing, which emits message.failed (or stays at sent until the receipt times out).
READOutboundNoYesYesThe recipient opened the message. Not emitted for SMS.Recipient never opens the message, has read receipts turned off, or the channel doesn't support read receipts (SMS).
FAILEDOutboundYesYesYesTerminal failure: the message will not be delivered. The payload carries message_status: FAILED but no failure reason.This is the failure event. To diagnose the cause, retrieve the message's activity history (GET /v3/messages/{id}/activities) or open the message in the Sent Dashboard.
SCHEDULEDOutboundYesYesYesThe send is deferred until the recipient's quiet hours end.The message is held, not lost; it re-enters the pipeline when the quiet-hours window closes.
FILTEREDOutboundYesYesYesA routing policy (for example, a recipient opt-out) suppressed the message before dispatch.Terminal for that recipient: the message is not dispatched.
BLOCKEDOutboundYesYesYesAn account-level gate (for example, insufficient balance or an unmet onboarding entitlement) stopped the message.Terminal for that message; new sends stay gated until the account condition is resolved.
RECEIVEDInboundYesYesYesA contact replied to one of your numbers (or, on RCS, tapped a quick-reply suggestion chip).Inbound delivery to your endpoint can still fail at HTTP (see the retry/auto-disable lifecycle in the preceding section).

Template events

Template events are emitted under the templates parent type as Meta updates a template's lifecycle. The most common statuses you'll receive:

Template EventsDirectionWhat it meansWhere it can go wrong
PENDINGOutboundTemplate has been submitted to Meta for review.None
APPROVEDOutboundMeta approved the template. It is now usable for WhatsApp sends.None
REJECTEDOutboundMeta rejected the template. The reason is in payload.reason.Fix the template content or category, then re-submit.
CATEGORY_UPDATEDOutboundMeta moved the template to a different category (for example, MARKETING → UTILITY). The change description is in payload.reason.None

Meta may also forward other lifecycle values verbatim (for example PAUSED or DISABLED); your handler should be tolerant of statuses outside the preceding list.

What's Next

  • Subscribe to the events your app needs in the Events Reference: full payload schemas and filtering rules.
  • Verify incoming requests against the signing secret described in Signature Verification.
  • See Handling Retries for guidance on idempotency, response codes, and recovery.

On this page