Skip to main content
POST
Outbound Webhooks

Outbound Webhooks

You can configure an endpoint to receive Sequenzy email, SMS, subscriber, and sequence lifecycle events as signed JSON POST requests.

Create

string
required
Human-readable webhook name.
string
required
Absolute HTTPS endpoint URL.
string[]
Event types to receive. Omit this field to receive the default lifecycle events: sent, delivered, delayed, bounced, complained, email unsubscribed, SMS lifecycle (sms.sent, sms.delivered, sms.failed, sms.opted_out), invalid subscriber, subscriber created, and subscriber unsubscribed. Add opened, clicked, replied, subscriber.updated, subscriber.list_subscribed, subscriber.list_unsubscribed, poll.answered, sequence.finished, and sequence.failed explicitly if you need engagement, inbound reply, poll response, profile sync, per-list consent sync, or sequence lifecycle events.

Manage

Updating an endpoint URL, enabling a disabled endpoint, sending a test event, and replaying a delivery reset the endpoint failure state so a recovered receiver can be tested immediately. A test event targets the endpoint you name, so it is delivered even when that endpoint subscribes to no event types. The response returns the queued delivery, so you can poll that delivery ID for the result instead of waiting for it to show up in the delivery list:

Event Payload

Each webhook delivery sends a signed JSON event to your endpoint. Email events include Sequenzy IDs and, when available, your subscriber external ID or the subscriberExternalId stored on a transactional send:
Webhook payloads use one canonical snake_case field per value. external_id is included when the recipient is linked to a subscriber with a customer-owned external ID, or when a single-recipient transactional send included subscriberExternalId even if no subscriber exists. email.sent events include computed_lists when campaign personalization selected per-recipient list items for that email; items preserves the original campaign data objects. poll.answered fires after a Poll or NPS response is stored. For single-answer polls, the nested poll.value is the stable scalar value saved to the subscriber attribute, while poll.answer is the human-readable label captured for reporting. For multi-select polls, poll.value is the complete selected-value array; poll.values and poll.answers provide parallel value and label arrays, and poll.allow_multiple is true.
A multi-select response uses this poll shape:
email.replied fires when an inbound reply is stored. The payload includes reply, conversation, and original send context plus the reply body text, HTML body, and stripped text. Attachment bodies are not included; only metadata is delivered.
Subscriber events include the current subscriber profile when one exists. subscriber.created fires once per newly created contact and carries source (the origin, using the same vocabulary as the per-list consent events) plus list_ids for the lists it joined at creation. It fires for every creation path, including bulk imports and integration syncs, so filter on source if you only want organic signups. When double opt-in is on, it fires at confirmation rather than at signup, with source set to double_opt_in - a contact who never confirms never emits it. subscriber.invalid fires when a subscriber add attempt cannot create a sendable subscriber because the attempted email is missing, syntactically invalid, has an invalid/blocked domain, or is already suppressed from previous delivery failures. subscriber.updated fires when email, external_id, first_name, last_name, custom_attributes, or a non-unsubscribe status change occurs. Active to unsubscribed changes emit subscriber.unsubscribed; they only also emit subscriber.updated when another profile field changes in the same update. List and tag changes do not emit subscriber.updated. subscriber.list_subscribed and subscriber.list_unsubscribed fire only for actual per-list membership transitions. Each payload includes the subscriber ID, email, optional external ID, list ID and name, action (added or removed), and the change source. A global opt-out emits subscriber.unsubscribed without a per-list event fan-out.
Sequence lifecycle events include the subscriber email, external ID when available, and the event data recorded for that sequence enrollment:

Responses

Verify Requests

Webhook requests include X-Sequenzy-Timestamp and X-Sequenzy-Signature. Build the signed payload as v1:{timestamp}:{raw_request_body}, compute an HMAC-SHA256 digest with each active webhook signing secret, and compare it to any v1= signature value. If a webhook has multiple active signing secrets, Sequenzy still sends one POST request and includes one v1= signature per secret in the same header. Add a new secret, deploy it in your receiver, then remove the old secret.