Billing API
API endpoints for managing billing and subscriptions.
Billing API
Manage Stripe billing programmatically. Checkout and portal endpoints require admin role.
Create Checkout Session
Create a Stripe Checkout session to upgrade to a paid plan.
POST /api/v1/billing/checkoutAuthentication: Session (admin role required)
Request body:
{
"plan": "starter"
}| Field | Type | Required | Description |
|---|---|---|---|
plan | string | Yes | Plan to upgrade to: starter or business |
Response:
{
"url": "https://checkout.stripe.com/c/pay/..."
}Redirect the user to the returned URL to complete checkout.
Errors:
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | Invalid plan name |
| 501 | billing_not_configured | Stripe not configured (self-hosted without billing) |
Create Portal Session
Create a Stripe Customer Portal session for managing subscriptions, payment methods, and invoices.
POST /api/v1/billing/portalAuthentication: Session (admin role required)
Response:
{
"url": "https://billing.stripe.com/p/session/..."
}Redirect the user to the returned URL to manage their subscription.
Get Subscription Status
Get the current subscription status for the tenant.
GET /api/v1/billing/statusAuthentication: Session or API key
Response:
{
"data": {
"plan": "starter",
"status": "active",
"current_period_end": "2026-04-23T00:00:00.000Z",
"cancel_at_period_end": false
}
}| Field | Type | Description |
|---|---|---|
plan | string | Current plan: free, starter, business, enterprise |
status | string | Subscription status: active, canceled, past_due |
current_period_end | string | ISO 8601 date when current billing period ends |
cancel_at_period_end | boolean | Whether subscription will cancel at period end |
Stripe Webhook
Receives events from Stripe to sync subscription state. This endpoint is called by Stripe directly — no authentication header required. Stripe signature verification is used instead.
POST /api/v1/billing/webhookHeaders:
| Header | Description |
|---|---|
stripe-signature | Stripe webhook signature |
Handled events:
checkout.session.completed— Activate subscription after checkoutcustomer.subscription.updated— Sync plan changescustomer.subscription.deleted— Downgrade to free planinvoice.payment_failed— Mark subscription as past due