Webhook events and payloads
Every webhook delivery is a JSON HTTP POST with an event name and a versioned payload envelope. This reference lists the 19 supported event types, the envelope fields, and how registrations, waitlist entries, and event lifecycle changes appear in the data.
Event types
Each endpoint subscribes to one or more of these events. The UI label is shown next to each event identifier.
Event identifier | UI label | Fires when |
|---|---|---|
| New registration | A registration becomes active (payment confirmed for paid events) |
| Attendee info completed | The attendee finished filling in their info |
| Registration refunded | A registration was refunded in full |
| Registration cancelled | A live registration your receiver already heard about was cancelled (bulk cancels fire one event per registration) |
| Attendee checked in | An attendee was checked in (bulk check-ins fire one event per attendee) |
| Registration moved | A host moved a registration to another event |
| Registration exchanged | A registration was exchanged |
| Registration transferred | A guest transferred their ticket to someone else |
| Joined waitlist | Someone joined a waitlist |
| Waitlist spot offered | A waitlist spot was offered |
| Waitlist spot accepted | A waitlist offer was accepted |
| Waitlist offer expired | A waitlist offer expired |
| Event published | An event went live, whether you published it by hand, on a schedule, or in a bulk publish |
| Event details changed | A meaningful detail changed (see "Which edits count" below); a time change sends |
| Event rescheduled | The start or end time moved |
| Event cancelled | An event was cancelled |
| Event finished | An event finished and was marked completed |
| Event sold out | An event crossed from having seats to having none |
| Whole series cancelled | A whole recurring series was cancelled in one action |
The Send test event button delivers a ping event with an empty data object, and the test appears in Recent deliveries as a ping row.
Every type is opt-in per endpoint, the six event.* types included. New endpoints select all 19 by default. An endpoint you created before the lifecycle types existed is not subscribed to them automatically, so add them to its event list in Settings → Integrations to start receiving them.
Payload envelope
Every delivery shares one envelope:
{
"event": "registration.created",
"payload_version": 1,
"occurred_at": "2026-08-27T10:15:00Z",
"backfill": false,
"site_id": 42,
"team_id": 7,
"data": { }
}event: The event identifier that fired.payload_version: Currently 1. Check this to handle future format changes.occurred_at: When the event happened, as an ISO 8601 timestamp.backfill:truemarks a historical replay (for example after connecting a new integration) rather than a live event.site_idandteam_id: The site and team the event belongs to.data: The event-specific payload.
Data objects
registration.* events carry a registration object in data with the attendee, event, ticket type, quantity, order ID, and currency. waitlist.* events carry the waitlist entry with the attendee, event, and position. event.* events carry the event itself, described under "Event lifecycle payloads" below. series.cancelled carries the series, described under "Recurring series" below.
data.amount_paid is denominated in the store currency the sale was charged in, and data.currency carries that ISO code, for example MXN. Read the two together rather than assuming dollars: a store selling in pesos sends peso amounts.
Orders
There is no separate order object. A multi-seat purchase arrives as one registration.created per registration, all sharing the same data.order_id. Group on that field to reconstruct the order.
The whole-order actions in the guest list, Refund order and Cancel order, stay per registration too: each fires one registration.refunded or registration.cancelled delivery per affected registration, and no order-level event is sent. Group those deliveries on data.order_id as well.
Cancellations
registration.cancelled fires once for each cancellation of a registration your receiver has already heard about: a single host cancellation, a bulk cancellation (one event per registration), a waitlist move, or a Squarespace order cancelled on Squarespace's side. The payload carries data.previous_status, usually "active", alongside cancellation_reason and cancelled_at.
A pending registration that was never announced as created does not emit registration.cancelled, because no registration.created was sent for it. An unfinished checkout expiring or being cleaned up is silent for the same reason.
When a cancellation also produces a refund, the integration receives both registration.cancelled and registration.refunded, one each, in transition order. The cancellation releases the seat and the refund returns the money. A plain refund emits only registration.refunded, because a refunded registration is refunded rather than cancelled. Deduplicate on X-Eventually-Delivery-Id as always; the ID is derived per event type, so the two never collide.
Cancelling the event itself is not silent. It sends event.cancelled, covered below.
The event is opt-in per endpoint: existing endpoints receive nothing unless registration.cancelled is selected, and new endpoints select it among the available event types by default.
Event lifecycle payloads
The six event.* types use the same envelope and carry the event in data: id, title, status, start_at, end_at, timezone, location, location_type, venue_name, capacity, sold_out, sold_out_at, schedule_type, occurrence_number, parent_event_id, series_id, categories, tags, created_at, a ticket_types array, and the changes array. Lifecycle deliveries fire only for events that are or were live; draft events never send them.
Each ticket_types entry carries the ticket type's id, name, price, capacity, and sold count.
The keys this payload shares with the event object nested inside a registration.* or waitlist.* payload carry the same names and the same values, so one parser reads both.
Location fields follow the event's location type. For a virtual event, the physical place fields location, venue_name, and address are omitted from the event and registration payloads, and the waitlist entry's venue_name is omitted too. A join link set as the event's location still arrives in location, and location_type still identifies the event as virtual.
How the changes array works
data.changes is always present. Each meaningful edit is one entry with the field, previous, and current values:
"changes": [
{"field": "start_at", "previous": "2026-10-01T18:00:00Z", "current": "2026-10-08T18:00:00Z"},
{"field": "capacity", "previous": 50, "current": 40}
]The list is empty on an event.published for a newly created event, and on event.sold_out, which is a crossing rather than an edit.
Ticket-type price, capacity, and name changes add the tier's ticket_type_id and use field names such as ticket_type.price, ticket_type.capacity, and ticket_type.name. Adding or removing a tier is one ticket_types entry that names the tier in current (added) or previous (removed).
Which edits count
These are the edits that send a delivery:
The start or end time.
The location:
location,location_type,venue_name, andaddress. The finer geo fields (city,region,postal_code,country_code) are derived from geocoding rather than typed by you, so they never fire on their own.The capacity.
A ticket type's price, capacity, or name, and a ticket type added or removed.
A status change that no other event type covers.
Editing the description, an image, the SEO fields, or an internal note sends nothing. The next delivery you do receive carries the current record anyway.
Which changes send which event
A start or end time change always sends
event.rescheduledinstead ofevent.updated, never both, even when another field changed in the same save. Thechangesarray still lists every meaningful field that moved, so a save that shifts the date and cuts the capacity is oneevent.rescheduledcarrying both.Taking a live event back to draft has no type of its own. It arrives as
event.updatedcarrying astatuschange frompublishedtodraft.An event that has finished is marked completed the night it ends and sends
event.completed. There is no secondevent.updatedfor the same transition.Publishing, cancelling, and selling out send their dedicated event types, not
event.updated.Deleting an event is silent, and so is restoring one.
Recurring series
Publishing, updating, or rescheduling a whole series sends one delivery for the series root, not one per occurrence. Cancelling is always per date: every date a cancellation takes down, the series' first date included, sends its own event.cancelled. A date cancelled on its own sends only its own event.cancelled, which you can recognize by its parent_event_id.
Group a series' dates by series_id. It is the series' ID on every date of the series, the first date included, and null on a single event and on an Event Series. It matches the id a series.cancelled delivery carries. parent_event_id is null on the first date, so it cannot tell you that the first date belongs to a series.
A series ticket in an Event Series is announced as one registration when it becomes active; the per-session seats the series ticket generates send nothing. Cancelling the series ticket sends the one cancellation for the ticket, not one per seat.
When a host cancels a whole series, the series also sends one series.cancelled, after the dates' own event.cancelled deliveries. Its data carries the series: id, title, timezone (the series' first date's), status, first_event_id, event_series_id and event_series_status (the Event Series that sells series tickets, or null), and cancelled_event_ids, the dates this cancellation took down. A date cancelled earlier on its own is not listed.
event.completed and event.sold_out are tied to individual occurrences and fire once per occurrence, because each date finishes on its own end time and each date has its own seats.
Selling out
event.sold_out fires on the crossing, once, not on every recount while the event stays sold out. An event that sells out, refunds a seat, and sells out again sends it twice.
Sold out is measured the way a buyer sees it: seats held in an in-flight checkout are gone, and add-on supply cannot keep an event on sale.
What does not send an event
Three state changes are silent today. Each one leaves a receiver that reconciles money or attendance a little behind the truth.
A partial refund. Refunding some of the seats on a registration reduces the seat count and the amount paid rather than refunding the buyer, so no
registration.refundedfires. A whole refund does fire it.Undoing a check-in.
registration.checked_inhas no inverse event, so a check-in reversed by mistake is never announced.Removing a guest from the roster. The registration is discarded quietly, with no cancellation event.
Treat the registration in the next delivery you do receive as the source of truth for these fields, or poll if your reconciliation cannot wait that long.