Choose a plan (checkout-gated)
POST/api/billing/subscribe
Subscribe the tenant to a catalogue plan. Admin only.
Checkout-gating (Faz 3 Dilim B). Behaviour depends on the chosen tier under the live Stripe provider:
- Free tier — switched synchronously (no payment); responds
200with the refreshed billing summary. - Paid tier — responds
202with a hosted Stripe Checkout URL (checkout_url). NO quota is granted here; the subscription only becomes live after the customer completes payment and Stripe's webhook syncs it.
Under the deterministic fake provider (dev/test) there is no real money, so
every plan is provisioned directly and the response is always the 200
summary. Clients should handle BOTH response shapes (redirect to
checkout_url on 202).
Terms + DPA. A paid tier chosen while legal_acceptance.accepted is
false requires accept_terms: true (422 on accept_terms otherwise); the
acceptance is recorded before any invoice is issued.
Request
Responses
- 200
- 202
- 401
- 403
- 422
- 502
The refreshed billing summary — a free-tier switch, or any plan under the fake provider.
A paid tier under the live Stripe provider: redirect the browser to the returned hosted Checkout URL. The subscription activates only after payment (via webhook).
Not authenticated. code: account_disabled means the member's seat was deactivated in this workspace: the session is over even though the token was not revoked (clients sign out and clean up).
Authenticated but not allowed.
The request failed validation.
The payment provider could not start the payment. Nothing was charged; the invoice this request issued is voided.