Skip to content
External Console API

External Console API

The External Console API is the surface you call from your own systems to run the account work you would otherwise do by hand in the console: list the models an account may call, read usage history, check an account's credit, and transfer credit between accounts.

It is authenticated with a console token (csk-...), which is not the same credential as the sk-... key used for model inference. The Asset Management API is served from the same base URL but takes the sk-... API key instead.

Base URL

https://console-api.siraya.ai/extapi/v1

Endpoints

Method Endpoint Description
List Accounts GET /accounts Accounts this token can reach
List Models GET /models Models an account may call, with list pricing
Get Usage GET /usage Usage history, paginated
Get One Usage Record GET /usage/{request_id} A single usage record
Get Credit GET /accounts/{accountId}/credit Balance or remaining quota of one account
Transfer Credit POST /accounts/transfers Move credit to a sub-account

Authentication

Send your console token as a Bearer token on every request:

Authorization: Bearer <CONSOLE_TOKEN>

A console token carries no permissions of its own. It inherits the authority of the user who created it, resolved against IAM on every call. Two consequences worth designing around:

  • Take a permission away from that user and the token loses it immediately — no re-issue needed.
  • A token issued by a member who lacks a permission cannot be used to work around that. Issuing a token grants nothing the session did not already have.

See Console Tokens for how to create, pin and revoke them.

Choosing the account a request acts in

Most organisations have one root account with sub-accounts beneath it. A token that is not pinned can reach several of them, so every request settles on one effective account.

The request names it — the parameter differs per endpoint and is documented with each one. Whatever you pass is intersected with the token's pin and your live memberships, so you cannot name an account you have no claim to.

Omit it and the first account in your list is used. That default is positional: it moves as your account list changes.

Name the account explicitly in automated jobs

Call GET /accounts first and pass the id you want. A job that relies on the positional default will silently start acting on a different account the day your account list changes.

Status codes

Branch on the HTTP status and on error.code — never on error.message, which is prose and will change.

Treat the payload as open: ignore fields you do not recognise. New ones are added without a version bump.

Status Meaning
400 The request was malformed or failed validation
401 Token missing, malformed, expired or revoked
403 The issuing user lacks the permission, or their membership is inactive
404 The thing you named is not reachable from your effective account
429 Rate limited. Honour Retry-After
5xx A server-side failure

Rate limiting

Limits are applied per user, not per token and not per IP — a second token held by the same user draws from the same budget. The default is 120 requests per 60 seconds.

Every response carries the current budget:

Header Meaning
X-RateLimit-Limit Requests allowed per window
X-RateLimit-Remaining Requests left in this window (floors at 0)
X-RateLimit-Reset Unix seconds when the window rolls over
Retry-After Seconds to wait — sent on 429 only

Going over budget returns 429 with error.code RATE_LIMIT_EXCEEDED.