Skip to content
External Console API

Get Credit

Read the balance — or, for a quota-funded sub-account, the remaining quota — of one account you can reach, without opening the console.

GET https://console-api.siraya.ai/extapi/v1/accounts/{accountId}/credit

Path Parameters

The account is named in the path. There is no query parameter and no body.

accountId string Required

The account to read. Must be a UUID. Use any id returned by List Accounts — root, sub-account, or archived.

If your token is pinned to one account, accountId must be that account; any other id is refused with 403.

curl https://console-api.siraya.ai/extapi/v1/accounts/566a70b9-9e33-4a0b-9c3c-6f4c2f6c2a11/credit \
  -H "Authorization: Bearer <CONSOLE_TOKEN>"
import requests

account_id = "566a70b9-9e33-4a0b-9c3c-6f4c2f6c2a11"
url = f"https://console-api.siraya.ai/extapi/v1/accounts/{account_id}/credit"
headers = {"Authorization": "Bearer <CONSOLE_TOKEN>"}

response = requests.get(url, headers=headers)
print(response.json()["data"])

Example Response — direct_transfer account

{
  "isSuccess": true,
  "data": {
    "id": "566a70b9-9e33-4a0b-9c3c-6f4c2f6c2a11",
    "name": "Acme Root",
    "parent_id": null,
    "is_root": true,
    "is_archived": false,
    "funding_type": "direct_transfer",
    "balance": "1250.500000",
    "currency": "USD"
  }
}

Example Response — limit_quota account

{
  "isSuccess": true,
  "data": {
    "id": "8d2f0c1e-4b7a-4e55-9a10-2f3c9b7d6e01",
    "name": "Acme Team A",
    "parent_id": "566a70b9-9e33-4a0b-9c3c-6f4c2f6c2a11",
    "is_root": false,
    "is_archived": false,
    "funding_type": "limit_quota",
    "currency": "USD",
    "quota": {
      "limit": "5000.000000",
      "used": "1250.500000",
      "remaining": "3749.500000",
      "quota_period": 1,
      "unit_period": "month",
      "next_reset_at": "2026-10-24T00:00:00Z"
    }
  }
}

Reading the response

Every root account, and every sub-account funded by transfer, holds a wallet of its own and returns balance. A limit_quota sub-account holds no money of its own — it spends against an allowance — and returns quota instead.

Field Meaning
id The account read. Always the accountId you sent
name The account's display name
parent_id The parent account's id. null on a root account
is_root true for a root account
is_archived true for an archived account. Archived accounts stay readable and still report their balance or quota
funding_type direct_transfer or limit_quota. A root account is always direct_transfer
balance The wallet balance, as a decimal string with 6 decimals. direct_transfer only — omitted on limit_quota
currency ISO 4217 currency code. USD when the wallet names none, and always on limit_quota
quota The spending allowance. limit_quota only — omitted on direct_transfer
quota.limit The allowance per period, 6 decimals. null when no limit has been set
quota.used Spend recorded in the current period, 6 decimals
quota.remaining limit − used, never below zero. null when limit is null
quota.quota_period / quota.unit_period The period length, read together: 1 × "month" is one month. null when not set
quota.next_reset_at RFC 3339 UTC time the current period ends. null when billing has not opened a period for the account yet

Exactly one of balance and quota is present. Branch on funding_type, not on which key happens to exist.

Amounts are decimal strings, not numbers — parse them with a decimal type to avoid floating-point rounding.

What the number is — and is not

  • Live. The balance is read from the wallet on every call and is never cached, so a read straight after a Transfer Credit already reflects it.
  • Not aggregated. A parent's balance is its own wallet only. It does not include the balances of its sub-accounts. To see a tree, call this endpoint once per account from List Accounts.
  • No ancestor balance. A limit_quota account spends from the nearest direct_transfer ancestor, but this endpoint never returns that ancestor's balance through the sub-account. Read the ancestor directly if your token reaches it.

Who may read

The account must be one your token can reach — the same set List Accounts returns:

  • every account where the token's user holds a membership, and
  • every account inside a sub-account tree the user owns.

On top of that:

  • the user's membership in that account must be active, and
  • the user must hold the res.credit permission (read) on it.

A token pinned to one account reads that account only.

Errors

Status error.code Meaning
400 BAD_REQUEST accountId is not a UUID
401 UNAUTHORIZED / INVALID_CREDENTIALS Token missing, malformed or revoked
403 FORBIDDEN Token pinned to another account; token pinned to an account its user no longer belongs to; user belongs to no account; membership inactive; or token lacks res.credit
404 NOT_FOUND The account is not reachable with this token — see below
429 RATE_LIMIT_EXCEEDED Per-user rate limit
500 INTERNAL_ERROR Account or membership lookup failed
502 UPSTREAM_UNAVAILABLE The wallet or billing service did not answer, or answered data that could not be read. Retry; no stale or zero value is returned in its place
503 SERVICE_UNAVAILABLE Credit information is temporarily unavailable

Why 404 is deliberately vague

An account that does not exist, one in another organisation, and one outside the subtree your token reaches all return the same 404 — "Account not found" — identical in status and body. The endpoint therefore cannot be used to discover which account ids are real by reading the errors apart.

A pinned token is the exception: it has exactly one valid account, so naming any other gets a plain 403 — there is nothing to enumerate.