Cancel a subscription
Stops a subscription renewing at the end of the current period, so the customer keeps the access they have already paid for.
Parameters
| Parameter | Description |
|---|---|
| subscription_idstring · pathrequired | Id of the subscription, which starts sub_. |
Returns
The subscription with renewal_state: canceling and cancel_at_period_end: true. status stays active until the period is over. Gate access on serves_customer, which turns false at current_period_end. Once the period is over and no charge is still in progress, the subscription becomes canceled with cancellation_reason: “period_end” and canceled_at set to the period end, and subscription.canceled fires. There is no immediate-cancel option.
If the period has already ended and its renewal was never charged, the call ends the subscription at once: status: canceled, cancellation_reason: “period_end”, canceled_at at the old period end, and nothing is charged for the unpaid period. While a renewal payment is still settling, the call returns 409 operation_pending with reason: “renewal_processing”.
The one exception is a price with refund_on_cancel set. When the cancellation issues that refund, the subscription is canceled at once and subscription.canceled fires. See Refunding on cancellation.
Until the boundary passes the customer can change their mind: reactivate clears the pending cancellation with no new checkout. Cancelling an already-cancelling or cancelled subscription returns it unchanged, so a retried call converges on one state. The exception is an already-cancelling subscription while a plan change or payment-method update is in flight for the customer, which returns 409 operation_pending.
Test it
Cancel in test mode, then advance the test clock past current_period_end: no renewal is charged, no further invoice appears, serves_customer reads false, and the subscription becomes canceled with canceled_at at the period end.
Errors
| Status | Cause |
|---|---|
| 400 | The request was refused (type: invalid_request_error): a required parameter is missing (parameter_missing), one failed validation (parameter_invalid) or is not one the operation takes (parameter_unknown), and param names it. |
| 401 | No credential, or one that does not authenticate. |
| 402 | The account is suspended (tenant_suspended), or the payment provider refused a charge or refund the call made (type: payment_error, code: payment_refused). |
| 403 | Authenticated, but not allowed: missing scope (insufficient_scope), a key of the wrong mode (mode_mismatch), or a refused origin. Needs the subscriptions:cancel scope. |
| 404 | No such object in this account and mode. |
| 409 | Conflicts with the object's current state (state_conflict, or a more specific code), or an operation still in flight (operation_pending). |
| 413 | The request body is larger than the API accepts. |
| 429 | Rate limited. Retry-After says when to try again. |
| 500 | Something failed on BillKit's side (type: api_error). Retry with the same Idempotency-Key. |
| 502 | The payment provider failed or did not answer. |
| 503 | Temporarily unable to serve. reason says whether the request was attempted. |
Other subscriptions operations
- List subscriptions GET /v1/subscriptions
- Retrieve a subscription GET /v1/subscriptions/{subscription_id}
- Pause subscription POST /v1/subscriptions/{subscription_id}/pause
- Preview update subscription POST /v1/subscriptions/{subscription_id}/preview_update
- Reactivate subscription POST /v1/subscriptions/{subscription_id}/reactivate
- Reauthorize payment method POST /v1/subscriptions/{subscription_id}/reauthorize_payment_method
- Resume subscription POST /v1/subscriptions/{subscription_id}/resume
- Change a subscription's plan POST /v1/subscriptions/{subscription_id}/update
BillKit