Appearance
Billing API
8 operations. Paths are relative to the API host (http://localhost:5080 in local development). Every operation accepts an OIDC bearer token (Authorization: Bearer …) or a workspace API key (X-Api-Key: keel_live_…); errors are RFC 9457 Problem Details with a code (error codes). Permissions: matrix.
| Method | Path | Summary |
|---|---|---|
| POST | /api/public/v1/billing/stripe-webhook | Stripe webhook (signed, idempotent per event id, out-of-order safe; F20 AC2). Not for browsers. |
| GET | /api/v1/tenant/billing | The billing page: plan, add-ons, usage meters and the plan catalog (Owners). |
| PUT | /api/v1/tenant/billing/add-ons/{addOn} | Add or remove an add-on (prorated; a trial buys it at checkout) (Owners). |
| GET | /api/v1/tenant/billing/payments | Payment method, billing contact and invoices from the payment provider (Owners). |
| POST | /api/v1/tenant/billing/plan | Choose or change the plan: a checkout URL for a trial, a prorated change for a paid plan; 422 Billing.DowngradeBlocked lists what to remove first; 422 Billing.DowngradeConfirmationRequired lists what the change keeps frozen until it is confirmed (Owners). |
| POST | /api/v1/tenant/billing/portal | A customer portal session URL: payment method, billing details, invoices (Owners). |
| POST | /api/v1/tenant/billing/subscription:cancel | Cancel: a paid plan ends at the end of its period; a trial ends now (read-only, nothing deleted) (Owners). |
| GET | /api/v1/tenant/entitlements | Plan, status, trial and read-only state, features in effect and usage at 80%+ (any member; drives banners and navigation). |
ReceiveStripeWebhook
http
POST /api/public/v1/billing/stripe-webhookStripe webhook (signed, idempotent per event id, out-of-order safe; F20 AC2). Not for browsers.
Request body (application/json): any
| Status | Description | Body |
|---|---|---|
| 200 | OK | WebhookReceipt |
| 400 | Bad Request | ProblemDetails |
| 401 | Unauthorized | ProblemDetails |
Response 200: WebhookReceipt
| Field | Type | Notes |
|---|---|---|
outcome | string |
GetBillingOverview
http
GET /api/v1/tenant/billingThe billing page: plan, add-ons, usage meters and the plan catalog (Owners).
| Status | Description | Body |
|---|---|---|
| 200 | OK | BillingOverviewDto |
Response 200: BillingOverviewDto
| Field | Type | Notes |
|---|---|---|
addOns | AddOnDto[] | |
cancelAtPeriodEnd | boolean | |
catalogVersion | string | |
currentPeriodEnd | date-time? | |
hasPaymentAccount | boolean | |
paymentsEnabled | boolean | |
plan | string | |
planName | string | |
plans | PlanOptionDto[] | |
priceLabel | string | |
readOnly | boolean | |
retainDataUntil | date-time? | |
source | string | |
status | string | |
trialDaysLeft | int32? | |
trialEndsAt | date-time? | |
usage | UsageMeterDto[] | |
usageResetsAt | date-time |
SetBillingAddOn
http
PUT /api/v1/tenant/billing/add-ons/{addOn}Add or remove an add-on (prorated; a trial buys it at checkout) (Owners).
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
addOn | path | string | yes |
Request body (application/json): SetAddOnRequest
| Field | Type | Notes |
|---|---|---|
enabled | boolean |
| Status | Description | Body |
|---|---|---|
| 200 | OK | PlanChangeDto |
Response 200: PlanChangeDto
| Field | Type | Notes |
|---|---|---|
changed | boolean | |
checkoutUrl | uri? |
GetBillingPayments
http
GET /api/v1/tenant/billing/paymentsPayment method, billing contact and invoices from the payment provider (Owners).
| Status | Description | Body |
|---|---|---|
| 200 | OK | BillingPaymentsDto |
Response 200: BillingPaymentsDto
| Field | Type | Notes |
|---|---|---|
billingEmail | string? | |
invoices | InvoiceSummary[] | |
paymentMethod | string? | |
taxId | string? |
ChangePlan
http
POST /api/v1/tenant/billing/planChoose or change the plan: a checkout URL for a trial, a prorated change for a paid plan; 422 Billing.DowngradeBlocked lists what to remove first; 422 Billing.DowngradeConfirmationRequired lists what the change keeps frozen until it is confirmed (Owners).
Request body (application/json): ChangePlanRequest
| Field | Type | Notes |
|---|---|---|
confirm | boolean? | Go ahead although the change keeps features frozen or shortens audit retention (422 Billing.DowngradeConfirmationRequired lists them). |
plan | string |
| Status | Description | Body |
|---|---|---|
| 200 | OK | PlanChangeDto |
| 422 | Unprocessable Entity | ProblemDetails |
Response 200: PlanChangeDto
| Field | Type | Notes |
|---|---|---|
changed | boolean | |
checkoutUrl | uri? |
OpenBillingPortal
http
POST /api/v1/tenant/billing/portalA customer portal session URL: payment method, billing details, invoices (Owners).
| Status | Description | Body |
|---|---|---|
| 200 | OK | RedirectResponse |
Response 200: RedirectResponse
| Field | Type | Notes |
|---|---|---|
url | uri |
CancelSubscription
http
POST /api/v1/tenant/billing/subscription:cancelCancel: a paid plan ends at the end of its period; a trial ends now (read-only, nothing deleted) (Owners).
| Status | Description | Body |
|---|---|---|
| 204 | No Content | — |
GetEntitlements
http
GET /api/v1/tenant/entitlementsPlan, status, trial and read-only state, features in effect and usage at 80%+ (any member; drives banners and navigation).
| Status | Description | Body |
|---|---|---|
| 200 | OK | EntitlementsDto |
Response 200: EntitlementsDto
| Field | Type | Notes |
|---|---|---|
features | string[] | |
plan | string | |
planName | string | |
readOnly | boolean | |
seats | UsageMeterDto | |
sourceConnections | UsageMeterDto | |
status | string | |
trialDaysLeft | int32? | |
trialEndsAt | date-time? | |
warnings | UsageMeterDto[] | |
workspaces | UsageMeterDto |