Billing
Subscriptions, AI credit wallet, and Dodo Payments checkout/portal sessions.
Description
Billing is split across two independent systems that are easy to conflate:
- Entitlements (e.g.
portfolio_publish) — gate feature access based on an active subscription plan (ai_credits,portfolio_pro, orbundle). - The AI credit wallet — a separate, spendable balance used by
/ai/generateand the AI-gated ATS endpoints. A plan can grant credits, publishing access, both (bundle), or neither (FREE).
GET /billing/me returns both in one summary, along with the public product catalog.
Checkout and portal sessions are created through Dodo Payments. POST /billing/checkout
validates productKey and interval against a fixed whitelist (the product catalog) before
handing off to Dodo — arbitrary combinations are rejected with 400. A Redis lock prevents
starting a second checkout while one is already in flight; cancel it with
POST /billing/checkout/cancel if needed.
Payments are admin-gated in production during this phase
In production, checkout, portal, and credit pack checkout are currently restricted to the configured admin account. This is a rollout-phase restriction, not a permanent limitation, and does not apply in development.
Authentication
All routes in this group require a session cookie — none accept an API key.
Available Endpoints
GET /billing/me— Get Billing SummaryGET /billing/history— Get Billing HistoryGET /billing/credits— Get AI Credit WalletGET /billing/credits/history— Get AI Credit Transaction HistoryPOST /billing/checkout— Create Subscription Checkout SessionPOST /billing/checkout/cancel— Cancel In-Flight CheckoutPOST /billing/portal— Create Billing Portal SessionPOST /billing/credits/checkout— Create Extra Credit Pack Checkout
Delete Portfolio AssetDELETE
Deletes the R2 object and its metadata row. `data` is `null` on success. Session-authenticated only. This does not rewrite any portfolio that still references the asset — remove the reference and save the draft first, or publishing will fail with `400`.
Get Billing SummaryGET
Returns the caller's plan, subscription status, entitlements, AI credit wallet, and public catalog in one call. Entitlements (e.g. portfolio publishing) and the AI credit wallet are two independent systems — a plan can grant one, both, or neither depending on `productKey`. Session-authenticated only.