pass_series.completed

A holder reached the last date of their season, with the final attendance tallies.

When this fires

The last date on one holder's season ticket closed. Their season is over.

Fires per holder, not per series, because "finished" is a fact about a purchase: two people holding the same season reach its end on different dates when one of them bought in late.

This is the renewal signal

The tallies are the half worth acting on. A completion with two of ten attended is a churn signal; the same completion with ten of ten is a renewal one. If the creator linked a next season, the holders-only presale opens around the same moment — see pass_series.presale_opened.

Required ability

project-subscription:view — token must carry this at mint time to subscribe an endpoint to this event.

Payload

{
  "id": "evt_01HX...",
  "type": "pass_series.completed",
  "created_at": "2026-11-29T21:00:06Z",
  "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_attended": 8,
    "passes_missed": 2,
    "successor_plan_id": "b3e70d21-5f94-4a6c-8127-cd4a91e6f508"
  }
}

Field reference

FieldTypeNotes
idstring ULIDUnique event id, prefixed evt_. Use for idempotent processing.
typestringAlways pass_series.completed for this event.
created_atISO 8601 timestampServer-side emission time.
api_versionstringWebhook API contract version.
project_idstring UUIDProject this event belongs to.
data.subscription_idstring UUIDThe season ticket that finished.
data.subscriber_idstring UUIDThe holder.
data.plan_idstring UUIDThe series plan.
data.plan_namestringIts name.
data.passes_totalintegerDates this holder's season covered.
data.passes_attendedintegerHow many they joined.
data.passes_missedintegerHow many they did not.
data.successor_plan_idstring UUID | nullThe next season, if the creator linked one. null means there is no follow-on.

Caveats

  • The subscription is expired at this point, which is normal and not a failure. A dated purchase ends when its dates run out.
  • passes_total is this holder's slate, not the plan's. A mid-season buyer received fewer dates for the same price and their totals reflect that.
  • passes_attended + passes_missed can be less than passes_total when some dates were already covered by passes the holder owned individually — those were not issued twice.
  • successor_plan_id being present does not mean the holder has been invited yet. The presale opens when the series retires, which is a separate event.
  • The plan itself is deactivated automatically once its last date has run for everybody. That arrives as plan.deactivated with reason: series_exhausted.

How is this guide?

On this page

Subscriby is a product designed by you — for you.

No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request