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

# Subscription Events

> State-machine transitions on a subscription, each with a realistic sample payload.

State-machine transitions on a subscription. These carry the `subscription` object (and the `customer` and `plan` resolved through it). The shared delivery envelope, headers, and inline-expansion rules are on the [webhooks overview](/webhooks/delivery) and the [event index](/api-reference/webhook-events); every sample below shows the full envelope.

<AccordionGroup>
  <Accordion title="subscription_created" icon="circle-plus">
    Fires when a subscription is created, through `POST /v1/subscriptions`, or when a checkout that binds a plan settles. Emitted by `SubscriptionService.create` and `CheckoutSettlement`.

    ```json theme={null}
    {
      "id": "evt_01hkbz5created0000000000000",
      "type": "subscription_created",
      "createdAt": "2026-06-28T09:00:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "incomplete",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_activated" icon="circle-check">
    Fires when a subscription becomes `active`: a trial converts, or the first charge succeeds. Emitted via the state machine (`activate`).

    ```json theme={null}
    {
      "id": "evt_01hkbz5activated000000000000",
      "type": "subscription_activated",
      "createdAt": "2026-06-28T09:05:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "active",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_updated" icon="pen">
    Fires when a mutable field changes without a status transition. Today that is setting cancel-at-period-end. The changed flag is carried alongside the `subscription`.

    ```json theme={null}
    {
      "id": "evt_01hkbz5updated00000000000000",
      "type": "subscription_updated",
      "createdAt": "2026-06-28T10:00:00.000Z",
      "data": {
        "cancelAtPeriodEnd": true,
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "active",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_plan_changed" icon="arrow-right-arrow-left">
    Fires when a subscription's plan changes: immediately via `POST /v1/subscriptions/{id}/change-plan` (carries `fromPlanId`, `toPlanId`, and the `proration` result) or when a scheduled change is applied at renewal (carries `toPlanId` and `scheduled: true`). The changed-to plan is the one expanded into `plan`.

    ```json theme={null}
    {
      "id": "evt_01hkbz5planchg0000000000000",
      "type": "subscription_plan_changed",
      "createdAt": "2026-06-28T11:00:00.000Z",
      "data": {
        "fromPlanId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
        "toPlanId": "plan_01hkbz9a8b7c6d5e4f3g2h1j0k",
        "proration": { "amount": 41096, "kind": "credit" },
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "active",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz9a8b7c6d5e4f3g2h1j0k",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz9a8b7c6d5e4f3g2h1j0k",
          "name": "Team Annual",
          "amount": 1200000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_paused / subscription_resumed" icon="circle-pause">
    Fire when a subscription is paused or resumed (`POST /v1/subscriptions/{id}/pause` and `.../resume`). Each carries just the `subscription` (with `customer` and `plan`). The example is `subscription_paused`; `subscription_resumed` is identical with `type` and `status: "active"`.

    ```json theme={null}
    {
      "id": "evt_01hkbz5paused00000000000000",
      "type": "subscription_paused",
      "createdAt": "2026-06-28T12:00:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "paused",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_past_due" icon="triangle-exclamation">
    Fires when a renewal charge fails and the subscription moves to `past_due`; dunning has begun. Emitted by the state machine (`renewal_failed`) from the dunning service.

    ```json theme={null}
    {
      "id": "evt_01hkbz5pastdue0000000000000",
      "type": "subscription_past_due",
      "createdAt": "2026-07-28T09:00:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "past_due",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_recovered" icon="rotate-right">
    Fires when dunning wins and a `past_due` subscription returns to `active`. Emitted by the state machine (`recover`).

    ```json theme={null}
    {
      "id": "evt_01hkbz5recovrd0000000000000",
      "type": "subscription_recovered",
      "createdAt": "2026-07-29T09:00:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "active",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_unpaid" icon="ban">
    Fires when dunning is exhausted and the subscription is written off to `unpaid`. Emitted by the state machine (`exhaust_dunning`).

    ```json theme={null}
    {
      "id": "evt_01hkbz5unpaid00000000000000",
      "type": "subscription_unpaid",
      "createdAt": "2026-08-05T09:00:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "unpaid",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_cancelled" icon="circle-xmark">
    Fires on an immediate cancel (`POST /v1/subscriptions/{id}/cancel`). Any unused-time credit granted at cancellation is carried as `creditKobo` (minor units; `0` when none). Cancelling at period end emits `subscription_updated` instead, then `subscription_cancelled` when the period actually ends.

    ```json theme={null}
    {
      "id": "evt_01hkbz5cancel00000000000000",
      "type": "subscription_cancelled",
      "createdAt": "2026-07-01T09:00:00.000Z",
      "data": {
        "creditKobo": 41096,
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "canceled",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_expired" icon="hourglass-end">
    Fires when a subscription reaches its `maxCycles` and stops. Emitted by the state machine (`reach_limit`).

    ```json theme={null}
    {
      "id": "evt_01hkbz5expired0000000000000",
      "type": "subscription_expired",
      "createdAt": "2029-06-28T09:00:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "expired",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2028-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2029-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="subscription_incomplete_expired" icon="clock">
    Fires when an `incomplete` subscription expires before it was ever activated (the initial payment never completed). Emitted by the state machine (`expire_incomplete`).

    ```json theme={null}
    {
      "id": "evt_01hkbz5incexp00000000000000",
      "type": "subscription_incomplete_expired",
      "createdAt": "2026-06-28T10:00:00.000Z",
      "data": {
        "subscription": {
          "id": "sub_01hkbz3m4n5p6q7r8s9t0v1w2x",
          "status": "incomplete_expired",
          "customerId": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "planId": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "currentPeriodStart": "2026-06-28T09:00:00.000Z",
          "currentPeriodEnd": "2027-06-28T09:00:00.000Z",
          "trialEndsAt": null
        },
        "customer": {
          "id": "cus_01hkbz2a1b2c3d4e5f6g7h8j9k",
          "email": "ada@example.com",
          "name": "Ada Lovelace",
          "phone": "+2348012345678"
        },
        "plan": {
          "id": "plan_01hkbz1z0y9x8w7v6u5t4s3r2q",
          "name": "Pro Annual",
          "amount": 500000,
          "currency": "NGN",
          "interval": "year",
          "intervalCount": 1
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>
