Open the Stripe Customer Portal
const url = 'https://api.sloose.com/orgs/org_9f3c/billing/portal';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"returnUrl":"example"}'};
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/portal \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "returnUrl": "example" }'Where a customer changes their card, downloads invoices, or cancels. Everything the portal does reaches us back through the webhook.
Session only: billing is a person’s to manage, never an org’s API token’s (D5).
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The org id the session was issued for. A token for one org can never read another.
Example
org_9f3cThe org id the session was issued for. A token for one org can never read another.
Request Body
Section titled “Request Body”object
Where Stripe sends the browser afterwards.
Examplegenerated
{ "returnUrl": "example"}Responses
Section titled “Responses”Send the browser here.
object
Examplegenerated
{ "url": "example"}No bearer, or one that is expired, revoked or no longer resolves to a member.
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 org, it is an API token (SESSION_REQUIRED), or it is a staff member’s view of the org (IMPERSONATION_REFUSED; a read-only view is refused before this, IMPERSONATION_READ_ONLY): billing spends and changes the org’s money, and a view would do it in the member’s name.
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"}Stripe refused the request (PAYMENT_PROVIDER_REFUSED) — nothing was charged, though a step taken before the refusal stands: the org’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 (STRIPE_NOT_CONFIGURED). An org with no Stripe customer is not refused: the portal makes one.
object
Examplegenerated
{ "error": "example"}