---
title: ApiKeysClient
sidebar_label: ApiKeysClient
sidebar_position: 1
---

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lium.io/llms.txt
> Use this file to discover all available pages before exploring further.

<!-- Generated by scripts/generate_sdk_reference.py. Do not edit directly. -->

# ApiKeysClient

```python
from lium.sdk import ApiKeysClient
```

Defined in `lium.sdk.api_keys`.

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

## Methods

| Method | Description |
| --- | --- |
| [`scopes_payload`](#scopes_payload) | The body of GET /keys/scopes as the server sent it, read once per client:. |
| [`scopes`](#scopes) | Every scope the server knows: its sentence, what a key holding it can do, the routes it opens,. |
| [`pod_visibilities`](#pod_visibilities) | \{"own": &lt;sentence&gt;, "account": &lt;sentence&gt;\} — the server's words for each pod-visibility value. |
| [`list`](#list) | The keys of a workspace (GET /keys, X-Lium-Workspace-Id when given). |
| [`get`](#get) | One key by id (GET /keys/\{id\}). |
| [`refusals`](#refusals) | The requests this key's budget refused, newest first (GET /keys/\{id\}/refusals — the ledger's. |
| [`revoke`](#revoke) | Revoke a key (DELETE /keys/\{id\}): it stops working at once. Used by lium keys create to take. |
| [`resolve`](#resolve) | A key by name (case-insensitive) or id among the workspace's keys. |
| [`create`](#create) | Mint a key (POST /keys); the secret is in the returned key this once. |
| [`update`](#update) | Set or clear a key's budgets (PATCH /keys/\{id\}; server support pending). |

### scopes_payload

```python
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`](/developers/sdk/reference/exceptions/lium-not-found-error) that names the missing route. A server that answers a bare list is read
as the ``scopes`` list alone.

### scopes

```python
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

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

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

### list

```python
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

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

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

### refusals

```python
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`](/developers/sdk/reference/exceptions/lium-not-found-error)); 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

```python
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

```python
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

```python
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

```python
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.
