*_micro_usd, where 1 USD = 1,000,000 micro-USD).
Balance
GET /v1/credits/balance returns the current balance.
string
Always
credit_balance.integer
Available balance, in micro-USD.
string
live or test — the tier this balance is held in.Ledger
GET /v1/credits/ledger lists metered entries, newest first. Cursor-paginated — see Pagination. Each inference debit carries a 5-tier token line-item breakdown of what was metered.
object[]
Ledger entries.
?type=, ?session_id=, ?agent_id=, ?deployment_id=, ?from=, and ?to= (the from/to bounds are RFC 3339 timestamps).
Response
Top up
POST /v1/credits/topups opens a hosted charge and returns a topup object describing it. It does not move the balance: credit is applied when the payment provider’s signed callback arrives and is verified, so poll the balance rather than reading the create response as settlement. Requires the billing:write scope.
integer
required
Amount to add, in micro-USD.
The topup object
string
Top-up id (e.g.
top_01H...).integer
Amount requested, in micro-USD.
string
Lifecycle state. One of:
pending— the charge is being processed.requires_action— the payment needs additional authentication (e.g. 3-D Secure). Complete it viaaction_url, then poll.succeeded— the charge cleared and the balance was credited.failed— the charge was declined; the balance is unchanged.
string | null
Present only when
status is requires_action: the URL to complete authentication.integer | null
Always
null on this response — the balance moves only when the provider callback settles the charge. Read the balance instead.string
Creation timestamp.
Response
Confirming a charge that is not yet terminal
A charge can land inpending or requires_action, so the status on the create response is not always the final word.
Two ways to reach the terminal state:
- Poll the balance.
GET /v1/credits/balancereflects the credit as soon as the charge clears. This is the simplest check when you know the amount you expect. - Read the ledger.
GET /v1/credits/ledgerlists entries newest-first; the settled top-up appears as acreditentry. Match it bycreated_atandamount_micro_usd.
status comes back requires_action, send the payer to action_url first; the balance does not move until they complete authentication.
When the balance is too low to cover a call, the API returns
insufficient_credits (402); when a call would breach a configured per-agent or per-session cap it returns budget_exceeded (402). Top up (or raise the cap), then retry — see Errors and Agents. Successful top-ups are recorded in the audit log as credits.topped_up.The plan
Credits pay for what an agent does. The plan is separate: it is the right to use the organization at all. Every organization needs an active plan — $20 per month — before any route outside billing will answer. Without one the API returnssubscription_required (402) with the message telling you exactly what to do.
Creating an organization does not start a plan. Buy one, then the organization works.
Reading the plan
GET /v1/credits/subscription returns the current plan. Requires the billing:read scope, and is answerable whether or not a plan is active.
string
One of:
none— no plan has ever started. Every gated route is refused.active— the organization can be used.past_due— the last payment did not go through. The organization keeps working untilgrace_until, then is refused.canceled— the plan ended. Every gated route is refused.
string | null
When the paid period ends, or
null if no plan has ever started.string | null
While
past_due, the moment the organization stops working. null means no grace remains.boolean
true once a cancellation has been asked for. The organization stays usable until current_period_end and is refused after it.string | null
Always
null on a read; see below.An
active plan whose current_period_end is more than three days in the past stops being honoured. Renewals reach us as signed callbacks, and a callback that never arrives must not become permanent free access. Any later callback moves the deadline forward again, so a plan that is genuinely paid heals itself the moment the next event lands.Response
Starting or renewing the plan
POST /v1/credits/subscription opens a hosted checkout page and returns its URL as action_url. It takes no body. Requires the billing:write scope.
Like a top-up, it changes nothing on its own: the organization becomes usable once the payment is confirmed, which is normally a second or two after the customer completes the page. Re-read GET /v1/credits/subscription until status is active.
Response
Cancelling the plan
DELETE /v1/credits/subscription stops the plan at the end of the period already paid for — never immediately, and nothing is refunded or charged again. Requires the billing:write scope, and like the two routes above it answers whether or not the organization is currently usable: a recurring charge you can only stop by paying first is not one a customer can stop.
The organization keeps working until current_period_end, and is refused after it. Re-read GET /v1/credits/subscription to see cancel_at_period_end become true — the state follows the payment provider’s confirmation, so the read is the truth, not this response.
Response
POST /v1/credits/subscription again.
Managing the payment method, invoices and cancellation
POST /v1/credits/billing_portal returns a link to the payment provider’s own hosted account page, where a customer can change the card on file, download past invoices, and cancel. It takes no body and requires the billing:write scope. The link is single-use and expires — follow it, do not store it.
Like every other route on this page it changes nothing by itself. Whatever the customer does on that page arrives back as the same confirmed events that already move the plan, so re-read GET /v1/credits/subscription afterwards rather than assuming an outcome.
Response
404 not_found rather than an empty page:
404
What stays open without a plan
An organization with no plan can still identify itself, read its own billing state, and pay. Everything else is refused withsubscription_required (402).
A session already running is never cut off mid-turn. The plan is checked when work is admitted — starting a session, sending it a message, or a schedule firing — not on every turn of a session already under way. A lapse stops new work; it does not kill a task in flight. Plan changes are recorded in the audit log as
subscription.updated, and a customer’s own cancellation as subscription.canceled.