Cancel a subscription
Cancels a subscription and returns the subscription. mode decides when it
ends: at_period_end lets the period the buyer has already paid for run out, immediate ends
it now. A subscription in trial can only be cancelled immediate.
Nothing is refunded or prorated, in either mode. To return money to the buyer, refund the
payment through POST /v1/commerce/payments/{id}/refunds.
A 200 means the cancellation was accepted, not that the subscription has ended. It moves to
canceling — never straight to cancelled — and cancel_at carries when it ends: the end of
the paid period for at_period_end, the moment of the request for immediate. It reads
cancelled once the payment provider has actually ended it.
subscription.cancelled is not sent when you call this. That event is written when the
provider ends the subscription — for at_period_end, at the end of the paid period rather than
now — and it carries cancellation_reason business_cancel.
Refused with 422 subscription_not_eligible when the subscription is already ending
(already_canceling), is not one a cancel can end (not_active: only active, overdue,
paused and trial can be), is in trial and was sent at_period_end
(trial_requires_immediate), has no subscription at the payment provider
(missing_processor_subscription), or has another change still processing
(change_in_flight). An at_period_end cancel of an active or overdue subscription is
also refused inside the 60 minutes before its renewal
(too_close_to_renewal, a 422 of its own) or when no renewal date is known
(renewal_date_unknown) — the renewal it would stop may already be billing. Neither can reach
an immediate cancel or a paused subscription.
The body is optional and carries one member: reason, your own note, recorded on the attempt. Text longer than 500 characters is truncated. mode is required.
Authorizations
Bearer credential for the public API: a live COPE API key (ck_live_*; keys issued earlier as cope_sk_live_* keep working). Dashboard sign-in tokens are not accepted.
Headers
Required. At most 255 characters of valid UTF-8 with no NUL byte. The change attempt is recorded against this key for this subscription, and a retry that carries the same key and the same body does not change the subscription twice: it returns the subscription as it stands now. The exception is an attempt that failed at the payment provider or stopped responding: it is re-checked and then re-attempted. COPE also re-attempts, on its own, an attempt the payment provider did not confirm or that stopped responding, under the same re-check: usually within minutes, for up to 24 hours after it was recorded. The re-check asks whether subscription changes through the API are still enabled for the business and whether another change is still processing (change_in_flight: repeat under the same key once it settles); a price or plan change is also refused as not_active (final) once the subscription has ended and as superseded (final) when another price or plan change has been applied since it was recorded, and a pause, resume or cancel when the subscription has left the status it needs. A refusal of the first request under a key, change_in_flight included, is recorded against that key: once it settles, send the request again under a new key. The same key with a different body is refused with 409 idempotency_conflict.
255Path Parameters
id public identifier.
^ps_[A-Za-z0-9]{8,32}$"ps_A1b2C3d4E5f6"
Body
immediate ends the subscription now; at_period_end lets it run to the end of the period already paid for and ends it there. Neither refunds anything.
immediate, at_period_end Optional. Recorded on the attempt and returned as reason; longer text is truncated to 500 characters.
500Response
Successful response
Show child attributes
Show child attributes
Was this page helpful?