Billing API
Billing and subscription management endpoints for organizations and projects
Billing API
Billing endpoints manage Stripe customer creation, subscriptions, and portal sessions at both organization and project scopes.
Overview
Billing can be configured at either the organization or project level. Projects may inherit billing from their parent organization.
Organization Billing Endpoints
GET /api/v1/organizations/{orgId}/billing
PUT /api/v1/organizations/{orgId}/billing
POST /api/v1/organizations/{orgId}/billing/customer
POST /api/v1/organizations/{orgId}/billing/subscription
POST /api/v1/organizations/{orgId}/billing/portal
POST /api/v1/organizations/{orgId}/billing/cancel
GET /api/v1/organizations/{orgId}/billing/status
POST /api/v1/organizations/{orgId}/billing/setup-intentProject Billing Endpoints
GET /api/v1/projects/{projectId}/billing
PUT /api/v1/projects/{projectId}/billing
POST /api/v1/projects/{projectId}/billing/customer
POST /api/v1/projects/{projectId}/billing/subscription
POST /api/v1/projects/{projectId}/billing/portal
POST /api/v1/projects/{projectId}/billing/cancel
GET /api/v1/projects/{projectId}/billing/status
POST /api/v1/projects/{projectId}/billing/setup-intentBilling Status Endpoint
Returns billing status, payment method status, and Stripe subscription info for onboarding/payment enforcement.
GET /api/v1/organizations/{orgId}/billing/status**
GET /api/v1/projects/{projectId}/billing/status**Response:
Billing API Overview
KtrlPlane uses Stripe for all billing and payment processing. Billing information is managed centrally and inherited by projects and resources as needed. All billing info is sourced directly from Stripe; the database does not store SubscriptionStatus, SubscriptionPlan, or BillingEmail fields.
Key Concepts
- Billing Account: Each organization or project can have a billing account, managed via Stripe. The
billing_accountstable is the canonical source for Stripe IDs (customer, subscription, etc.). Projects and organizations reference billing_accounts only; Stripe IDs are not stored in their tables. - Subscription: Subscriptions are managed via Stripe and linked to billing accounts. Subscription status and cancellation are reflected live from Stripe.
- Invoices: The UI displays the last invoice (not upcoming) from Stripe. The "Current Period" field has been removed for clarity.
API Endpoints
GET /api/v1/billing/account- Retrieve billing account detailsPOST /api/v1/billing/account- Create or update billing accountGET /api/v1/billing/invoices- List invoices for the billing accountGET /api/v1/billing/subscription- Get subscription detailsPOST /api/v1/billing/subscription/cancel- Cancel subscription at period end
UI/UX Behavior
- Stripe is the single source of truth for billing info.
- The UI shows the last invoice, not upcoming.
- If a subscription is pending cancellation (
cancel_at_period_endis true), the UI displays a clear warning and disables the cancel button, guiding users to the Payment Management Portal to continue their subscription. - All billing and subscription actions are managed via Stripe and surfaced in the UI.
Cancellation Workflow
- To cancel a subscription, users schedule cancellation at the end of the current billing period.
- If cancellation is already scheduled, the UI shows a warning and provides a link to the Payment Management Portal to continue the subscription if desired.
Security & Compliance
- All billing endpoints require JWT authentication and RBAC enforcement.
- No sensitive payment data is stored in the KtrlPlane database.
Example Response
{
"billing_account": {
"id": "acct_123",
"stripe_customer_id": "cus_abc",
"stripe_subscription_id": "sub_xyz"
},
"subscription_details": {
"id": "sub_xyz",
"status": "active",
"cancel_at_period_end": true,
"current_period_end": 1704067200
},
"latest_invoice": {
"id": "in_456",
"amount_due": 1000,
"currency": "usd",
"period_start": 1701388800,
"period_end": 1704067200,
"status": "paid",
"hosted_invoice_url": "https://..."
}
}