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

# Changing subscriptions

> Seats, upgrades, downgrades, plan changes and retiring a plan

Customers grow, shrink and switch plans. Bouclay works out what the change costs for the rest of the period, so you don't have to.

## Proration, in plain words

**Proration** means charging or crediting only for the part of the period that is left. A customer on ₦30,000 a month who upgrades to ₦60,000 halfway through pays the ₦15,000 difference for the half month that is left, not a whole new month.

Bouclay's default is the one most customers expect:

* **More** (more seats, a dearer plan): applied now, and the difference for the rest of the period is billed now.
* **Less** (fewer seats, a cheaper plan, removing an add-on): waits until the next renewal, so the customer keeps what they already paid for.

You can override either default, as below.

## Change seats or a price

Change one item's quantity or price with `PATCH /subscriptions/{id}/items/{item}`:

```bash theme={null}
curl -X PATCH https://bouclay.com/api/v1/subscriptions/sub_…/items/si_… \
  -H "Authorization: Bearer $BOUCLAY_KEY" \
  -H "Idempotency-Key: seats-sub-123-to-12" \
  -H "Content-Type: application/json" \
  -d '{"quantity": 12}'
```

`prorationBehavior` overrides the default:

| `prorationBehavior` | What happens |
| - | - |
| `always` | Apply now and bill or credit the rest of the period. A decrease credits the unused time with a credit note: to the customer's balance when the period was paid, or off the open invoice when it wasn't. Never back to the card. |
| `none` | Apply now and bill nothing for this period. The next renewal bills the new amount. Good for support and goodwill fixes. |
| `next_cycle` | Change nothing now; apply at the next renewal. |

Send `"remove": true` to take an item off.

**Preview first.** `POST /subscriptions/{id}/items/{item}/preview` takes the same body and returns what the change would bill, without making it. Show it to the customer before they confirm. It only needs `subscriptions:read`.

## Move to another plan

To switch the whole subscription to another plan, use `POST /subscriptions/{id}/plan-change`:

```bash theme={null}
curl https://bouclay.com/api/v1/subscriptions/sub_…/plan-change \
  -H "Authorization: Bearer $BOUCLAY_KEY" \
  -H "Idempotency-Key: plan-change-sub-123-team" \
  -H "Content-Type: application/json" \
  -d '{"planId": "plan_…", "billingInterval": "year"}'
```

* **Timing.** A change that costs the same or more is applied `now`; one that costs less waits for the `next_renewal`. Override with `timing`. Moving from monthly to yearly applies now and credits the unused part of the month.
* **Charges are matched up.** A usage charge carries on onto the new plan's charge that counts the same meter; a fixed charge carries on onto the one with the same code. Charges with no match end, and the new plan's other charges start.
* **One pending change.** A plan change booked for the next renewal replaces any plan change already pending.

`POST /subscriptions/{id}/plan-change/preview` shows which charges carry on, end and start, and the invoice it would raise now.

## Price increases for existing subscribers

Prices never change once used. To charge more, create a new price, then move subscribers onto it with an item change or a plan change, usually with `timing: next_renewal` so nobody pays the new price mid-period.

## Add or end a charge for current subscribers

A charge added to a plan only reaches new subscribers. To give it to everyone already on the plan, call `POST /charges/{id}/add-to-subscribers`: each live subscriber gets it at their next renewal (at once for trialing or paused ones, since nothing is billed). `POST /charges/{id}/end-for-subscribers` ends a charge the same way. Running either again skips subscribers already done.

## Retire a plan

> [!NOTE]
>
> Early access.

To stop offering a plan and move everyone off it on a date, call `POST /plans/{id}/retirement` with `retiresAt` and, ideally, `successorPlanId`.

* From now on, nobody new can start or switch onto the plan.
* Each subscriber moves at their first renewal on or after `retiresAt`, so nobody loses time they paid for: to a plan change or cancellation they already booked, else to the successor plan's price in the same currency and interval.
* With no successor, the subscription pauses (`pauseReason: plan_retired`) and bills nothing until you move it to another plan and resume it.

`DELETE /plans/{id}/retirement` takes it back.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.