# Subscriptions

> A full subscription system with trials, seats, metered usage, proration, coupons, dunning and a customer portal, charged on your own processor account.

A subscription bills a customer for one or more recurring prices of a brand. Ownrecord runs the whole lifecycle: trials, renewals, plan changes, failed payments, pauses and cancellations. It's the same system Ownrecord uses to sell its own plans.

## What it covers

- **Prices:** flat, per seat, metered or tiered, and several items with different intervals in one subscription.
- **Trials**, with or without a payment method up front.
- **Plan and quantity changes** with proration, now or at the end of the period.
- **Coupons and promotion codes.**
- **Included credits:** a price can put credits into the customer's [wallet](https://ownrecord.io/docs/concepts/wallets.md#subscription-credits) every period.
- **Collection:** charge a saved card automatically, or send an invoice to be paid by bank transfer.
- **Dunning:** retries and reminders when a renewal payment fails (see [collection and dunning](https://ownrecord.io/docs/concepts/collection.md)).
- **Pause, resume and cancel**, now or at the end of the period.
- **[Entitlements](https://ownrecord.io/docs/concepts/entitlements.md)**, so your product knows what each customer may use.
- A **customer portal** where customers manage their own subscriptions, payment methods and invoices.

Every renewal is quoted by the [tax engine](https://ownrecord.io/docs/concepts/tax-engine.md) on its own tax point, and every invoice is issued in your entity's name and numbering.

## Lifecycle

```text
create → incomplete ──(paid within 23 h)──→ active or trialing
                    └──(not paid)──→ incomplete_expired
create → trialing ──(trial ends, payment succeeds or nothing is due)──→ active
                  └──(trial ends, no payment method)──→ canceled or paused
active ──(renewal payment fails)──→ past_due ──(payment succeeds)──→ active
                                             └──(retries exhausted)──→ unpaid or canceled
active ──(pause)──→ paused ──(resume)──→ active
any state that isn't final ──(cancel now)──→ canceled
active ──(cancel at period end)──→ stays active until the period ends ──→ canceled
```

| Status               | Meaning                                                                                             |
| -------------------- | --------------------------------------------------------------------------------------------------- |
| `incomplete`         | Waiting for the first payment, or for the customer to save a payment method.                        |
| `incomplete_expired` | The first payment wasn't completed within 23 hours.                                                 |
| `trialing`           | In a trial.                                                                                         |
| `active`             | Paid and running.                                                                                   |
| `past_due`           | A renewal payment failed and retries are running.                                                   |
| `unpaid`             | Retries are exhausted. No new invoices and no entitlements; paying the open invoice reactivates it. |
| `paused`             | Collection is stopped until it resumes, by hand or on a set date.                                   |
| `canceled`           | Ended. A subscription set to cancel at period end can be reactivated before then.                   |

What happens when a trial ends without a payment method, and when retries are exhausted, is set by each brand.

Every change of status is recorded as a subscription event and sent to your webhooks, so your product can react.

## Creating a subscription

Subscribe an existing customer with the API, or let customers subscribe themselves through [checkout](#subscribing-through-checkout).

```http
POST /api/v1/subscriptions
Idempotency-Key: 2b7e…

{
  "customerId": "cus_01m4…",
  "items": [{ "priceId": "price_01m4…", "quantity": 5 }],
  "collectionMethod": "charge_automatically",
  "trialDays": 14,
  "promotionCode": "LAUNCH20"
}
```

- **Items:** up to 20 recurring prices of one currency. Their intervals must be whole multiples of each other, such as monthly and yearly. Licensed prices take a `quantity` (seats); metered prices bill what is used.
- **Collection:** `charge_automatically` charges the customer's default payment method, or the one in `paymentMethodId`. `send_invoice` emails each invoice with your bank details, due `daysUntilDue` days after its issue date (14 by default), and needs no payment method.
- **Trial:** `trialDays` or `trialEnd`. Without either, the prices' own trial applies. `trialEndBehavior` says what happens if the trial ends without a payment method: `convert` (bill anyway: the invoice stays open and the subscription goes `past_due`, see [dunning](https://ownrecord.io/docs/concepts/collection.md)), `cancel_if_no_payment_method` or `pause_if_no_payment_method`.
- **Billing cycle anchor:** by default the first period starts now, or when the trial ends. A later `billingCycleAnchor` starts the cycle on that date. With `prorationBehavior: create_prorations` or `always_invoice`, the partial first period is billed now. With `none`, nothing is billed until the anchor.
- **Discounts:** a `couponId` or a customer-facing `promotionCode`. See [discounts](https://ownrecord.io/docs/concepts/discounts.md).

What happens next depends on what is due:

| Situation                                                  | Result                                                                                                                                                                     |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A free plan: every licensed price is zero, nothing metered | `active`, with no invoices.                                                                                                                                                |
| A trial                                                    | `trialing`. The first invoice comes when the trial ends.                                                                                                                   |
| `send_invoice`                                             | `active`. The first invoice is finalized and emailed now.                                                                                                                  |
| `charge_automatically` with a payment method               | `incomplete` until the first invoice is paid, then `active`. The charge runs right after the subscription is saved; the processor's webhook records the payment.           |
| `charge_automatically` without a payment method            | `incomplete`. The answer has `paymentSetup.url`: a checkout page in setup mode where the customer saves a card. The first invoice is charged as soon as the card is saved. |

An `incomplete` subscription that isn't paid within 23 hours becomes `incomplete_expired`. A plan of zero-priced licensed items with a metered item still needs a payment method, because usage will be billed.

The first invoice is a real invoice: numbered in the brand's series, with tax quoted on its tax point. An invoice that adds up to zero, such as a fully discounted first period, isn't issued at all; the history says it was skipped.

## Subscribing through checkout

A [checkout session](https://ownrecord.io/docs/concepts/checkout.md) in `subscription` mode sells recurring prices on the hosted page:

```http
POST /api/v1/checkout/sessions

{
  "mode": "subscription",
  "lineItems": [{ "lookupKey": "pro_monthly", "quantity": 1, "adjustableQuantity": { "min": 1, "max": 50 } }],
  "allowPromotionCodes": true,
  "subscriptionData": { "trialDays": 14 },
  "successUrl": "https://app.example/welcome"
}
```

- Without a trial, the customer pays the first invoice on the page. The card is saved for renewals at the same time.
- With a trial, nothing is charged today: the page saves the card and shows when the trial ends. With `subscriptionData.trialRequiresPaymentMethod: false`, the trial starts without a card.
- `adjustableQuantity` lets the customer choose the number of seats. `allowPromotionCodes` adds a promotion code field.
- The page quotes the tax on the first paid invoice and shows what is due today.

The subscription is created when the processor confirms the payment or the saved card, never earlier. A session in **`setup` mode** has no line items: it only saves a card for a customer. That's the page that `paymentSetup.url` points to.

## Changing a subscription

`PATCH /api/v1/subscriptions/{id}` changes the items: swap a price (`{ id, priceId }`), change seats (`{ id, quantity }`), add an item (`{ priceId, quantity }`) or remove one (`{ id, deleted: true }`). Items you don't name stay as they are. Send the `version` you read as `expectedVersion`, so two people changing the same subscription can't overwrite each other.

By default, an **upgrade** or a change of billing interval applies now: the unused time of the old items is credited and the new items are charged for the rest of the period, on an invoice issued and charged at once (`always_invoice`). A **downgrade** waits for the end of the period: it's stored as `pendingUpdate` and applied at the renewal.

Override the defaults with `effective` (`now` or `period_end`) and `prorationBehavior`:

- `always_invoice` invoices the difference now;
- `create_prorations` adds the difference to the next invoice; when the change lowers the price, the unused time goes to the customer's credit balance instead;
- `none` changes the items without billing the difference.

If the charge for an upgrade fails, the change still applies and the invoice stays open for collection, which retries it. With `paymentBehavior: pending_if_incomplete`, the old items stay until the invoice is paid instead.

**Preview first.** `POST /api/v1/subscriptions/{id}/preview_change` takes the same changes and answers with exactly what would happen: when it applies, how it's settled, the invoice with its lines and tax, any credit, and the monthly recurring revenue before and after. It runs the change and rolls it back, so the invoice in the preview is the invoice the change issues, apart from its number. The console shows this preview before you confirm a plan change.

Credits for unused time go to the customer's [credit balance](https://ownrecord.io/docs/concepts/invoices.md), at the prices' amounts before tax, and reduce the next invoices.

## Pause, cancel and reactivate

- **Pause** (`POST /api/v1/subscriptions/{id}/pause`): renewals stop collecting. `behavior` says what happens to their invoices: `void` (none are issued; the default), `keep_as_draft` or `mark_uncollectible`. Give `resumesAt` to resume automatically, or resume by hand with `/resume`.
- **Cancel** (`POST /api/v1/subscriptions/{id}/cancel`): `mode: at_period_end` (the default) keeps the subscription running until the period ends; until then `/reactivate` undoes it. `mode: now` ends it at once: usage so far and pending items go on a final invoice, and `prorate: true` credits the unused time to the credit balance. `refund: true` refunds the unused time to the customer's card instead, with a [credit note](https://ownrecord.io/docs/concepts/refunds.md) for every paid invoice with time left (it needs the refund permission; an invoice paid by bank transfer or from the credit balance can't be refunded that way: `subscription_refund_not_supported`).
- Store why the customer left with `feedback` (such as `too_expensive`) and an optional `comment`.

Customers can do much of this themselves in the [customer portal](https://ownrecord.io/docs/concepts/customer-portal.md), as your portal settings allow: switch plan along your plan-change matrix after seeing the price, change the quantity, apply a promotion code, choose the card, cancel (recorded with `cancellation.by: "customer"` and their reason) and keep a subscription they canceled. They get an email when a subscription renews, is set to end and ends (not after unsuccessful dunning, which dunning's own emails cover).

## Metered items

A metered item bills a customer's usage of its meter. A customer can have **at most one live metered item per meter**, across all their subscriptions, because the usage of a meter is billed once per customer. Adding a second one is refused with `subscription_meter_conflict`. [Usage events](https://ownrecord.io/docs/concepts/usage.md) can name the item they belong to with `subscriptionItemId`, or leave it out.

Usage is billed **in arrears**: the renewal invoice at the end of a period bills that period's usage, with the price's included quantity, tiers, minimum and maximum applied to the whole period. Usage that arrives after its period was invoiced (a **late event**) is billed on the next invoice as its own "Late usage" line, the difference between what the period cost with and without it. If a period's usage turns negative (refunds reducing a volume, for example), its line is zero and the amount goes to the customer's credit balance.

**Usage thresholds.** For usage-heavy customers, set `usageThreshold` on the subscription (`POST` or `PATCH`, an amount in the subscription's currency). Once the usage not yet invoiced would cost at least that much, it's invoiced and charged at once instead of waiting for the period end. The period's renewal then bills only what the period's usage costs beyond that, so tiers and minimums still apply to the whole period.

## Renewals

At the end of each period the subscription **renews**:

1. **An hour before** the period ends, the renewal invoice is created as a draft, so you can see it and add invoice items to it.
2. **At the end of the period** its lines are computed again and it's finalized: licensed items for the new period (in advance), metered usage of the period that ended (in arrears), late usage, pending items such as prorations, then discounts, a fresh tax quote and the customer's credit balance. It's charged to the saved payment method, or sent for `send_invoice` subscriptions, and the subscription moves to its next period (`subscription.renewed`).

A change scheduled for the end of the period (a downgrade, or a [price change](#price-changes-for-existing-subscribers)) applies at the renewal, and the new period is billed at the new price. A subscription set to cancel at the end of its period gets a final invoice of its usage and pending items instead, and ends. A trial's end works the same way, with the first invoice. A paused subscription renews by its pause `behavior`: no invoice (`void`), a draft that stays a draft (`keep_as_draft`), or an invoice written off at once (`mark_uncollectible`). An `unpaid` subscription issues no new invoices. With items of different intervals, each item is billed when its own period ends.

**Included credits.** A price with `includedCredits` grants them into the customer's [wallet](https://ownrecord.io/docs/concepts/wallets.md#subscription-credits) in the same step: at the start (or when a trial ends) and at every renewal while the subscription is active or past due, once per item and period. Paused and unpaid periods, trials and previews get none.

**The upcoming invoice.** `GET /api/v1/invoices/upcoming?subscriptionId=sub_…` shows the invoice the next renewal will issue, as it would be issued now: it runs the renewal and rolls it back, so it has every line, the tax and the amount due, but no number. Seven days before a renewal, the same preview goes to your webhooks as `invoice.upcoming`.

**Revenue recognition.** What a renewal bills in advance is booked as deferred revenue and recognised day by day over the period it pays for, to the second, once the invoice is paid (or written off). [The ledger](https://ownrecord.io/docs/concepts/ledger.md) shows it moving from `deferred_revenue` to the product's `revenue` account.

## Price changes for existing subscribers

Prices can't change once they are used, so to change what existing subscribers pay, create a new price and **migrate** them to it:

```http
POST /api/v1/subscriptions/migrations
Ownrecord-Dry-Run: true

{ "fromPriceId": "price_01m4…", "toPriceId": "price_01m9…", "noticeDays": 30 }
```

The two prices must bill alike (currency, interval, and usage type). Every subscription on the old price gets a change scheduled for its first renewal at least `noticeDays` away (or on or after `effectiveDate`, with `effective: "date"`). Each customer is emailed a notice `noticeDays` before their change, and the renewal applies it. Narrow the subscriptions with `filter` (statuses and customers); those with another change already scheduled, or set to cancel, are skipped.

Send it as a dry run first: the answer shows how many subscriptions it would change and the monthly recurring revenue before and after, without changing anything. `GET /api/v1/subscriptions/migrations/{id}` then reports progress: scheduled, notified, applied, pending and skipped. A migration changes what customers pay, so it's a financial action: [approval policies](https://ownrecord.io/docs/concepts/approvals.md) can require an approval for agents.

## History, webhooks and metrics

Every change writes a **subscription event**: created, trial started, upgraded, downgraded, quantity changed, discount applied, paused, resumed, cancellation scheduled, reactivated, canceled and more, each with the state before and after, who made it, and how it moved monthly recurring revenue (MRR). List them with `GET /api/v1/subscriptions/{id}/events`; the console shows them as the subscription's history.

Webhooks receive `subscription.created`, `subscription.updated`, `subscription.paused`, `subscription.resumed`, `subscription.cancel_scheduled`, `subscription.canceled`, and `subscription.trial_will_end` three days before a trial ends. Renewals and collection send `subscription.renewed`, `subscription.past_due` and `subscription.recovered`.

`GET /api/v1/subscription_metrics` sums the history over a window (the last 30 days by default), per currency:

- **MRR:** the monthly amount of the licensed items of `active` and `past_due` subscriptions, before discounts and tax. A yearly price counts a twelfth, a weekly price 52/12 times, a daily price 365/12 times; metered items count as zero.
- **New**, **expansion**, **contraction**, **churned** and **reactivation** MRR: the movements in the window. Net new MRR is their sum.
- **Churn rate:** churned MRR divided by MRR at the start of the window.

The brand's home page in the console shows these figures.

## Your money, your processor

Payments are charged on your own payment processor account, with the customer's saved [payment method](https://ownrecord.io/docs/concepts/payment-methods.md). Charges that follow from a change, such as a renewal or an upgrade, happen only after the change is safely recorded, and retrying them is safe: each one is idempotent.

In [test mode](https://ownrecord.io/docs/concepts/test-and-live-mode.md), [test clocks](https://ownrecord.io/docs/concepts/test-clocks.md) let you move time forward to see trials end, renewals happen and dunning run.
