pass_series.* events
Season-ticket lifecycle: bought, each date completing, dates added or dropped mid-season, and the holders-only presale on the next one.
Season-ticket lifecycle: bought, each date completing, dates added or dropped mid-season, and the holders-only presale on the next one. Fires across the life of a Pass Series, a season ticket sold once that grants a whole slate of other pass plans' dated windows.
The family exists because a series is not just a pass with more dates. A season grows when rules absorb new windows, changes when a date is cancelled, and progresses as each date runs, and none of that has an equivalent on a single-window pass. The pass.* family still fires for every underlying window, because each date is a real window on a real plan; these describe the slate.
Two payload facts integrators get wrong.
refund_per_holderonpass_series.leg_droppedis a figure, not an action. Subscriby never moves the money; the creator does. An automation that treats it as "already refunded" will double-refund.pass_series.purchasedfires in addition tosubscription.activated, because a series is a subscription row. An endpoint subscribed to both gets two deliveries for one purchase and must de-duplicate onsubscription_id.
| Event | Fires when |
|---|---|
pass_series.purchased | A season ticket was bought and its whole slate issued. |
pass_series.leg_completed | One date of a holder's season finished, with running attendance. |
pass_series.completed | A holder reached the last date, with final tallies. |
pass_series.leg_added | A rule absorbed a new window into a live season. |
pass_series.leg_substituted | A cancelled date was replaced and a holder moved. |
pass_series.leg_dropped | A cancelled date left a season, with the pro-rata figure. |
pass_series.seats_exhausted | A capped season sold its last seat. |
pass_series.presale_opened | Holders were given first refusal on the next season. |
Which scope each event is about
| Scope | Events | Ability |
|---|---|---|
| The slate: the plan and its dates | leg_added, seats_exhausted, presale_opened | project-subscription-plan:view |
| One holder: a purchase and a person | purchased, leg_completed, leg_substituted, leg_dropped, completed | project-subscription:view |
The split mirrors the pass.* family, where window_* events describe the window and holder_* events describe a person. Subscribe to the scope you actually act on.
Building a season timetable elsewhere
The four events that keep an external calendar honest, in the order you need them:
pass_series.purchased: create the entries. Read the plan'spass_series.windowsfor the full slate.pass_series.leg_added: add an entry. Seasons composed with rules grow after they sell.pass_series.leg_substituted: move an entry, usingfrom_window_idandto_window_id.pass_series.leg_dropped: remove an entry.
Subscribers get this for free: the portal offers a calendar feed that stays in step on its own. The events are for putting the same schedule somewhere Subscriby cannot reach.
Example envelope
{
"id": "evt_01HX...",
"type": "pass_series.purchased",
"created_at": "2026-09-01T11:03:44Z",
"api_version": "2026-05-01",
"project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
"data": {
"subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4",
"subscriber_id": "2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80",
"plan_id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",
"plan_name": "Autumn Season Ticket",
"passes_total": 10,
"passes_granted": 9,
"passes_already_held": 1,
"starts_at": "2026-09-20T13:00:00Z",
"ends_at": "2026-11-29T22:00:00Z",
"seat_cap": 50,
"seats_remaining": 13
}
}Related
pass.*events: the underlying windows opening, closing and being cancelled. Every series date is one of these too.plan.deactivated: a finished season taking itself off sale, withreason: series_exhausted.- Pass Series guide: the feature itself, control by control.
Events
pass_series.purchased
Someone bought a season ticket and their whole slate was issued.
pass_series.leg_added
An automatic rule absorbed a newly-scheduled window into a live series.
pass_series.leg_completed
One date of a holder's season finished, with their running attendance.
pass_series.leg_substituted
A cancelled date in a season was replaced, and one holder was moved to the replacement.
pass_series.leg_dropped
A cancelled date left a holder's season with no replacement, carrying the pro-rata figure.
pass_series.seats_exhausted
A capped season ticket sold its last seat.
pass_series.completed
A holder reached the last date of their season, with the final attendance tallies.
pass_series.presale_opened
A finished season's holders were given first refusal on the next one.
Compare with the current pages
How is this guide?