pass.* events
Time-limited pass access window lifecycle — opened, closed, cancelled, and what happened to each holder.
Fires as a time-limited pass plan's scheduled access windows open, close and — when a creator postpones one — get cancelled. A pass sells access to one dated window rather than an ongoing membership, so most of these describe the window itself: use them to drive slate-level automation such as posting a line-up when access opens or a recap when it ends.
The holder_* events are the exception: each describes one buyer rather than the window.
Cancelling a window resettles every buyer individually and the outcomes need different handling
downstream — a move is a date change to push into a calendar or CRM, a stranding is money owed —
so each holder gets its own event. holder_queued and holder_missed are the same idea applied
to attendance: who is set up to be let in, and who never turned up.
If the plan is a Pass Series, the window-level events and
holder_queued/holder_missed still fire for every underlying window, with the
pass_series.* family firing alongside them to describe the
slate. holder_moved and holder_stranded are the exception — a season-ticket holder gets
pass_series.leg_substituted or pass_series.leg_dropped instead of, not alongside, those
two.
For ordinary per-subscriber grants and revocations, use
member.resource_added and
member.resource_removed instead.
Events
pass.window_scheduled
A new access window came into existence.
pass.window_opened
Access window started and holders were admitted.
pass.window_closed
Access window ended and holders were removed.
pass.window_cancelled
A creator cancelled a window and its holders were resettled.
pass.holder_queued
A holder tapped their invite link and is now queued.
pass.holder_moved
One holder was moved to the next available window.
pass.holder_missed
A window closed and one holder never turned up.
pass.holder_stranded
One holder's pass ended with no replacement — a refund is owed.
What a cancellation emits
Cancelling one window produces several events in a single burst:
| Event | Fires |
|---|---|
pass.holder_moved | Once per holder who was moved (ordinary pass) |
pass_series.leg_substituted | Once per holder who was moved (season ticket) |
pass.holder_stranded | Once per holder whose pass ended (ordinary pass) |
pass_series.leg_dropped | Once per holder who lost that date (season ticket) |
pass.window_cancelled | Once, last, carrying the two tallies |
Which of each pair fires depends on what the holder bought: a single-window pass ends, whereas a season ticket loses one date and carries on.
A cancelled window never subsequently emits pass.window_opened or pass.window_closed —
it is removed from the lifecycle entirely.
Timestamps are UTC
Every payload carries its window times in UTC. A pass schedule is authored in the creator's
timezone, so convert before displaying — a window advertised as 9:00 AM in New York is
13:00+00:00 or 14:00+00:00 depending on daylight saving.
Required abilities
Tokens subscribing to a window-level event (window_scheduled, window_opened,
window_closed, window_cancelled) must carry project-subscription-plan:view: a pass window
belongs to the plan that sells it, so it is scoped with the plan rather than with the
subscription that holds it.
The holder-level events (holder_queued, holder_moved, holder_missed, holder_stranded)
describe a specific purchase and therefore require project-subscription:view instead.
How is this guide?