Separate the schedule from the subscription
A subscription schedule is a controller for changes over time, not a synonym for the subscription it manages. This distinction matters when a customer says “cancel the scheduled change.” Releasing the schedule stops scheduling its phases while leaving an existing subscription in place; canceling the schedule also cancels its active associated subscription immediately.[1][2][3] A support action intended to withdraw a future change should therefore not be translated automatically into a schedule cancellation.
There are also two different clocks. Calling the release or cancel endpoint is an immediate operation. Setting end_behavior describes what happens when the schedule reaches its end, after its final phase. The object reference defines release as the default end behavior: keep the underlying subscription running. The alternative, cancel, ends the underlying subscription when the schedule ends.[1][4] Setting end_behavior=cancel is not a substitute for an immediate cancellation call.
Choose the operation from the intended outcome
- Keep the current subscription but abandon all remaining scheduled transitions: choose POST /v1/subscription_schedules/{id}/release. This stops phase scheduling now, rather than waiting until the last phase finishes.[2]
- Stop the schedule and its active subscription now: choose POST /v1/subscription_schedules/{id}/cancel. The immediate cancellation applies even if the stored end_behavior says release; end behavior is a future completion policy, not a protection against the cancellation endpoint.[3][4]
- Let every phase run, then continue the subscription: use end_behavior=release. The subscription persists in its current state when the schedule ends; this is not a promise to restore its configuration from before the schedule existed.[4]
- Let every phase run, then end the subscription: use end_behavior=cancel. Check the actual final phase boundary rather than assuming it equals the next billing date.[1][4]
For example, withdrawing a planned future change while retaining today's service is a release scenario. A finite service contract that must run through its configured phases before stopping is an end_behavior=cancel scenario. A request to terminate today's active service is a cancel-endpoint scenario. These are illustrative decision cases, not results of live API tests.
What release changes, and what it does not prove
The release endpoint accepts schedules whose status is not_started or active. If the schedule has an associated subscription, release removes the schedule's subscription property and places that subscription ID in released_subscription. The returned schedule has status released and a released_at timestamp.[2] A null subscription field on the released schedule is consequently not evidence that the customer's subscription was deleted. Follow the released_subscription identifier and inspect the subscription itself.
The endpoint also exposes preserve_cancel_date, described as keeping any cancellation on the subscription that the schedule has set.[2] Treat this as an explicit business decision: should an already scheduled cancellation remain after detaching the schedule? Specify and verify the desired behavior against your integration's API version rather than assuming that “release” guarantees indefinite continuation. The retrieved parameter description does not state a default, so this article does not invent one.
For a schedule that has not started and has no existing subscription, do not require a released_subscription identifier as proof of success. The release description promises to leave any existing subscription in place and makes the identifier transfer conditional on an association.[2] Similarly, stopping future phases is not a documented refund operation or a reversal of earlier phase changes.
Cancellation has a billing decision attached
The cancel endpoint also permits only not_started or active schedules. For an active schedule, invoice_now defaults to true and controls generation of a final invoice containing un-invoiced metered usage and new or pending proration invoice items. The separate prorate parameter defaults to true and determines whether cancellation is prorated.[3] These are cancellation parameters, not the phase-transition proration settings described elsewhere in the schedule guide.[1][3]
Before approving an immediate cancellation, record whether final invoicing and cancellation proration are intended. Do not describe invoice_now=false as forgiveness of every balance, or cancellation as a refund guarantee: those conclusions are not established by this endpoint reference. Keep the lifecycle decision, the billing review, and your own access-control policy separate.
Troubleshoot state rather than button labels
- If the subscription remains active after release, first check whether that was the intended outcome. Keeping the existing subscription is the documented behavior, not a failure.[2]
- If end_behavior=cancel is configured but no cancellation date appears yet, inspect the phase position. Stripe's guide says the subscription cancellation date is not set until the subscription enters the final phase.[1]
- If a later operation targets an old schedule, retrieve its status. The object has distinct not_started, active, completed, released, and canceled states; do not collapse them into a single “subscription ended” flag.[4] Stripe recommends discarding released schedule IDs from the active management path, then changing the subscription directly or creating a new schedule.[1]
- If a direct subscription edit is later overwritten, check whether the schedule still controls it. Stripe warns that not all direct changes propagate to the schedule and later phase transitions can overwrite them. Prefer schedule-level changes while a schedule is attached.[1]
- After an immediate release, reconcile released_subscription and released_at; after immediate cancellation, reconcile status=canceled and canceled_at. These are endpoint return semantics, not evidence that an invoice was paid or your application's entitlements were updated.[2][3]
Implementation boundary and evidence
A useful acceptance checklist is to retain the business intent, the pre-operation schedule and subscription identifiers, the intended final date, and the observed post-operation objects. Test future-start, active, final-phase, and already-terminal cases in your own test environment before enabling a destructive support action. This is a recommended validation procedure; no authenticated Stripe calls or payment experiments were performed for this article.
The official sources below were retrieved on 2026-09-22 and did not provide a publication or last-updated date in the retrieved text. They document API behavior, not country-by-country commercial availability. No geography-specific exception to these lifecycle rules was identified in these sources; that does not establish Stripe account eligibility, payment-method availability, local cancellation obligations, or tax treatment in every region. Verify those separately and check your pinned API version before implementation.
Sources and dates
Official documentation; the site may return localized text. Publication and update dates are not stated; retrieved and checked on 2026-09-22. Retrieval is not publication. This is documentation research, not a live-account test, PayIn feature claim, or legal, tax or financial advice.
- [1] Subscription schedules · Checked 2026-09-22; source date not stated.
- [2] Release a schedule · Checked 2026-09-22; source date not stated.
- [3] Cancel a schedule · Checked 2026-09-22; source date not stated.
- [4] The Subscription Schedule object · Checked 2026-09-22; source date not stated.