Cancel a subscription
Requires billing:write. Stops a subscription — at the end of the period it has been paid for, or immediately.
at_period_end is required, and that is deliberate
The two are different acts and neither is the safe default. true leaves the customer with what they paid for and the subscription stays active with cancel_at_period_end set until the period ends. false stops access today, and no money comes back on its own — that is a refund conversation.
So an omitted field is refused rather than assumed. An absent value quietly meaning “cut them off now” is the kind of default that gets discovered by a customer.
A gateway that cannot schedule a cancellation answers 501 when asked to, rather than cancelling immediately.
This is not a delete
canceled is a status. The subscription and its invoices stay — they are the record that money changed hands, and it outlives the relationship.
Autorizações
A staff session token, uk_st_…. Minted by sign-up, sign-in or the two-factor exchange.
Cabeçalhos
The organization the caller is acting on — the org_… code that appears in the panel URL. It identifies; the membership JOIN is what authorizes, so a forged code reads nothing. Absent, the session's default organization answers.
Forwarded to the payment gateway as its idempotency key, so a retry of this call does not charge twice or move a subscription twice.
This is not the guarantee Idempotency-Key carries on the API-key surface: nothing is stored here and a replay is not answered with the original response. It is passed through, and what it buys is whatever the gateway does with it — for Stripe, the original result is replayed for 24 hours.
Send a fresh key per act you mean to perform, and the same key with the same body when you are retrying one. The gateway compares the parameters, so a key reused for a different act is refused there rather than replayed.
255Parâmetros de caminho
The subscription's id here, not the gateway's id for it.
Parâmetros de consulta
Which environment to act in. A view parameter, valid only on the staff surface — a machine credential never chooses its environment, it is resolved from the key.
live, test Corpo
Resposta
The subscription, re-read after the gateway accepted. On an at-period-end cancellation the status is still active and cancel_at_period_end is true — access is unchanged, which is exactly what was asked for.
What one of your customers is paying, mirrored from the gateway.
That word decides how to read every field below. The gateway is the source of truth about money; this is a local copy kept so an entitlement can be answered without a network call, joined to the rest of your data, and read while the gateway is unreachable. provider_synced_at is when the copy was last confirmed — null means never, which is what a checkout that was started and not completed looks like.
Who is billed. A subscription always hangs off a customer, including when that customer is a team of one.
What they are subscribed to, as opposed to how it is billed — which is items. Entitlements are computed from the plan's features, so this always has exactly one answer.
In our vocabulary, never a gateway's spelling, so this does not change when you change gateway.
incomplete is created and not yet paid — no access. past_due is paid before and a payment has failed; whether that keeps access is a grace-period decision and not this field's. unknown means the adapter did not recognise what the gateway said: it is a reason to look, never a reason to charge anybody or to cut them off, and it deliberately does not read as active or as canceled.
incomplete, trialing, active, past_due, paused, canceled, unknown The period paid for. Null together with the end, never one alone: an incomplete subscription has no period, and a made-up one is a date an entitlement expires on that nothing happens at.
A cancellation that has been scheduled and has not happened. The subscription is still active until current_period_end, which is why this is its own field rather than a status.
When it actually stopped. Null while it has not.
Null when there is no trial — which is a different fact from a trial that ended, and only one of them should make a screen say a trial expired.
Which gateway holds this subscription. Exactly one: that is who is charging the card.
stripe The merchant account, as the gateway names it. Empty until a health check has asked who the keys belong to.
The gateway's own id. Empty for a checkout that was started and never completed — a row that exists here and nowhere else, and the one state in which no act on this subscription is possible.
When this copy was last re-read from the gateway, as opposed to when the row was last written. Null means never confirmed. A mirror that cannot say how stale it is would be claiming to be the source.
The lines. Present on a single subscription, absent from the list.
What a gateway can do beyond the minimum every gateway can do. Every flag defaults to false, so a provider that declares nothing is treated as the weakest one — silence is never a claim. Read it to stop offering an act that would be refused.
Every flag below is always present. The object is emitted whole or not at all: absent means this server has no adapter loaded for the gateway, and it never means "some flags were left out". A reader must therefore distinguish false from missing rather than testing for falsiness — a key that is not here is not a gateway that cannot do something, it is a question nobody asked.
Present only on the answer to an act. true means the gateway was re-read afterwards and everything above is what it said. false means the act happened and the copy above is not (or not entirely) the gateway's answer — either the re-read did not get through, or it did and part of it could not be written down. mirror_stale_reason says which. Treat it as a reason to read again, never as a sign the act failed.
Present whenever mirror_refreshed is, and null when it is true — an absent field would leave you inferring that nothing is wrong.
provider_reread_failed — the gateway was not reachable after it accepted the act. Nothing above was updated; read again.
price_not_mapped_to_provider — the gateway named a price that is not mapped onto any price in this catalogue for this environment, so plan_id was left as it was while everything else was applied. This one matters: entitlements are computed from the plan, so until you map the price (see unmapped_provider_price_id) the customer keeps the plan they were on. Prices created in the gateway's own dashboard are the usual cause.
subscription_has_extra_lines — the gateway holds more priced lines than one, so which of them names the plan is not decidable and both plan_id and items were left as they were.
provider_reread_failed, price_not_mapped_to_provider, subscription_has_extra_lines, null The gateway's own price id to map, when mirror_stale_reason is price_not_mapped_to_provider. Null otherwise.