show
GET /v1/credits/balance:
79416537 micro-USD is $79.416537.
topup
POST /v1/credits/topups, body { amount_micro_usd }. Opens a hosted checkout and credits nothing — only the verified provider callback moves the balance. Send the person to the returned URL.
ledger
GET /v1/credits/ledger. LedgerFilter extends the page query with type ("debit" | "credit"), session_id, agent_id, deployment_id, from, and to — every movement, attributable to what spent it.
subscription
GET /v1/credits/subscription — the plan, which is the right to use the organization at all:
status is none | active | past_due | canceled. Every route outside billing answers 402 subscription_required until it reads active. While past_due, grace_until is the moment the organization stops working. action_url is null on a read.
subscribe
POST /v1/credits/subscription. Opens the hosted checkout for the plan — send the person to action_url; nothing changes until the signed callback lands.
cancelSubscription
DELETE /v1/credits/subscription. Stops the plan at the end of the period already paid for — never immediately. The state follows the provider’s callback, so the answer reports the request, not a completed change (cancel_at_period_end: true).
billingPortal
POST /v1/credits/billing_portal. Returns a link to the payment provider’s own hosted account page — change the card, download invoices, cancel. Send the person to action_url; it is single-use and expires, so mint one per visit rather than caching it.
ApiError with code not_found. Catch it and offer subscribe() instead.