# Subscription metrics from Stripe, Paddle and Lemon Squeezy

> Connect Stripe, Paddle or Lemon Squeezy with a read-only API key to see MRR, churn, trials and a churn cohort grid next to your traffic.

The **Subscriptions** page shows recurring revenue for a site: MRR, ARR,
active subscriptions, churn, trials and a churn cohort grid. The numbers
come from your own payment provider, read with a read-only API key. It is
available on every plan.

## Connect

Open the site's **Subscriptions** page (also linked from **Site settings →
Integrations**) and pick the provider the site bills through. You can
connect more than one, and their numbers are added together. Connecting,
syncing and disconnecting need the `sites.manage` permission.

### Stripe

1. In Stripe, open **Developers** > **API keys** and click **Create
   restricted key**.
2. Give it **Read** access to **Subscriptions** and nothing else.
3. Paste the key (it starts with `rk_live_`, or `rk_test_` in test mode)
   and click **Connect**.

A full secret key (`sk_live_`) is refused. A restricted key can only read
what you allow, so it is the safe choice.

### Paddle

1. In Paddle, open **Developer tools** > **Authentication** and create an
   API key with the **Read** permission for **Subscriptions**.
2. Paste the key and click **Connect**. A sandbox key is detected and uses
   Paddle's sandbox.

Paddle keys expire (after 90 days by default, a year at most). When a key
expires the page shows **Sync failed** and asks for a new one.

### Lemon Squeezy

1. In Lemon Squeezy, open **Settings** > **API** and create an API key.
2. Paste the key and click **Connect**. If the key can see more than one
   store, enter the **Store ID** of the one to connect. The error message
   lists the stores and their IDs.

### What is stored

For each subscription we store the provider's subscription ID, its status,
its start, trial, cancellation and end dates, and its monthly amount and
currency. We do not store customer names, emails, IDs, addresses or
countries, and nothing links a subscription to a visitor.

Your API key is stored encrypted and is only used to read subscriptions.
It is never shown again or returned by the API. You can revoke it at the
provider at any time. Disconnecting deletes the key and every subscription
row read with it.

### Syncing

Subscriptions are read again every 6 hours, and **Sync now** reads them
straight away. Each sync reads all subscriptions, so new
subscriptions, cancellations and price changes at the provider show up
after the next sync. A badge marks a connection that uses a test or sandbox key.

If a sync fails, the connection shows **Sync failed** with the reason. The
last numbers stay in place until a sync succeeds or you paste a new key.

## The numbers

- **MRR:** the monthly value of every subscription that has paid and has
  not ended. Yearly, weekly and multi-month prices are converted to a
  month, quantities are multiplied in, and recurring discounts are taken
  off (Stripe only, while Paddle and Lemon Squeezy use the list price).
  **ARR** is MRR times 12.
- **Active subscriptions:** subscriptions that have paid at least once and
  have not ended. A subscription that is past due still counts. A paused
  one does not.
- **Average per subscription:** MRR divided by active subscriptions.
- **Churn, last 30 days:** subscriptions that ended in the last 30 days,
  as a share of those active 30 days ago. **MRR churn** is the same with
  their MRR.
- **Active trials** and **Trials that paid, last 90 days:** of the trials
  that ended in the last 90 days, the share that went on to pay.
- **By month:** MRR and active subscriptions at the end of each month, with
  the subscriptions that first paid and that ended in it. The churn rate
  is the month's ended subscriptions as a share of those active when the
  month began.

Amounts in other currencies are converted to the site's currency at the
latest European Central Bank rate. Months follow the site's time zone, and
the current month is measured up to now.

Past months use each subscription's current price. An upgrade or downgrade
changes the amount for every month of that subscription, so expansion and
contraction are not shown separately. Metered (usage-based) prices count as
zero.

## Churn cohorts

The grid groups subscriptions by the month of their first payment. Each
row is one month's cohort, **Size** is how many subscriptions it has, and
each cell is a month since: **M0** is the cohort's first month, **M1** the
next, and so on.

- **Churn** (the default) shows the share of the cohort that had ended by
  the end of that month. Read across a row to see how fast a cohort
  leaves, and down a column to compare cohorts at the same age.
- **Retention** shows the share still running.
- **MRR** measures the cohort's monthly revenue instead of counting
  subscriptions, so losing a large plan weighs more than a small one.

Trials that never paid are not in any cohort. Choose 6, 12 or 24 months
at the top of the page.

## API and MCP

Everything on the page is available over the [API](/docs/api) and MCP:

| Endpoint | MCP tool | What it does |
|---|---|---|
| `GET /sites/{site}/subscriptions` | `subscriptions_report` | Totals and the monthly series (`months`: 6, 12 or 24) |
| `GET /sites/{site}/subscriptions/cohorts` | `subscriptions_cohorts` | The cohort grid (`months`, `metric`, `view`) |
| `POST /sites/{site}/subscriptions/connections` | `subscriptions_connect` | Connect with `provider`, `api_key` and, for Lemon Squeezy, `store_id` |
| `POST /sites/{site}/subscriptions/sync` | `subscriptions_sync` | Read subscriptions now (`provider`) |
| `DELETE /sites/{site}/subscriptions/connections/{provider}` | `subscriptions_disconnect` | Disconnect and delete the key and data |

Money is in minor units (cents) of the site's currency.
