Overview
What Billing covers, workspace billing ownership, and how checkout relates to local cancel/upgrade.
What this reference explains
Billing is the end-user voice subscription surface: list packages, see the current plan and minute/assistant usage, upgrade or cancel locally, and create a paid subscription through card checkout. In the product UI the sidebar label is Billing (route /subscription); checkout uses /payment.
Workspace billing ownership
GET /subscriptions/current and GET /subscriptions/usage attach a sibling billing object: source is self or workspace_owner, plus workspace_id, workspace_name, and can_manage_billing. Team members on an owner-billed workspace see the owner's plan and cannot manage billing themselves.
Cancel vs checkout
The Billing page cancels via POST /subscriptions/cancel, which marks the local row cancelled — it does not call POST /stripe/subscription/cancel. New paid plans are created with POST /stripe/subscription (payment method id + package). POST /subscriptions/subscribe creates a local active row without card checkout (legacy companion).
Response envelope
Panel shape {"success": true, "data": ...}. Some reads also return sibling billing and/or message. Checkout create returns 201. Config is flat: success, publishable_key, test_mode, currency (no nested data).
Feature availability
These routes are not gated by a feature flag. Authenticated users under auth:sanctum + reseller context can call them. Package listing and payment publishable config are also available on public reseller-scoped routes for the pricing/checkout pages.
Out of scope here
- Agent-token wallet (
/agent-tokens/*, featureai_chat) — Agents surface. /user/usage/*widgets, transaction create/update/process, unused payment-intent / subscription cancel-update-details under/stripe.- Registered but unimplemented
downgrade/reactivateroutes. - Admin, reseller-admin, and Connect payment configuration.