plan.updated
Any mutable plan field changes.
When this fires
A plan is edited through the REST API (PATCH /api/v1/projects/{project}/plans/{plan}) — pricing, name, currency, billing cadence, eligibility filters. Edits made in the creator dashboard do not emit this event, and trial fields are only written (and only then reported) when the payload also carries kind. An active flag sent on a PATCH is reported here as an ordinary changes.active entry. The dedicated plan.activated / plan.deactivated events come only from the /publish and /unpublish endpoints.
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.updated",
"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",
"currency_id": "8f27a0d4-63be-4915-8c07-1a5d9e34b628",
"billing_cycle": "month",
"active": true
},
"changes": {
"price": { "from": "25.0000", "to": "29.00" }
}
}
}Field reference
| Field | Type | Notes |
|---|---|---|
id | string ULID | Unique event id, prefixed evt_. Use for idempotent processing. |
type | string | Always plan.updated for this event. |
created_at | ISO 8601 timestamp | Server-side emission time. |
api_version | string | Webhook API contract version. |
project_id | string UUID | Project this event belongs to. |
data.plan | object | Full post-update plan snapshot (same shape as plan.created). |
data.changes | object<string, {from,to}> | Map of fields that changed. Keys are plan attributes; values are before/after pairs. from is the plan's previous value after model casting (price is a string, enum columns are their backed string value); to is the caller-supplied value as validated. |
Caveats
- Existing subscriptions priced on the old terms are not retroactively re-priced. New checkouts use the new price; renewals follow the rules described billing docs.
- An
activeflag sent on a PATCH is reported here as an ordinarychanges.activeentry. The dedicatedplan.activated/plan.deactivatedevents come only from the/publishand/unpublishendpoints.
Related events
plan.activated,plan.deactivated— dedicated active-flag events.plan.sync_completed— fires after price changes propagate to the PSP catalog.- Plan events overview — back to family overview.
How is this guide?