Create Portal Session
const url = 'https://example.com/api/billing/portal-session?organization_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';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://example.com/api/billing/portal-session?organization_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0' \ --header 'Authorization: Bearer <token>'Mint a Stripe Billing Portal session (TODO-089/COMM-007).
The portal itself is where invoices, receipts, payment-method updates
and self-service cancellation actually live — Stripe hosts all of that,
this route’s only job is minting the one-time, short-lived URL into it.
Deliberately NOT _find_or_create_customer: unlike the setup-intent
route (whose whole point is establishing a customer to attach a first
card to), a billing owner with no gateway customer yet has never
checked out and has nothing for the portal to show — 404, not a portal
session for an empty account.
return_url is server-constructed from settings.app_base_url, never
echoed from the request, same discipline as the Google OAuth redirect
(see that setting’s own docstring) — the portal must never be steerable
to an attacker-supplied return target.
Authorizations
Section titled “ Authorizations ”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “ Query Parameters ”Responses
Section titled “ Responses ”Successful Response
POST /api/billing/portal-session — TODO-089/COMM-007.
A single-use, short-lived URL to Stripe’s own hosted Customer Portal (invoices, receipts, payment-method update, cancellation) — the portal_url itself is the whole response; the console just redirects the browser to it. Never store or reuse this URL past the redirect.
object
Example generated
{ "portal_url": "example"}Validation Error
object
object
object
Example generated
{ "detail": [ { "ctx": {}, "input": "example", "loc": [ "example" ], "msg": "example", "type": "example" } ]}