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

# Subscriptions

> Bill customers on a repeating schedule in stablecoins

Subscriptions let you charge a customer every week, month or year in USDC or
EURC. You create a **plan** that sets the price and how often it bills, then
**subscribe** customers to it.

<Note>
  The API below is live and you can build against it today. Automatic renewal
  billing is still rolling out — subscriptions you create will not charge a
  second time on their own yet. [Get in touch](mailto:hello@creptapay.com) if
  you want to be on the early list.
</Note>

## Why stablecoin subscriptions work differently

Card subscriptions are **pull** payments. You store a card and charge it
whenever a period ends, without the customer doing anything.

Stablecoins are **push** payments. Only the holder of a wallet can move funds
out of it, so nothing can silently charge your customer. CreptaPay handles this
in two ways:

<CardGroup cols={2}>
  <Card title="Recurring invoices" icon="link">
    Each cycle we create a payment and send your customer a pay link. They
    settle it from any wallet or exchange, on any supported network.
  </Card>

  <Card title="On-chain auto-debit" icon="bolt">
    Your customer approves a spending cap once, and the contract pulls each
    cycle. True auto-renew, but self-custody EVM wallets only.
  </Card>
</CardGroup>

Set which one a plan uses with `collection_mode`. Recurring invoices work for
every customer, so that is the default.

## Plans

A plan is the template: the price, the cadence, and how long a late payer has
to catch up.

```bash theme={null}
curl -X POST https://api.creptapay.com/v1/plans \
  -H "x-api-key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pro monthly",
    "amount": 49,
    "currency": "USD",
    "interval": "month",
    "interval_count": 1,
    "trial_days": 14,
    "grace_days": 7
  }'
```

`interval` and `interval_count` combine, so `3` and `month` bills quarterly.

Plans are priced in fiat. Your customer pays the stablecoin equivalent at
checkout, and you are credited in stablecoins.

### Grace periods

`grace_days` is how long after a period ends a subscriber can still pay before
their subscription expires. You choose it per plan — a gym might allow a day,
an annual B2B contract a fortnight.

The grace deadline is **frozen onto the subscription** when each period starts.
Shortening a plan's grace period later never moves a deadline a subscriber has
already been given.

## Subscribing a customer

```bash theme={null}
curl -X POST https://api.creptapay.com/v1/subscriptions \
  -H "x-api-key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "plan": "6712f0a1b9c4e2d3f4a5b6c7",
    "customer": {
      "first_name": "Chidera",
      "last_name": "Okonkwo",
      "email": "chidera@example.com"
    }
  }'
```

Pass `customer_id` instead to subscribe someone you already have on file.

## Changing a plan's price

Plans are fully editable, price and cadence included. **Existing subscribers
are never affected.**

When a customer subscribes, the plan's terms are copied onto their
subscription. Billing reads that copy, never the plan. So a plan is a template
for new sign-ups rather than a live price that reaches backwards into people
who already signed up.

```json theme={null}
{
  "reference": "SUB-K3F9A2QP",
  "terms": {
    "amount": 49,
    "currency": "USD",
    "interval": "month",
    "interval_count": 1,
    "grace_days": 7,
    "captured_at": "2026-01-15T09:22:11Z"
  },
  "on_legacy_terms": true
}
```

`on_legacy_terms` tells you the plan has since been repriced and this
subscriber has not moved. To move them onto current pricing, call
`apply-plan-terms` — it takes effect from the next period and leaves the
period they have already paid for alone.

```bash theme={null}
curl -X POST https://api.creptapay.com/v1/subscriptions/{id}/apply-plan-terms \
  -H "x-api-key: sk_live_..."
```

Nothing moves a subscriber's price unless you ask for it.

## Subscription statuses

| Status     | What it means                                    |
| ---------- | ------------------------------------------------ |
| `trialing` | In a free trial, or waiting on the first payment |
| `active`   | Paid and inside the current period               |
| `past_due` | The period ended unpaid; inside the grace window |
| `paused`   | Billing stopped until you resume it              |
| `canceled` | Ended by you or the customer                     |
| `expired`  | Grace ran out without payment                    |

### Canceling

Canceling defaults to the end of the paid-for period. The subscription stays
`active` with `cancel_at_period_end: true` until then, so a customer keeps what
they paid for.

```bash theme={null}
curl -X POST https://api.creptapay.com/v1/subscriptions/{id}/cancel \
  -H "x-api-key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "at_period_end": true }'
```

Pass `at_period_end: false` to end it immediately.

<Tip>
  When you list subscriptions for a dashboard, treat `cancel_at_period_end` as
  its own state. Those subscriptions are still active and still paying — showing
  them as canceled hides revenue you still have.
</Tip>

## Billing dates

Periods are measured from a fixed anchor: the start of the first paid period.
Period *N* ends at anchor plus *N* intervals.

This matters at month ends. A subscription anchored on 31 January bills
28 February, then **31 March**, then 30 April, then **31 May** — the anchor day
comes back whenever the month is long enough. Chaining each period off the
previous one would clamp to the 28th and stay there, quietly shortening every
future cycle.
