/api/v1/account/billing-portalReturns a Stripe Customer Portal session URL.
Returns a Stripe Customer Portal session URL. The frontend MUST redirect the user to this URL via `window.location.href = response.url` (Stripe disallows iframe embedding via X-Frame-Options: DENY). Free users without a Stripe customer get a 400 with `error: no_stripe_customer`.
Why use this
Common use case
Stripe Customer Portal session URL — single endpoint for self-serve subscription management (update card, view invoices, cancel subscription, change billing email). EXEMPT (cost: 0). The frontend redirect pattern is a HARD requirement (not a recommendation): window.location.href = response.url. Iframe embedding is blocked by Stripe's X-Frame-Options: DENY on the portal HTML and will silently 0x0 in the browser. Free-tier users without stripe_customer_id get a 400 with error: no_stripe_customer — gate the 'Manage Billing' button by checking GET /api/v1/account/balance plan === 'paid' first. For viewing the per-charge wallet ledger inline use GET /api/v1/billing/history; for invoice PDF downloads use GET /api/v1/billing/invoices (which fetches the same Stripe data via a server-side API call, no redirect needed).
Response schema
| Field | Type | Nullable | Description |
|---|---|---|---|
| url | string | no | Stripe Customer Portal session URL. Short-lived (~1 hour TTL). REDIRECT the browser to this URL via `window.location.href = response.url` — DO NOT iframe-embed (Stripe sets `X-Frame-Options: DENY` on the portal response). After the user finishes (or closes the portal), Stripe redirects back to `${FRONTEND_URL}/account` per the server-configured `return_url`. |
Sample response
- "url": "https://billing.stripe.com/p/session/test_YWNjdF8xUXBlV0VLRzQzS3JCbnJ1eA0HDJI"
Errors
| Status | Label | Description |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Invalid query, body, or path parameter. |
| 401 | Unauthorized | Missing or invalid Authorization header / api_Token. |
| 402 | Payment Required | Insufficient token balance for this call. Top up |
| 429 | Too Many Requests | Rate limit exceeded for your tier (see /pricing for tier limits). Tier limits |
| 500 | Server Error | Unexpected server-side failure. Retry with backoff; report if persistent. |
Code samples
curl -X POST "https://api.finradar.ai/api/v1/account/billing-portal" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).