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 message, template, and channel 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 a gate such as insufficient balance, an unapproved template, or a free-form send with no open conversation 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 the parent event categories message, templates, and channel, each with a set of sub-types. 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 a template moves through review. Each status carries a matching sub-type:

Template EventsSub-typeWhat it meansWhere it can go wrong
PENDINGtemplates.pendingThe template was submitted for review. A submission covers every channel, so this is a whole-template event and the per-channel results arrive separately.None
APPROVEDtemplates.approvedThe leg named in payload.channel is approved and can be sent.None
REJECTEDtemplates.rejectedThe leg was rejected. The reason is in payload.reason.Fix the template content or category, then re-submit.
PAUSEDtemplates.pausedMeta paused the WhatsApp leg for low quality. Sends against it are rejected until it recovers.Terminal for WhatsApp sends while the pause holds.
DISABLEDtemplates.disabledMeta disabled the WhatsApp leg, for example for a policy violation.That leg is not sendable. Author a replacement rather than appealing in place.
DELETED, PENDING_DELETIONtemplates.deletedThe template was deleted, including a deletion made outside Sent.Sends referencing the template fail after this point.
CATEGORY_UPDATEDtemplates.category_updatedThe category changed, which changes how the template is priced. Fires when Meta sets or moves it on the WhatsApp leg, and when you change it on an edit, which is the usual way a rejected template is recategorised before resubmitting. See the events reference for the reason strings.None
QUALITY_UPDATEDtemplates.quality_updatedMeta's quality rating for the WhatsApp leg changed. The change is in payload.reason. A declining rating can eventually trigger PAUSED.None

Who reviews a template depends on the account. With a connected WhatsApp Business Account, Meta reviews it, and an APPROVED or PENDING verdict applies to every channel while a rejection from Meta applies to the WhatsApp leg only. Without one, Sent's compliance team reviews it and decides each channel individually. Either way payload.channel names the leg a decision is about, a decision covering the whole template omits the field, and an account with no WhatsApp channel keeps a WhatsApp leg sitting at PENDING with nothing to submit it to.

Meta forwards a wider set of lifecycle values than the preceding table covers, and adds to it without notice. A status outside the table arrives on the bare templates parent with no event key and the status reported verbatim in payload.status, so route on field first and treat event as optional.

Channel events

Channel events are emitted under the channel parent type as one market moves through provisioning and compliance. The subject is always one market, named by payload.country:

Channel EventsSub-typeWhat it meansWhere it can go wrong
Filedchannel.submittedYour request is filed and it's with Sent or a registry. Fires for a first filing, for a resubmission, and for a sender ID that Sent pre-registers with the destination's regulator on your behalf once that market's documents are in.Nothing to do. Registry decisions take days for SMS.
Corrections wantedchannel.changes_requestedSomething needs correcting before the market can go forward. A market that pre-registers its sender ID arrives here while its required documents are missing.Nothing progresses until you act. Call GET /v3/compliance/requirements for the market to see which fields and documents are outstanding.
Verdict inchannel.approvedThe registry answered and the sender is being acquired.Not sendable. A requested area code can extend this to a full acquisition cycle.
Livechannel.activatedThe sender is live and the market can carry traffic. Subscribe to this one alone if all you need is to know when you can send.None.
No longer livechannel.deactivatedThe sender stopped working: released to the pool, unbound because its campaign lapsed, or cancelled for you.Stop queueing against the market. Otherwise you learn on the next send.

payload.status reports where the market stands (PROVISIONING, PENDING_REVIEW, ACTION_NEEDED, ACTIVE, or INACTIVE), and is the same value GET /v3/channels publishes for that market. It answers a different question from the sub-type: the sub-type says what happened, the status says whether the market can send. A resubmission filed against a market whose sender is already live arrives as channel.submitted carrying ACTIVE.

ACTIVE means provisioning and compliance are complete. It does not promise the next send succeeds: a suspended account and a destination blocked by a routing rule both report ACTIVE.

An organization's webhook also receives its Sender Profiles' channel events, with payload.account_id naming the Sender Profile whose market moved.

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