Creates a Stripe Customer Portal session where users can manage their subscription, update payment methods, and view invoices.
Authentication Required: This endpoint requires a Clerk JWT token with
organization context. The organization is determined from the org_id claim
in the token.
Bearer token with organization context: Bearer {clerk_jwt_token}
Request Body
URL to redirect back to after leaving the portal
Response
The Stripe Customer Portal URL - redirect the user here
curl -X POST https://searchcompany-main.up.railway.app/api/billing-portal \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_CLERK_JWT_TOKEN" \
-d '{
"return_url": "https://app.searchcompany.co/dashboard/settings"
}'
{
"url": "https://billing.stripe.com/p/session/abc123..."
}
Errors
| Status | Description |
|---|
| 401 | Missing or invalid authentication token |
| 401 | No organization context in token |
| 400 | No Stripe customer linked to this organization |
| 404 | Organization not found |
| 500 | Stripe API error |
Usage
After receiving the URL, redirect the user:
// Get token with organization context
const token = await getToken({ organizationId: organization.id });
const response = await fetch("/api/billing-portal", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
return_url: window.location.href,
}),
});
const { url } = await response.json();
window.location.href = url;