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

# Subscriptions

> Create, upgrade, downgrade, cancel, and restore subscriptions safely

Subscription changes run from a trusted merchant backend. Derive customer and subscription IDs from server-owned records; never accept either as authoritative browser input.

## Create a subscription

Use checkout for payment-gated plans. Direct subscription creation is available for flows that do not require interactive payment.

```ts theme={null}
const subscription = await nozle.subscribe('customer_123', 'free')
```

## Payment-aware plan changes

Use checkout for paid upgrades. The current paid plan remains active until verified payment succeeds. A lower-value change may return a scheduled result for the next billing boundary.

```ts theme={null}
const checkout = await nozle.checkout(
  'customer_123',
  'scale_monthly',
  'https://app.example.com/settings/billing',
)
```

The React `UpgradeButton` opens a caller-supplied preview and delegates checkout to your `BillingProvider.createCheckout` callback:

```tsx theme={null}
<UpgradeButton
  planCode="scale_monthly"
  preview={preview}
  onStripeClientSecret={setClientSecret}
  onUpgraded={refreshBillingState}
  onDowngradeScheduled={refreshBillingState}
/>
```

## Simple cancellation

The Node.js and Python SDKs default to end-of-period cancellation:

```ts theme={null}
const result = await nozle.cancelSubscription('customer_123', 'subscription_123')
console.log(result.subscription.ending_at)
```

```python theme={null}
result = nozle.cancel_subscription("customer_123", "subscription_123")
print(result["subscription"].get("ending_at"))
```

Pass `immediate` explicitly only after the merchant confirms that access should end now.

## Settlement transitions

The backend SDKs provide preview and apply operations for `cancel`, `downgrade`, and `uncancel`.

```ts theme={null}
const params = {
  customerId: 'customer_123',
  subscriptionId: 'subscription_123',
  operation: 'downgrade' as const,
  timing: 'end_of_period' as const,
  targetPlanCode: 'growth_monthly',
  creditAction: 'none' as const,
}

const preview = await nozle.previewSubscriptionTransition(params)

const result = await nozle.applySubscriptionTransition(
  params,
  'transition-subscription-123-growth-v1',
)
```

Settlement options include:

* timing: `end_of_period` or `immediate`;
* billing anchor: `keep_anchor` or `reset_anchor`;
* proration: `prorate_immediately` or `none`;
* credit action: `credit`, `refund`, `offset`, or `none`;
* refund mode: `prorated` or `full`; and
* final invoice: `generate` or `skip`.

Preview first, present the monetary effect to the merchant, and apply with a stable idempotency key. End-of-period transitions require `creditAction: 'none'`; uncancel does not accept settlement options.

<Warning>
  Payment webhooks and the applied transition result are authoritative. Do not unlock paid access from a browser callback alone.
</Warning>

## Independent plans per Entity

One customer can own multiple Entity subscriptions with different plans and billing intervals:

```text theme={null}
Customer: workspace_123
├── user_42 → Pro monthly
└── user_43 → Max annual
```

Each Entity receives a stable subscription identity and follows the standard checkout, invoice, renewal, transition, and cancellation lifecycle. Operations are isolated: upgrading, downgrading, or cancelling one Entity does not mutate another Entity.

Nozle revalidates the live Entity before checkout. Suspended, deleted, or recreated Entity identities fail closed. See [Entity Subscriptions](/api/entity-subscriptions).

For seat-pool purchases, bulk Entity checkout combines multiple Pro/Max-style Entity subscriptions into one invoice and one Stripe payment. The first successful paid Entity checkout can establish an anniversary billing anchor for the customer; later Entity purchases align to that anchor and prorate their initial period.
