Move a suspended organisation to Free
const url = 'https://api.sloose.com/orgs/org_9f3c/billing/plan/free-from-suspended';const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.sloose.com/orgs/org_9f3c/billing/plan/free-from-suspended \ --header 'Authorization: Bearer <token>'A suspended organisation (a payment owed past its grace period) may leave for Free (#2380). Its Stripe subscription is cancelled at once, and Stripe’s webhook for an ended subscription does the rest: the organisation is Free, the unpaid notices end, and the plan’s included credits end. What is owed stays owed: the invoice that failed is not voided or forgiven. It stays open at Stripe and can still be paid from its own page, and paying it does not bring the plan back. While it stands, the organisation cannot start a trial (OWES_INVOICE on POST …/billing/trial, with the invoice’s page) until that invoice is paid or voided; buying a plan stays allowed. Asked twice before Stripe’s webhook lands, the second is 409 MOVE_UNDER_WAY and writes nothing. Only a card-billed subscription: one billed by invoice is changed by Sloose’s team. Administrators, through their own session; never a staff member’s view.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The organisation id the session was issued for. A token for one organisation can never read another.
Example
org_9f3cThe organisation id the session was issued for. A token for one organisation can never read another.
Responses
Section titled “Responses”The subscription is ended at Stripe; the organisation reaches Free when Stripe’s webhook says so, usually within a minute.
object
cancelled: Stripe cancelled the subscription for this request. ended already: Stripe had ended it, and its webhook is the one that moves the organisation.
Example
{ "stripe": "cancelled"}No bearer, or one that no longer resolves: a session that is unknown or expired (code: AUTH_REQUIRED), or an API token that was revoked or expired (TOKEN_REVOKED, TOKEN_EXPIRED), whose organisation is gone (ORG_NOT_FOUND) or whose member or user row is (MEMBERSHIP_GONE).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}The bearer’s role is too low, it was issued for a different organisation, it is an API token (SESSION_REQUIRED), or it is a staff member’s view (IMPERSONATION_REFUSED). Like every route behind a session: a session signed in but in no organisation is refused code: NO_ORG, a banned person code: BANNED, and a closed organisation code: ORG_CLOSED.
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}PLAN_SETTLING: what Stripe bills and what Sloose has recorded differ (a payment recovered, or a change made in Stripe’s dashboard, whose webhook has not landed), so nothing is cancelled until they agree; try again shortly. MOVE_UNDER_WAY: the move was asked for in the last ten minutes and Stripe’s webhook has not landed yet; nothing was done again. NOT_SUSPENDED: the organisation is not suspended. NOT_SUBSCRIBED: it holds no Stripe subscription. INVOICE_BILLED: a plan billed by invoice is changed by Sloose’s team. CHANGE_IN_PROGRESS: another change to the organisation’s plan, or a webhook about it, is being made at this moment. CHANGE_UNCONFIRMED: Stripe did not answer, so the subscription may have been ended; the plan as it stands arrives within a minute.
object
Example
{ "code": "NOT_SUSPENDED"}Stripe refused the request (PAYMENT_PROVIDER_REFUSED) — nothing was charged, though a step taken before the refusal stands: the organisation’s first Stripe customer, or an existing customer’s billing email brought up to date — or was unavailable (PAYMENT_PROVIDER_UNAVAILABLE: unreachable, failing or rate-limiting), which may or may not have gone through — check before retrying. Stripe’s own words are logged, not returned.
object
Example
{ "code": "PAYMENT_PROVIDER_REFUSED"}Stripe is not configured. Or the restore switch is on (code: MAINTENANCE): every route but /health and /robots.txt is refused before anything is read, with Retry-After (the operator’s ADMIN_TOKEN alone is let through to POST /staff/people/{id}/delete, and to nothing else).
Headers
Section titled “Headers”Seconds until asking again is worth it (300 while the switch is on).