Skip to main content

ApiKeysClient

from lium.sdk import ApiKeysClient

Defined in lium.sdk.api_keys.

ApiKeysClient(lium: lium.sdk.client.Lium)

Methods​

MethodDescription
scopes_payloadThe body of GET /keys/scopes as the server sent it, read once per client:.
scopesEvery scope the server knows: its sentence, what a key holding it can do, the routes it opens,.
pod_visibilities{"own": <sentence>, "account": <sentence>} — the server's words for each pod-visibility value.
listThe keys of a workspace (GET /keys, X-Lium-Workspace-Id when given).
getOne key by id (GET /keys/{id}).
refusalsThe requests this key's budget refused, newest first (GET /keys/{id}/refusals — the ledger's.
revokeRevoke a key (DELETE /keys/{id}): it stops working at once. Used by lium keys create to take.
resolveA key by name (case-insensitive) or id among the workspace's keys.
createMint a key (POST /keys); the secret is in the returned key this once.
updateSet or clear a key's budgets (PATCH /keys/{id}; server support pending).

scopes_payload​

def scopes_payload() -> Dict[str, Any]:

The body of GET /keys/scopes as the server sent it, read once per client: \{"scopes": [...], "pod_visibility": [...], "money_routes": [...]\}.

A server before per-key budgets has no such route: the path falls into its session-only GET /keys/\{id\} and answers 401 (lium.io on 21 Sep 2026), or 404 once that route is gone. On a server that has the route it takes no credential at all, so neither answer can mean a bad key — both become one LiumNotFoundError that names the missing route. A server that answers a bare list is read as the scopes list alone.

scopes​

def scopes() -> List[lium.sdk.models.ApiKeyScope]:

Every scope the server knows: its sentence, what a key holding it can do, the routes it opens, and whether a key made without naming scopes gets it.

pod_visibilities​

def pod_visibilities() -> Dict[str, str]:

\{"own": <sentence>, "account": <sentence>\} — the server's words for each pod-visibility value.

list​

def list(workspace_id: Optional[str] = None) -> List[lium.sdk.models.ApiKeyInfo]:

The keys of a workspace (GET /keys, X-Lium-Workspace-Id when given).

get​

def get(
key_id: str,
workspace_id: Optional[str] = None
) -> lium.sdk.models.ApiKeyInfo:

One key by id (GET /keys/\{id\}).

refusals​

def refusals(
key_id: str,
workspace_id: Optional[str] = None
) -> List[lium.sdk.models.ApiKeyRefusal]:

The requests this key's budget refused, newest first (GET /keys/\{id\}/refusals — the ledger's api_key_budget_refused rows; server support pending). A server without the route answers 404 (LiumNotFoundError); a body of \{"refusals": [...]\} or a bare list is read alike. Rows are ordered on the parsed stamp, so Z, offset and naive stamps sort together; unreadable ones go last.

revoke​

def revoke(key_id: str, workspace_id: Optional[str] = None) -> None:

Revoke a key (DELETE /keys/\{id\}): it stops working at once. Used by lium keys create to take back a key the server minted without the cap that was asked for.

resolve​

def resolve(
name_or_id: str,
workspace_id: Optional[str] = None
) -> lium.sdk.models.ApiKeyInfo:

A key by name (case-insensitive) or id among the workspace's keys.

Names are not unique on the server: two keys with that name is an error that names both ids.

create​

def create(
name: str,
scopes: Optional[Iterable[str]] = None,
*,
daily_budget_usd: Optional[float] = None,
monthly_budget_usd: Optional[float] = None,
max_budget_usd: Optional[float] = None,
pod_visibility: Optional[str] = None,
workspace_id: Optional[str] = None,
allow_unrecorded: bool = False
) -> lium.sdk.models.ApiKeyInfo:

Mint a key (POST /keys); the secret is in the returned key this once.

scopes defaults to DEFAULT_SCOPES (read, rent, manage) and is always sent, so billing — the money routes — is on a key only when named, and then alone (BILLING_ALONE). The three budgets (daily_budget_usd per UTC day, monthly_budget_usd per UTC month, max_budget_usd for the key's lifetime) are sent as numbers (USD ≥ 1, whole cents) only when given, daily ≤ monthly ≤ max. pod_visibility (own: the key sees only the pods it creates; account: every pod of the account) is sent only when given — left None, the server's own default decides, which its operator may switch. A server before per-key budgets ignores the budget and visibility fields and answers the row without them: unrecorded() tells, and this method revokes the key unless allow_unrecorded is true (the CLI sets that so --allow-unbudgeted can keep the key).

update​

def update(
key_id: str,
*,
daily_budget_usd: Optional[float] = UNSET,
monthly_budget_usd: Optional[float] = UNSET,
max_budget_usd: Optional[float] = UNSET,
workspace_id: Optional[str] = None
) -> lium.sdk.models.ApiKeyInfo:

Set or clear a key's budgets (PATCH /keys/\{id\}; server support pending).

A budget given as a number is set, as None is cleared, left out (UNSET) is kept as it is; naming none is a ValueError here (the server would answer 400). The budgets named here must keep daily ≤ monthly ≤ max among themselves. Scopes and pod visibility are fixed at creation and cannot be changed.