> ## Documentation Index
> Fetch the complete documentation index at: https://docs.staging.cope-demo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# subscription.plan_changed

> A live subscription has been moved onto a different payment plan.

# subscription.plan\_changed

> Generated from COPE public event contracts. Do not edit this page by hand.

Use this event to follow a subscription that changed plan rather than price — the sibling of subscription.amount\_changed, which announces a new amount on the SAME plan. The switch is applied in place with no proration; the new plan's amount bills at the existing cycle boundary, and the currency, interval and interval count do not move. Read `new_plan_id` for the plan the subscription now runs on and `new_plan_name` for its display name; `old_plan_id` is null today, because the superseded terms are held as an immutable snapshot that carries no plan reference, so `old_plan_name` is what identifies them. `initiated_by` separates the buyer's own switch (`buyer`) from one the business made through the API (`business`), where the buyer is notified rather than asked. `effective_at` is a prediction on the same terms as subscription.amount\_changed.

## Delivery Contract

| Field           | Value                                                                                |
| --------------- | ------------------------------------------------------------------------------------ |
| Encoding        | CloudEvents 1.0 structured JSON                                                      |
| Delivery        | At least once                                                                        |
| Idempotency     | Use the CloudEvents `source` + `id` tuple, or COPE `idempotency_key` when available. |
| Source          | `cope.subscription`                                                                  |
| Subject pattern | `subscription:<identifier>`                                                          |
| Category        | Subscriptions                                                                        |
| Availability    | Available in the public webhook reference.                                           |
| Schema title    | subscription.plan\_changed v1 payload                                                |
| Schema ID       | `https://schemas.cope.com/events/subscription.plan_changed/v1`                       |

## Payload Fields

| Field                        | Required | Type      | Allowed Values              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------------------- | -------- | --------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `business`                   | yes      | `object`  | -                           | The business selling the subscription. Carries `object` (what it is) and `id` (which one); `id` is the public identifier a merchant addresses it by.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `buyer`                      | yes      | `object`  | -                           | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `currency`                   | yes      | `string`  | -                           | ISO 4217 3-letter uppercase currency code. One currency for both sides: a plan is only a candidate for a switch when it matches the subscription's currency, so a plan change never crosses currencies and there is no from/to pair to carry.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `effective_at`               | yes      | \`string  | null\`                      | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | When the new plan is expected to bill, derived at write time from the subscription's next payment date. A PREDICTION, not a confirmation: nothing is scheduled, the renewal simply reads whichever snapshot is current when it runs, so a cycle that moves for an unrelated reason leaves this value stale. The confirmation is stamped internally after Stripe bills the new amount and is deliberately NOT carried here — at emit time it is always null. A consumer that needs the confirmed date reads the change back from the subscriptions API, which renders effective\_confirmed\_at; this event names no internal attempt-row id for it to resolve, and adding a published reference later is additive.                                                                                                                                                 |
| `event_type`                 | no       | `const`   | `subscription.plan_changed` | Optional on the wire, and normally absent: the event's type is carried by the CloudEvents envelope as `type`, so the payload does not repeat it. It is declared here so that if you copy the envelope's type onto the payload before validating the payload against this schema, that validation still passes. Read the envelope rather than depending on this field — a payload without it is valid.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `initiated_by`               | yes      | `string`  | `buyer`, `business`         | Who asked for the switch, and the WHOLE of what this event discloses about the actor. `buyer` is the buyer changing their own plan; `business` is the seller changing it on the buyer's subscription through the API, in which case the buyer is notified rather than asked. Read this before wording anything sent to the buyer: telling someone their seller changed the plan when they changed it themselves, or the reverse, is what the field exists to prevent. No user identifier accompanies it, deliberately: the internal user id subscription.amount\_changed publishes is a sequential platform key, and the buyer's id would be worse — it is the same value at every merchant that person buys from, so publishing it would hand two merchants a key for correlating a shared customer. Which side acted is what a merchant can act on; which person acted is recorded in COPE's audit trail and answered by the subscriptions API. It deliberately does not reuse the `creator` value that subscription.amount\_changed pins — that value belongs to the older contract and is unchanged by this one. |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `interval`                   | no       | \`string  | null\`                      | `day`, `week`, `month`, `year`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Billing cadence after the switch. Carried once rather than as a from/to pair because a plan is only a candidate for a switch when its interval and interval\_count already match the subscription's, so the cadence does not move.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `interval_count`             | no       | \`integer | null\`                      | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `manage_subscription_url`    | yes      | `string`  | -                           | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `new_plan_id`                | yes      | `string`  | -                           | Opaque COPE payment-plan token ('plan\_' + 8 alphanumerics, payment\_plans.public\_id) of the plan the subscription now runs on. Deliberately not pattern-constrained here: the shape is enforced by a database CHECK on the producing side, and pinning it in a published contract would make a future id-shape change a breaking event change.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `new_plan_name`              | yes      | \`string  | null\`                      | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `new_recurring_amount_cents` | yes      | `integer` | -                           | The recurring charge from the next cycle onward, quantity-inclusive. The schema asserts only positivity; the producer enforces the per-currency minimum-charge floor, so the contract does not couple to that constant.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `old_plan_id`                | yes      | \`string  | null\`                      | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Opaque COPE payment-plan token ('plan\_' + 8 alphanumerics) of the plan the subscription was on. NULL in practice today, and that is a recorded gap rather than data loss: a subscription's terms live in an immutable payment\_plan\_snapshots row, and that table carries no payment\_plan foreign key, so the plan the old snapshot was built from is not recoverable. old\_plan\_name below is what identifies the old terms; a later slice that adds the FK populates this field with no version bump.                                                                                                                                                                                                                                                                                                                                                       |
| `old_plan_name`              | yes      | \`string  | null\`                      | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Display name frozen on the superseded snapshot — the human-readable identity of the old terms, and today the only identifier of them. Nullable because payment\_plan\_snapshots.display\_name is.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `old_recurring_amount_cents` | yes      | `integer` | -                           | The recurring charge before the switch, quantity-inclusive — the amount Stripe was billing, not the per-unit snapshot figure.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `order`                      | no       | `object`  | -                           | The order the subscription was bought on. Carries `object` (what it is) and `id` (which one); `id` is the public identifier a merchant addresses it by.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `product`                    | yes      | `object`  | -                           | The product the subscription is for. Carries `object` (what it is) and `id` (which one); `id` is the public identifier a merchant addresses it by.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `reason`                     | no       | \`string  | null\`                      | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `subscription`               | no       | `object`  | -                           | The subscription this event concerns. Carries `object` (what it is) and `id` (which one); `id` is the public identifier a merchant addresses it by.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `subscription_id`            | yes      | \`string  | null\`                      | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | The subscription's public reference ('sub\_' + 16 alphanumerics, line\_items.id), and THE handle for this change: it is the only field naming the subscription, because the line item's internal primary key is deliberately not published. Nullable because the reference is minted on demand rather than by a database default, so a subscription nobody has addressed publicly does not have one yet; a change made through the public API always does, because that is how the request found the subscription, and that is the only path emitting this event today. A consumer that meets a null here has order\_uuid as its correlation anchor. Deliberately replaces the line\_item\_uuid field subscription.amount\_changed declares — that field reads a column line\_items does not have and never had, so it has been null on every event ever emitted. |

## Example CloudEvent

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "business": {
      "name": "example_name",
      "owner_locale": "example_owner_locale"
    },
    "buyer": {
      "email": "buyer@example.com",
      "first_name": "example_first_name",
      "last_name": "example_last_name",
      "locale": "example_locale"
    },
    "currency": "EUR",
    "effective_at": "2026-05-05T12:00:00.000Z",
    "initiated_by": "buyer",
    "manage_subscription_url": "https://example.com",
    "new_plan_id": "example_id",
    "new_plan_name": "example_new_plan_name",
    "new_recurring_amount_cents": 1000,
    "old_plan_id": "example_id",
    "old_plan_name": "example_old_plan_name",
    "old_recurring_amount_cents": 1000,
    "product": {
      "name": "example_name"
    },
    "subscription_id": "example_id"
  },
  "datacontenttype": "application/json",
  "dataschema": "https://schemas.cope.com/events/subscription.plan_changed/v1",
  "id": "subscription.plan_changed:example",
  "idempotency_key": "subscription.plan_changed:example",
  "source": "cope.subscription",
  "specversion": "1.0",
  "subject": "subscription:example",
  "time": "2026-05-05T12:00:00.000Z",
  "type": "subscription.plan_changed"
}
```

## Compatibility

Fields may be added within the same major version. Removing or changing the meaning of a documented field requires a new event version.
