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 /subscriptions/{id}/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.
cancelImmediatelyThe older cancelImmediately boolean is deprecated but still accepted, and existing integrations keep working unchanged: true means immediately and false means end_of_current_cycle. When both are sent, cancelAt wins — except for the one contradictory combination, cancelImmediately: true with a cancelAt other than immediately, which returns a 400.
Immediate cancellation
To cancel a subscription right away:
{
"cancelAt": "immediately"
}
Odus immediately:
- Voids all open invoices belonging to the subscription. No further charges are attempted.
- Sets the subscription
statustocancelled.
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.
A subscription with a pending cancellation cannot have its plan or next billing date updated; the request returns a 400. Resume it first, apply the update, then cancel again.
The cancellation still fires at the end of that cycle. A failed renewal that starts retries 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.
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 the subscription first and then cancel it again. Cancelling immediately is always allowed, since it is terminal either way.
Cancelling from the Dashboard
- Open the subscription detail page.
- Click Cancel Subscription.
- In the dialog, use the Cancel immediately toggle to choose between immediate and end-of-period cancellation.
- 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 /subscriptions/{id}/resume request — no request body is required:
POST /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
- Open the subscription detail page.
- Click Resume Subscription.
- 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.
Related Guides
- Subscription Lifecycle — how subscription statuses, billing cycles, and invoices work together
- Updating Plans — how to change a subscription's pricing plan