Skip to content
runlot
ReferenceAPIai

ai

Covers 8 API operations in the ai category.

MethodPathDescription
GET/v1/ai/modelsAI model catalog (runlot ai models)
GET/v1/orgs/{orgSlug}/projects/{projectName}/aiAI status (runlot ai usage)
POST/v1/orgs/{orgSlug}/projects/{projectName}/aiTurns on AI (a deployment calls this after reading "ai": true)
DELETE/v1/orgs/{orgSlug}/projects/{projectName}/aiTurns off AI (runlot ai delete)
GET/v1/orgs/{orgSlug}/ai/creditAI credit balance and auto top-up settings (runlot ai credit)
GET/v1/orgs/{orgSlug}/ai/ledgerAI ledger
POST/v1/orgs/{orgSlug}/ai/credit/checkoutCredit top-up checkout
PUT/v1/orgs/{orgSlug}/ai/autotopupTurns auto top-up on or off

GET /v1/ai/models

Every model env.ai can call (docs/ai.md §2.3). Any signed-in user can read it — what you can buy is not an org secret, and this list is the price list.

There are two lanes. frontier passes the provider's list price straight through (listPrice: true, zero margin) — that is why the provider's name stays in the model id and provider is included. value models are the ones we buy wholesale and sell at our own price, so provider is not included: that is a value we swap whenever we want.

Prices are integer microcents per million tokens (1 µ¢ = 1e-8 USD). The point is that the server does not fix the number of decimal places — a small call rounds to 0 in cents (docs/ai.md §3.1), and that fact must not be tied to a single format string.

A model id that is not on this list returns 400 at call time. There is no arbitrary model passthrough.

operationId listAIModels

Status codeDescriptionResponse body
200Catalogobject
401

GET /v1/orgs/{orgSlug}/projects/{projectName}/ai

Whether AI is turned on, the four limits, the org's balance, and the last 24 hours of usage (docs/ai.md §6). The limits come populated even when AI is off — they are the material for "here is what the limits would be if you turned this on", and granted is the real state.

0 in maxOutputTokens and maxInputTokens means the model decides.

spentMicroCents24h cannot be built from usage_hourly, so it is read from the ledger instead — prices are a function of the moment, which is why 0046 split the two tables.

viewer or above.

operationId getAI

Status codeDescriptionResponse body
200AI statusAIStatus
403
404
503no_coreError

POST /v1/orgs/{orgSlug}/projects/{projectName}/ai

This is idempotent. There is no request body — neither the limits nor the model list is a value the user sets.

Once it is on, the node connects env.ai on the next convergence. The bundle must also say \\"ai\\": true — turning it on is the CP's side, and which system workers start is the bundle's side.

There is no node credential check: the upstream credentials (Bedrock, Vertex) live in the node's site.env, so the CP has no record of them. On a node without them, turning it on still succeeds and the call returns 503 (an open item in docs/ai.md §9).

member and above. Audited as ai.grant.

operationId grantAI

Status codeDescriptionResponse body
200Status after turning it on (the existing value if it was already on)AIStatus
403
404
503no_coreError

DELETE /v1/orgs/{orgSlug}/projects/{projectName}/ai

From the next deployment on, there is no env.ai. This is idempotent.

The ledger is not deleted — it is the record of money already paid. The credit balance stays as well: the balance belongs to the org, and what you are turning off belongs to the project.

admin. Audited as ai.revoke.

operationId revokeAI

Status codeDescriptionResponse body
204turned off
403
404
503no_coreError

GET /v1/orgs/{orgSlug}/ai/credit

The balance is in microcents and can go negative (docs/ai.md §3.3 — the balance check runs before a call and the deduction after it, so a single call that has already started can take the balance past zero).

If hasPaymentMethod is false, auto top-up cannot be turned on — there is no saved card, and the first top-up is always manual (that is what saves the card).

autoTopupsToday and autoTopupPerDay come together. That cap is the ceiling on a day's spend, so a screen has to show both to answer "why didn't it top up".

member or above.

operationId getAICredit

Status codeDescriptionResponse body
200Credit statusAICredit
403

GET /v1/orgs/{orgSlug}/ai/ledger

This is the source of truth for amounts (0046). kind is call (negative), topup (positive), or adjust. The cursor is ledger_id — cutting by time would split two rows in the same millisecond across a page boundary.

member or above.

operationId listAILedger

ParameterLocationRequiredTypeDescription
limitqueryNointeger
beforequeryNointegerrows before this ledger_id
Status codeDescriptionResponse body
200Ledgerobject
403

POST /v1/orgs/{orgSlug}/ai/credit/checkout

Returns an embedded checkout URL (the same shape as docs/billing.md §3.1 — the dashboard opens it in an iframe).

A browser coming back is not proof. The one thing that raises the balance is the order.paid webhook, and the screen polls the balance after the success event.

microCents must be one of the listed tiers — auto top-up uses the same list (it charges with nobody watching, so the amount has to be one of the enumerated values), and leaving manual top-up free-form would create two tables.

operationId createAICreditCheckout

Request body: application/json · object

Status codeDescriptionResponse body
200Checkoutobject
400The top-up amount is not one of the offered tiers, or returnTo is not an allowed addressError
403
501billing_off — this installation has no credit product configuredError

PUT /v1/orgs/{orgSlug}/ai/autotopup

Turning it on is explicit consent (docs/ai.md §3.5). The screen shows "when the balance falls below X, we charge Y to the saved card, at most N times a day" verbatim and takes a checkbox — card network rules require prior consent for off-session charges, and that sentence is the content of the consent.

The server checks three things: whether a payment method is saved (409 if not), whether the amount is on the tier list, and whether the threshold is greater than 0 and smaller than the top-up amount. A threshold of 0 makes the whole asynchronous top-up window return 402, and a threshold at or above the top-up amount leaves the balance still below the threshold after a top-up, so it keeps topping up to the daily cap — that is a trap, not a setting.

admin. Audited as ai.autotopup.on / ai.autotopup.off.

operationId setAIAutoTopup

Request body: application/json · object

Status codeDescriptionResponse body
200Turned onobject
204turned off
400The amount is not on the tier list, the threshold is 0 or less, or the threshold is at or above the top-up amountError
403
409no_payment_method — there is no saved card. Top up manually once firstError

On this page