# Cancelling and Resuming

ODUS gives you three ways to cancel a subscription: immediately, at the end of the current billing period, or at the end of the **next** one — letting the upcoming renewal charge go through first. Either scheduled option can be reversed by resuming the subscription before it takes effect.

## Prerequisites

You need the ID of an `active` subscription. Only active subscriptions can be cancelled or resumed.

## Cancelling a Subscription

Send a [`POST /v2/subscriptions/{id}/cancel`](https://docs.odus.com/docs/api/core/v2/subscription-controller-cancel) request and pick the boundary with `cancelAt`:

| `cancelAt`             | Takes effect          | Further charges                  |
| ---------------------- | --------------------- | -------------------------------- |
| `immediately`          | Right away            | None; open invoices are voided   |
| `end_of_current_cycle` | At `currentPeriodEnd` | None                             |
| `end_of_next_cycle`    | One renewal later     | One more renewal charge is taken |

`cancelAt` defaults to `end_of_current_cycle`.

Moving from v1: send `cancelAt`, not `cancelImmediately`

`cancelImmediately` is not part of v2. Where v1 sent `{ "cancelImmediately": true }`, send `{ "cancelAt": "immediately" }`.

If you remove `cancelImmediately` without adding `cancelAt`, the request gets the default, `end_of_current_cycle`. It succeeds without an error, and the subscription keeps billing until the end of the current cycle.

### Immediate cancellation

To cancel a subscription right away:

```
{

  "cancelAt": "immediately"

}
```

ODUS immediately:

1. **Voids all open invoices** belonging to the subscription. No further charges are attempted.
2. Sets the subscription `status` to `cancelled`.

The customer loses access as soon as the request completes. This action cannot be undone. To re-subscribe the customer, you must create a new subscription.

### End-of-period cancellation

To let the customer keep access until their current billing period ends:

```
{

  "cancelAt": "end_of_current_cycle"

}
```

ODUS sets `cancelAtPeriodEnd: true` on the subscription and records the booking in `cancelAtCycle`. The subscription `status` remains `active`, and the customer continues to have access until `currentPeriodEnd`. When that date arrives, ODUS cancels the subscription automatically without collecting any additional charge.

The response shows the pending cancellation state:

```
{

  "id": "sub_2Q9fNQAs77Fhue9itgVFbUzq8NV",

  "status": "active",

  "cancelAtPeriodEnd": true,

  "currentCycle": 4,

  "cancelAtCycle": 4,

  "currentPeriodEnd": "2024-03-09T00:00:00.000Z"

}
```

### Cancellation after one more renewal

Some cancellation policies have a notice window: a request made close to the renewal date should let that renewal complete and take effect afterwards. Send:

```
{

  "cancelAt": "end_of_next_cycle"

}
```

ODUS books the cancellation against the **next** cycle. Because the current cycle is unaffected, `cancelAtPeriodEnd` stays `false` and the upcoming renewal is charged exactly as it would have been:

```
{

  "id": "sub_2Q9fNQAs77Fhue9itgVFbUzq8NV",

  "status": "active",

  "cancelAtPeriodEnd": false,

  "currentCycle": 4,

  "cancelAtCycle": 5,

  "currentPeriodEnd": "2024-03-09T00:00:00.000Z"

}
```

Once that renewal is billed and the subscription moves into cycle 5, `cancelAtPeriodEnd` flips to `true` on its own and the subscription cancels at the new `currentPeriodEnd`.

You do not need to run a timer against the renewal date yourself. The booking is stored as a **cycle number**, not a timestamp, so it stays correct even when the period boundary moves — for example when a failed renewal delays it through retries.

Plan updates while a cancellation is booked

A subscription with a pending cancellation cannot have its plan or next billing date updated; the request returns a `400`. [Resume](#resuming-a-subscription) it first, apply the update, then cancel again.

If the intervening charge fails

The cancellation still fires at the end of that cycle. A failed renewal that starts [retries](https://docs.odus.com/docs/guides/subscriptions/subscription-lifecycle.md) advances the subscription into the booked cycle just as a successful one does, so the booking becomes due at that cycle's `currentPeriodEnd` either way. If the retries are exhausted, the subscription is cancelled at that point instead — sooner than booked, never later.

If billing stops for another reason before the renewal is even attempted, the booking is brought forward onto the current period, so the cancellation still happens rather than waiting for a renewal that will never come. For the same reason, `end_of_next_cycle` is rejected with a `400` on a subscription whose automatic billing has already stopped — use `end_of_current_cycle` there.

One booking at a time

A subscription that is already scheduled for cancellation — at either boundary — cannot be scheduled again; the request returns a `400`. To move a booking from one boundary to the other, [resume](#resuming-a-subscription) the subscription first and then cancel it again. Cancelling **immediately** is always allowed, since it is terminal either way.

### Cancelling from the Dashboard

1. Open the subscription detail page.
2. Click **Cancel Subscription**.
3. In the dialog, use the **Cancel immediately** toggle to choose between immediate and end-of-period cancellation.
4. Click **Cancel** to confirm.

The Dashboard covers the immediate and end-of-current-period options; `end_of_next_cycle` is available through the API.

## Resuming a Subscription

If you have scheduled a subscription for cancellation — at either boundary — and it has not yet taken effect, you can reverse the decision.

Send a [`POST /v2/subscriptions/{id}/resume`](https://docs.odus.com/docs/api/core/v2/subscription-controller-resume) request — no request body is required:

```
POST /v2/subscriptions/sub_2Q9fNQAs77Fhue9itgVFbUzq8NV/resume
```

ODUS clears `cancelAtCycle` and sets `cancelAtPeriodEnd` back to `false`. The subscription returns to its normal billing state and will renew at `currentPeriodEnd` as usual.

### Resuming from the Dashboard

1. Open the subscription detail page.
2. Click **Resume Subscription**.
3. Confirm in the dialog.

### Edge case: already cancelled subscriptions

Resume only works when a subscription is `active` with a pending cancellation — that is, with a non-null `cancelAtCycle`. A subscription whose `status` is already `cancelled` cannot be resumed. You must create a new subscription for the customer instead.

## Reactivating a Subscription Whose Billing Stopped

A subscription can stay `active` after its billing has stopped: `autoBillingEnabled` is `false`, and no renewal will be attempted. Once the customer can be charged again, restart billing with a [`POST /v2/subscriptions/{id}/reactivate`](https://docs.odus.com/docs/api/core/v2/subscription-controller-reactivate) request. No request body is required, and your key needs `subscription:force_bill`.

```
POST /v2/subscriptions/sub_2Q9fNQAs77Fhue9itgVFbUzq8NV/reactivate
```

ODUS then:

1. Starts a new billing period now. `currentPeriodEnd` is set to the time of your request, and `upcomingInvoice` covers one billing interval from then.
2. Sets `autoBillingEnabled` to `true`.
3. Takes the renewal charge within a few minutes, like any other renewal. If the charge fails, the usual retry rules apply.

Missed periods are not charged

The customer is charged once, for the new period. Periods that went unpaid while billing was stopped are not charged, and the renewal date moves to the day you reactivate.

Reactivating takes a charge. Check that the customer still wants the subscription and has a payment method that can be charged before you send the request.

If a customer bought several subscriptions together and [payment bundling](https://docs.odus.com/docs/guides/subscriptions/payment-bundling.md) is enabled, reactivate them one right after another so they can be charged in a single payment.

The request is refused with `400` and `type` `invalid_state_error` when the subscription:

* is not `active`
* is still billing (`autoBillingEnabled` is `true`)
* is scheduled for cancellation. [Resume it](#resuming-a-subscription) first.
* has an `open` invoice that can still be paid, for example while a payment is being retried. Wait for that invoice to be paid or voided.
* has a paid billing period that has not ended, or had its latest renewal paid by a retry. The customer has already paid, and billing resumes on its own.
* is still processing the outcome of its latest renewal. Try again in a few minutes.
* is in a billing period that has not started yet.

Reactivation is available in v2 only.

## Related Guides

* [Subscription Lifecycle](https://docs.odus.com/docs/guides/subscriptions/subscription-lifecycle.md) — how subscription statuses, billing cycles, and invoices work together
* [Updating Plans](https://docs.odus.com/docs/guides/subscriptions/updating-plans.md) — how to change a subscription's pricing plan
