---
title: Wallet
description: Read the account wallet, set its budget, add credit and page through the ledger. Every amount is a decimal string.
---

The wallet is account-wide: it belongs to your organisation when you are a
member of one, and to you otherwise. Sessions reserve from it while they run and
settle what they spend.

!!! info "No payment integration"
    Adding credit is an administrative action. Ledger entries record
    `payment_provider: null`; nothing here is a purchase.

A new wallet starts with `enforced: false` and keeps per-session budgets until
the owner sets a budget or adds credit.

## Get the wallet

`GET`{ .get } `/developer/account/wallet`
{ .endpoint }

```jsonc title="200 OK · DeveloperCreditAccountRead"
{
  "id": "3f6c…",
  "owner_kind": "client",        // "client" or "user"
  "owner_id": "a41e…",
  "currency": "USD",
  "budget_usd": "200.000000",
  "reserved_usd": "10.000000",
  "spent_usd": "18.250000",
  "available_usd": "171.750000", // budget − reserved − spent
  "enforced": true,
  "version": 3,
  "created_at": "2026-09-01T08:12:44Z",
  "updated_at": "2026-09-26T17:03:10Z"
}
```

Show `available_usd` to people, not a per-session cap.

## Set the budget

`PUT`{ .put } `/developer/account/wallet`
{ .endpoint }

Sets the **total** budget — not a delta. The new budget cannot be lower than
`spent_usd + reserved_usd`.

<div class="params" markdown>

`budget_usd` `string`{ .type } **required**{ .required }
:   The new total budget, as a decimal string: `"200.00"`.

`idempotency_key` `string`{ .type } **required**{ .required }
:   Unique per logical action, up to 255 characters. Reuse it when retrying the
    same action.

`expected_version` `integer`{ .type } *optional*{ .optional }
:   The `version` you last read. Omit it on the first write.

`note` `string`{ .type } *optional*{ .optional }
:   Recorded on the ledger entry.

</div>

```json title="Request"
{
  "budget_usd": "200.00",
  "idempotency_key": "budget-2026-09-27-7f3a",
  "expected_version": 2,
  "note": "Q4 engineering budget"
}
```

| Status | Meaning |
|---|---|
| `200` | Updated. The body is the new wallet. |
| `409` | Version conflict, or the budget is below what is already committed. |
| `422` | Validation failed. |
| `503` | The execution account is temporarily unavailable. Retry with backoff. |

## Add credit

`POST`{ .post } `/developer/account/wallet/credits`
{ .endpoint }

Adds an amount to the current budget.

<div class="params" markdown>

`amount_usd` `string`{ .type } **required**{ .required }
:   The amount to add, as a decimal string.

`idempotency_key` `string`{ .type } **required**{ .required }
:   As above.

`note` `string`{ .type } *optional*{ .optional }
:   Recorded on the ledger entry.

</div>

## List ledger entries

`GET`{ .get } `/developer/account/wallet/ledger`
{ .endpoint }

Newest first. Page backwards with the last entry's `id` as `before`.

<div class="params" markdown>

`before` `uuid`{ .type } *optional*{ .optional }
:   Return entries older than this entry. An unknown id returns `404`.

`limit` `integer`{ .type } *optional*{ .optional }
:   1–500. Default `100`.

</div>

Each entry has an `id`, a `kind`, the `amount_usd`, the wallet balances after
it (`budget_after_usd`, `reserved_after_usd`, `spent_after_usd`,
`available_after_usd`) and, where relevant, the session and task it belongs to.

| `kind` | Written when |
|---|---|
| `budget_set` | The total budget changes. |
| `credit_added` | Credit is added. |
| `reserve` | A session reserves funds before running. |
| `reserve_release` | Unused reservation is returned. |
| `spend` | Work is settled. |
