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

# Address Book

> Manage the organization withdrawal address whitelist via the API.

The address book is an organization-level whitelist of withdrawal destinations. Enforcement is **implicit**: as soon as the address book has at least one entry, every withdrawal from the organization must pay out to an address in the book — requests to any other destination are rejected with `address_book_whitelist_violation` (HTTP 403). An empty address book means withdrawals are unrestricted.

There is no separate enforcement toggle, no status endpoint, and no label editing — the list of entries is the single source of truth. To know whether the whitelist is active, list the entries: a non-empty list means enforcement is on.

<Note>
  **Roles.** Anyone in the organization can read the address book. All writes (adding and deleting entries) require the acting profile to be an organization **owner** or **admin**. Requests by other members fail with `forbidden` (HTTP 403).
</Note>

Key behaviors, enforced server-side:

* **Implicit enforcement** — adding the first entry turns enforcement on; deleting the last entry turns it off.
* **Hard delete** — removing an entry deletes it permanently. Deleting the last entry is allowed and lifts all withdrawal restrictions for the organization.
* **Uniqueness** — one entry per `(chain, address)` pair. EVM addresses are matched case-insensitively; Solana addresses are matched exactly.
* **Immutable entries** — `address`, `chain`, and `label` are set at creation and cannot be changed. To change a destination or its label, delete the entry and create a new one.

Supported chains: `ethereum`, `ethereum_sepolia`, `polygon`, `arbitrum`, `base`, `solana`, `solana_devnet`.

The full surface is three endpoints: list, create, and delete.

## List entries

The entry list is the only read. Derive enforcement from it: the whitelist is active exactly when the list is non-empty.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X GET "$BASE_URL/v2/address-book/entries?limit=100" \
  -H "Authorization: Bearer $API_TOKEN"
```

Entries are returned newest first. The response uses the same cursor pagination as other list endpoints — pass `nextCursor` back as `cursor` to fetch the next page (`limit` max 200).

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "entries": [
    {
      "id": "a1b2c3d4-0000-4000-8000-000000000001",
      "organizationId": "0a1b2c3d-0000-4000-8000-000000000000",
      "address": "0x52908400098527886E0F7030069857D2E4169EE7",
      "chain": "arbitrum",
      "label": "Ops treasury",
      "addedBy": "9f8e7d6c-0000-4000-8000-000000000002",
      "addedAt": "2026-06-09T12:00:00.000Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}
```

## Create an entry

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST "$BASE_URL/v2/address-book/entries" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "0x52908400098527886E0F7030069857D2E4169EE7",
    "chain": "arbitrum",
    "label": "Ops treasury"
  }'
```

`label` must be 1-120 characters. The address format is validated for the given chain (EVM hex format for EVM chains, base58 public key for Solana chains).

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "entry": {
    "id": "a1b2c3d4-0000-4000-8000-000000000001",
    "organizationId": "0a1b2c3d-0000-4000-8000-000000000000",
    "address": "0x52908400098527886E0F7030069857D2E4169EE7",
    "chain": "arbitrum",
    "label": "Ops treasury",
    "addedBy": "9f8e7d6c-0000-4000-8000-000000000002",
    "addedAt": "2026-06-09T12:00:00.000Z"
  }
}
```

Creating a duplicate entry for the same `(chain, address)` fails with `address_book_duplicate_entry` (HTTP 409). If this is the organization's first entry, withdrawal enforcement is now active — subsequent withdrawals must pay out to an address in the book.

## Delete an entry

Permanently removes an address from the whitelist. The response returns the removed entry.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X DELETE "$BASE_URL/v2/address-book/entries/$ENTRY_ID" \
  -H "Authorization: Bearer $API_TOKEN"
```

<Warning>
  Deleting the **last** entry is allowed and implicitly turns withdrawal enforcement off — withdrawals to any destination will be accepted until a new entry is added.
</Warning>

## Error reference

| Code                               | HTTP | Meaning                                                                                                   |
| ---------------------------------- | ---- | --------------------------------------------------------------------------------------------------------- |
| `validation_error`                 | 400  | Missing/invalid fields (e.g. label length, invalid id).                                                   |
| `unsupported_chain`                | 400  | `chain` is not in the supported chain list.                                                               |
| `invalid_destination_address`      | 400  | Address format is invalid for the given chain.                                                            |
| `forbidden`                        | 403  | Acting profile is not an organization owner or admin.                                                     |
| `address_book_entry_not_found`     | 404  | Entry does not exist for this organization.                                                               |
| `address_book_duplicate_entry`     | 409  | An entry already exists for this `(chain, address)`.                                                      |
| `address_book_whitelist_violation` | 403  | Returned by withdrawal creation when the address book has entries and the destination is not one of them. |

See [Withdraw Funds](/docs/portfolio-wallets/withdraw-funds) for how enforcement applies to withdrawal creation.
