← Docs

Billing & plans

Every Organization has exactly one real Plan — price, limits, and feature flags, never inferred from a separate tier label. See the public pricing page for the real, current catalog, or fetch it directly:

GET /api/v1/billing/          -> { plan, usage, paystack }  (your own Organization)
GET /api/v1/billing/plans/    -> the full real catalog, for the upgrade UI

Usage is tracked, not estimated

usage.applications.count and usage.mau.count are computed live from real rows (a live Application count; monthly active users counted from real sign-in activity in the current period) — never a cached estimate that can drift from what actually happened.

Overage gates creation, never authentication

Reaching Plan.max_applications blocks creating another Application (a real 400 from POST /api/v1/applications/) — it never blocks anyone from signing in, and never disables an Application you've already registered. The same principle applies to every other plan-gated feature (custom domain, white-label branding, webhooks, API keys, SCIM): the check happens server-side, at the point of use, not just hidden in this dashboard's UI, and a downgrade takes effect immediately on the next check, not just on new creation attempts.

Upgrading — a real Paystack checkout

POST /api/v1/billing/upgrade/  { "plan_slug": "growth-monthly" }
-> { authorization_url, reference }

Redirects the browser to Paystack's own hosted checkout page (authorization_url) — no card details ever touch this platform's own servers. The Organization's Plan only actually changes once Paystack confirms the charge via a real, signature-verified webhook, never optimistically on redirect — closing the checkout tab without completing payment leaves the Organization on its current plan, not a half-upgraded state.

Cancelling

POST /api/v1/billing/cancel/

Cancels the real Paystack subscription first; the Organization only drops to the free plan once that cancellation is confirmed — never charged again after a successful cancellation request, and never silently downgraded while a subscription might still be active on Paystack's side. The same real cancellation path is reused, not reimplemented, when an Organization is deleted outright (see Organizations & Applications — a Paystack failure during that flow blocks and rolls back the whole deletion, rather than deleting the Organization while still billing it).

What's not built yet

No self-service downgrade scheduling (a downgrade takes effect immediately on request, same as cancellation — there's no "at the end of the current billing period" option yet). Enterprise pricing is not self-service — its Plan row has no fixed price (null means "contact us"), negotiated outside this flow entirely.