Early bird discounts live! Claim your offer

plan.deactivated

Active plan flipped inactive.

When this fires

A plan is taken off sale through the REST API (POST /api/v1/projects/{project}/plans/{plan}/unpublish) or the publish_plan MCP tool; automatically when a pass series runs its last date; or when the free-plan entitlement sweep disables an unentitled zero-priced plan. The plan remains visible to existing subscribers and stays in the catalog, but new checkouts cannot select it. Deactivating from the creator dashboard does not emit this event.

Required ability

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

Payload

{
  "id": "evt_01HX...",
  "type": "plan.deactivated",
  "created_at": "2026-05-18T10:05:00Z",
  "api_version": "2026-05-01",
  "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
  "data": {
    "plan": {
      "id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",
      "name": "Premium Monthly",
      "price": "29.00",
      "active": false
    }
  }
}

Payload (series retired automatically)

{
  "id": "evt_01HX...",
  "type": "plan.deactivated",
  "created_at": "2026-05-18T10:05:00Z",
  "api_version": "2026-05-01",
  "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
  "data": {
    "plan_id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",
    "plan_name": "Summer Season",
    "reason": "series_exhausted",
    "window_count": 12,
    "successor_plan_id": "b1a7c3d5-2e48-4f60-9a1b-7c5d3e820f94"
  }
}

The two shapes are disjoint. The publish-state path sends data.plan and nothing else; an automatically retired series sends the five flat keys and no data.plan object. Branch on whether data.plan or data.plan_id is present before reading any other field.

Field reference

FieldTypeNotes
idstring ULIDUnique event id, prefixed evt_. Use for idempotent processing.
typestringAlways plan.deactivated for this event.
created_atISO 8601 timestampServer-side emission time.
api_versionstringWebhook API contract version.
project_idstring UUIDProject this event belongs to.
data.planobjectSent by the publish-state path only; absent when a series retires itself.
data.plan.idstring UUIDPlan identifier.
data.plan.namestringDisplay name.
data.plan.pricestringDecimal amount as a string, e.g. "29.00".
data.plan.activebooleanAlways false for this event.
data.plan_idstring UUIDSeries-retirement payload only. The plan taken off sale.
data.plan_namestringSeries-retirement payload only. Display name of that plan.
data.reasonstringSeries-retirement payload only. Currently always series_exhausted.
data.window_countintegerSeries-retirement payload only. Number of passes the finished season held.
data.successor_plan_idstring UUID, nullableSeries-retirement payload only. The next season linked on the series; null when none is set.

Caveats

  • Existing subscriptions on the plan are unaffected and continue to renew until cancelled or expired.
  • For permanent removal use plan.deleted.

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