Subscription

The Subscription object represents a recurring billing relationship with a customer.

A Subscription object represents an ongoing billing relationship where a customer is charged on a recurring basis. Subscriptions are created when a customer purchases a subscription Product and manage the lifecycle of recurring Payments.

Subscriptions track billing intervals, status changes, and link to all associated Payments and Orders. You can use the API to manage subscriptions including updating, pausing, and cancelling them.

Endpoints

MethodEndpointDescription
GET/v0/subscriptions/listList and filter subscriptions
POST/v0/subscriptions/createCreate a new subscription
GET/v0/subscriptions/{subscriptionIdOrNumber}Retrieve a subscription
PATCH/v0/subscriptions/{subscriptionIdOrNumber}/updateUpdate a subscription
POST/v0/subscriptions/{subscriptionIdOrNumber}/chargeCharge a subscription immediately
PATCH/v0/subscriptions/{subscriptionIdOrNumber}/cancelCancel a subscription
PATCH/v0/subscriptions/{subscriptionIdOrNumber}/pause-collectionPause subscription billing
PATCH/v0/subscriptions/{subscriptionIdOrNumber}/endTrialEnd a trial immediately and start paid billing

Ending a trial early

A subscription in trialing status can be converted to a paid subscription right away with the endTrial endpoint. The first invoice is created and charged immediately using the payment method on file, and the outcome (emails, webhooks, orders) is identical to the trial ending naturally. The request fails with a 400 if the subscription is not trialing or has no payment method saved.

Multiple line items

The create, update, and charge endpoints accept an items array with up to 20 line items, so a single subscription can bill several offers together (e.g. a package plus add-ons) while the invoice and webhook payloads keep the full per-line breakdown.

Because one subscription maps to a single Stripe subscription, all items must be on the same cadence:

  • Same currency — every item resolves to the same currency (either explicitly or from its offer).
  • Same billing interval — every offer shares the same interval and interval_count. Mixing, for example, a monthly and a yearly offer is rejected with a 400 rather than failing at Stripe.
  • No trial — a trial is only applied to single-item subscriptions; multi-item subscriptions start billing immediately.
  • No discount codes — discount codes are not supported when a subscription has more than one item.

Requests that violate these rules return a 400 with a descriptive message.

The Subscription object

objectstring

Object type identifier. Always "subscription" for Subscription objects.

idstringrequired

Subscription identifier, based on the initial order number.

statusstringrequired

Current subscription status. Possible values: active, past_due, canceled, unpaid, incomplete, incomplete_expired, trialing, paused

createdAtinteger | null

Unix timestamp (milliseconds) when the subscription was created.

currentIntervalStartinteger | null

Unix timestamp (milliseconds) when the current billing interval started.

currentIntervalEndinteger | null

Unix timestamp (milliseconds) when the current billing interval ends.

cancelAtIntervalEndboolean

Whether the subscription will cancel at the end of the current interval. Defaults to false.

canceledAtinteger | null

Unix timestamp (milliseconds) when the subscription was cancelled, if applicable.

userIdstring | null

UUID of the subscribed User.

userUser | null

Expanded User object with basic subscriber information.

user properties
objectstring

Always "user".

idstringrequired

Unique identifier (UUID) for this user.

usernamestring | null

Username of the user.

orderIdstringrequired

UUID of the initial Order that created this subscription.

orderNumberstringrequired

Human-readable number of the initial order.

orderOrderrequired

Expanded Order object for the initial subscription order.

order properties
objectstring

Always "order".

idstringrequired

Unique identifier (UUID) for this order.

numberstringrequired

Human-readable order number.

statusstringrequired

Current order status.

lastPaymentIdstring | null

UUID of the most recent Payment for this subscription.

lastPaymentNumberstring | null

Human-readable number of the most recent payment.

lastPaymentPayment | null

Expanded Payment object for the most recent charge.

lastPayment properties
objectstring

Always "payment".

idstringrequired

Unique identifier (UUID) for this payment.

typestringrequired

Payment type: subscription_initial, subscription_interval, subscription_update, subscription_extra

numberstringrequired

Human-readable payment number.

statusstringrequired

Current payment status.


Subscription lifecycle


Example response

{
  "status": "success",
  "data": {
    "subscription": {
      "object": "subscription",
      "id": "#SUB123DEF456",
      "status": "active",
      "createdAt": 1705590000000,
      "currentIntervalStart": 1708268400000,
      "currentIntervalEnd": 1710946800000,
      "cancelAtIntervalEnd": false,
      "canceledAt": null,
      "userId": "123e4567-e89b-12d3-a456-426614174000",
      "user": {
        "object": "user",
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "username": "johndoe"
      },
      "orderId": "550e8400-e29b-41d4-a716-446655440000",
      "orderNumber": "#ABC123DEF456",
      "order": {
        "object": "order",
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "number": "#ABC123DEF456",
        "status": "PAID"
      },
      "lastPaymentId": "660e8400-e29b-41d4-a716-446655440001",
      "lastPaymentNumber": "#PAY789GHI012",
      "lastPayment": {
        "object": "payment",
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "type": "subscription_interval",
        "number": "#PAY789GHI012",
        "status": "PAID"
      }
    }
  }
}

Webhook events

EventTypical use
subscription_createdSubscription exists; first payment may still be processing
payment_successFirst or recurring charge succeeded — fulfill here
subscription_intervalNew billing period charged (renewal)
subscription_updatedPlan change, cancel-at-period-end, trial ended, etc.
subscription_cancelledSubscription ended

See Event types and Webhooks overview for why subscription_created can include PENDING payments and why you should not rely on it alone for access grants.


Last updated