# Manage the address book via the API

This guide shows you how to create and maintain counterparties and their blockchain addresses through the Ripple Custody (Wallet) API. Counterparties represent the organizations, individuals, and dApps you transact with. Addresses are the on-chain destinations that belong to them. For address book concepts, see [Address book overview](/pt-br/products/wallet/governance-and-controls/address-book). To manage the address book in the console instead, see [Manage address book via the console](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book).

## Address book actions

| Action | Console role | Console procedure | API procedure |
|  --- | --- | --- | --- |
| Create a counterparty | Owner, Administrator | [Create a counterparty](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book#create-a-counterparty-via-the-console) | [Create a counterparty](#create-a-counterparty-via-the-api) |
| List and get counterparties | All except Viewer | [List and get counterparties](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book#list-and-get-counterparties-via-the-console) | [List and get counterparties](#list-and-get-counterparties-via-the-api) |
| Update a counterparty | - | - | [Update a counterparty](#update-a-counterparty-via-the-api) |
| Add an address | Owner, Administrator | [Add an address](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book#add-an-address-via-the-console) | [Add an address to a counterparty](#add-an-address-to-a-counterparty-via-the-api) |
| List addresses | All except Viewer | [List addresses](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book#list-addresses-via-the-console) | [List addresses](#list-addresses-via-the-api) |
| Delete an address | Owner, Administrator | [Delete a counterparty or address](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book#delete-a-counterparty-or-address-via-the-console) | [Get or delete an address](#get-or-delete-an-address-via-the-api) |
| Delete a counterparty | Owner, Administrator | [Delete a counterparty or address](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book#delete-a-counterparty-or-address-via-the-console) | [Delete a counterparty](#delete-a-counterparty-via-the-api) |
| Require approval for new addresses | Owner, Administrator | [Require approval for new entries](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book#require-approval-for-new-entries-via-the-console) | - |


**Permissions:** In the console, owners and administrators can create, update, and delete counterparties and addresses. Owners, administrators, proposers, and approvers can approve addresses. See [User roles and permissions](/pt-br/products/wallet/organization-and-access/users-and-roles#addresses). The API procedures need an API credential of type `CONTROLS`. See [Prerequisites](#prerequisites).

## Prerequisites

- **An API credential of type `CONTROLS`.** This credential type covers counterparties, address book entries, and policy rules. See [API credentials overview](/pt-br/products/wallet/organization-and-access/api-credentials) and [Manage API credentials](/pt-br/products/wallet/organization-and-access/api-credentials/manage-api-credentials).
- **An access token.** Exchange your credential's `clientId` and `clientSecret` for a token. See [Getting started with the API](/pt-br/products/wallet/get-started/use-the-api#step-2-authenticate).


For the base URLs, token lifetime, pagination, filtering, and error format that every endpoint shares, see [API conventions](/pt-br/products/wallet/api-and-developer-experience/api-conventions).

Address approval happens in the console
If your organization has an **Addresses** approval group, an address that you add through the API has status `CREATION_APPROVAL_PENDING` and `active: false` until approvers approve it in the console. See [Configure approval flows](/pt-br/products/wallet/governance-and-controls/approvals/configure-approval-flows).

## Create a counterparty via the API

**API reference:** [Create counterparties](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/counterparties/counterpartyservice_createcounterparty)

Send a `POST` request to `/v2/counterparties` with a `name` and a `details` object. Set `details.type` to `ORGANIZATION`, `INDIVIDUAL`, or `DAPP`, and include the matching object:

| `details.type` | Object | Required fields |
|  --- | --- | --- |
| `ORGANIZATION` | `organization` | `legalName` (5 to 50 characters). An optional `address` needs `address1`, `city`, `state`, `postCode`, and `country`. |
| `INDIVIDUAL` | `individual` | `firstName` and `lastName` (up to 50 characters each). An optional `address` needs the same fields as for an organization. |
| `DAPP` | `dApp` | None. |


```bash
curl -X POST https://api.sandbox.palisade.co/v2/counterparties \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Treasury",
    "description": "A counterparty used by the treasury department",
    "details": {
      "type": "ORGANIZATION",
      "organization": {
        "legalName": "Acme Financial Ltd",
        "address": {
          "address1": "10 Mayo Road",
          "city": "London",
          "state": "Greater London",
          "postCode": "W1 1AA",
          "country": "United Kingdom"
        }
      }
    }
  }'
```

The response is the new counterparty. Save the `id`, because you need it to add addresses.

```json
{
  "id": "ce4918bf-a199-4ce2-85a3-d0d296855384",
  "organizationId": "a9a1de05-0b19-4fca-8597-1199353bd569",
  "createdBy": "8617b5b5-dfcf-4ffc-9f46-f7cec35a88bd",
  "createdAt": "2026-09-24T12:00:00Z",
  "updatedBy": "8617b5b5-dfcf-4ffc-9f46-f7cec35a88bd",
  "updatedAt": "2026-09-24T12:00:00Z",
  "name": "Acme Treasury",
  "description": "A counterparty used by the treasury department",
  "details": {
    "type": "ORGANIZATION",
    "organization": {
      "legalName": "Acme Financial Ltd",
      "address": {
        "address1": "10 Mayo Road",
        "city": "London",
        "state": "Greater London",
        "postCode": "W1 1AA",
        "country": "United Kingdom"
      }
    }
  },
  "addressCount": 0
}
```

## List and get counterparties via the API

**API reference:** [List counterparties](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/counterparties/counterpartyservice_listcounterparties), [List counterparties with a request body](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/counterparties/counterpartyservice_listcounterparties2), [Get counterparties](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/counterparties/counterpartyservice_getcounterparty)

List the counterparties in your organization:

```bash
curl "https://api.sandbox.palisade.co/v2/counterparties?filter.type=ORGANIZATION&pageSize=50" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

- **Paging:** `pageSize` (default 50, maximum 1,000) and `pageToken`. Pass `filter.nextPageToken` from the response as the next `pageToken`.
- **Filters:** `filter.type` takes `ORGANIZATION`, `INDIVIDUAL`, or `DAPP`. `filter.id`, `filter.name`, `filter.description`, `filter.createdAt`, and `filter.updatedAt` take an operator, for example `filter.name.contains=acme`.
- **Search:** `search` matches the counterparty ID, name, description, and details, without regard to case.


To send the filters in a JSON body instead, use `POST /v2/counterparties:list`.

The response holds the counterparties in a `counterparties` array, each in the same shape as the create response, and a `filter` object with `nextPageToken` and `total`.

To get one counterparty, request it by ID:

```bash
curl https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

## Update a counterparty via the API

**API reference:** [Update counterparties](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/counterparties/counterpartyservice_updatecounterparty)

Send a `PUT` request with the new `name`, which is required, and an optional `description`. You can't change `details` through the API: if you include `details`, Ripple Custody (Wallet) ignores it.

```bash
curl -X PUT https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Treasury",
    "description": "Updated description for the treasury team"
  }'
```

The response is the updated counterparty.

## Add an address to a counterparty via the API

**API reference:** [Create addresses](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/addresses/counterpartyservice_createaddress)

Send a `POST` request to `/v2/counterparties/{counterpartyId}/addresses`:

| Field | Required | Description |
|  --- | --- | --- |
| `termsAndConditionsAccepted` | Yes | Set to `true` to confirm that the ownership information you submit is correct. |
| `details.type` | Yes | Set to `EXTERNAL`. |
| `details.externalAddress.address` | Yes | The on-chain address. For an XRP Ledger address with a destination tag, append the tag after a colon, for example `rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH:12345`. |
| `details.externalAddress.name` | Yes | A name for the address. |
| `details.externalAddress.blockchains` | Yes | One or more blockchains that the address supports, for example `["ETHEREUM"]`. |
| `details.externalAddress.description` | No | A description of the address. |
| `custodian` | No | For a custodial address, such as one held at an exchange, the custodian's `name` and decentralized identifier `dId`. Both are required if you include `custodian`. |


```bash
curl -X POST https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID/addresses \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "termsAndConditionsAccepted": true,
    "details": {
      "type": "EXTERNAL",
      "externalAddress": {
        "address": "0x55502b9d5a68b0F8a48384352295BeD968aD8AA4",
        "name": "Treasury",
        "description": "Wallet used to store treasury funds",
        "blockchains": ["ETHEREUM"]
      }
    }
  }'
```

If the address isn't valid on every blockchain in `blockchains`, the request fails with `PAL013.015` ("address is not compatible with one or more selected blockchains").

The response is the new address. If you don't send `custodian`, the response holds it with empty values. Its `status` and `active` fields show whether you can send to it yet:

```json
{
  "addressId": "019d0624-b5d7-77cf-8eee-b72ceac0f71e",
  "counterpartyId": "ce4918bf-a199-4ce2-85a3-d0d296855384",
  "organizationId": "a9a1de05-0b19-4fca-8597-1199353bd569",
  "createdBy": "8617b5b5-dfcf-4ffc-9f46-f7cec35a88bd",
  "createdAt": "2026-09-24T12:05:00Z",
  "updatedBy": "8617b5b5-dfcf-4ffc-9f46-f7cec35a88bd",
  "updatedAt": "2026-09-24T12:05:00Z",
  "custodian": {
    "name": "",
    "dId": ""
  },
  "termsAndConditionsAccepted": true,
  "details": {
    "type": "EXTERNAL",
    "externalAddress": {
      "address": "0x55502b9d5a68b0F8a48384352295BeD968aD8AA4",
      "name": "Treasury",
      "description": "Wallet used to store treasury funds",
      "blockchains": ["ETHEREUM"]
    }
  },
  "status": "CREATION_APPROVAL_PENDING",
  "active": false
}
```

Address details are also subject to compliance checks, so an address can pass through `COMPLIANCE_PENDING` before it's available. When the address is ready to use, `status` is `ENABLED` and `active` is `true`.

## List addresses via the API

**API reference:** [List counterparty addresses](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/addresses/counterpartyservice_listaddresses), [List counterparty addresses with a request body](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/addresses/counterpartyservice_listaddresses2), [List organization addresses](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/addresses/counterpartyservice_listglobaladdresses), [List organization addresses with a request body](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/addresses/counterpartyservice_listglobaladdresses2)

To list the addresses that belong to one counterparty:

```bash
curl "https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID/addresses?pageSize=100" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

This list returns up to 100 addresses for each page. To send the filters in a JSON body instead, use `POST /v2/counterparties/{counterpartyId}/addresses:list`.

To search across every counterparty, list addresses at the organization level:

```bash
curl "https://api.sandbox.palisade.co/v2/addresses?filter.blockchain.eq=ETHEREUM&filter.active.eq=true" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

Both lists support these query parameters:

- **Paging:** `pageSize` and `pageToken`. The organization-level list returns up to 1,000 addresses for each page.
- **Filters:** `filter.status` takes one address status, for example `ENABLED`. `filter.addressId`, `filter.counterpartyId`, `filter.address`, `filter.name`, `filter.description`, `filter.active`, `filter.blockchain`, `filter.createdAt`, and `filter.updatedAt` take an operator, for example `filter.counterpartyId.eq=<id>`.
- **Search:** `search` matches the address ID, on-chain address, name, and description, without regard to case.


The organization-level list also takes an `address` parameter to look up an on-chain address. To send the filters in a JSON body instead, use `POST /v2/addresses:list`.

Both lists return an `addresses` array of address objects in the same shape as the create response, and a `filter` object with `nextPageToken` and `total`.

## Get or delete an address via the API

**API reference:** [Get addresses](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/addresses/counterpartyservice_getaddress), [Delete addresses](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/addresses/counterpartyservice_deleteaddress)

Get or delete an address by its counterparty ID and address ID. The address must belong to that counterparty: otherwise a get returns `PAL013.012` ("address not found") and a delete returns `PAL013.021`. A delete request returns an empty JSON object as soon as Ripple Custody (Wallet) accepts it. If your organization has an **Addresses** approval group, the deletion waits for approval: the address keeps `active: true` with status `DELETION_APPROVAL_PENDING` until approvers approve it in the console. Get the address to check whether the deletion has completed.

```bash
curl https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID/addresses/$ADDRESS_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN"

curl -X DELETE https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID/addresses/$ADDRESS_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

Check policies before you delete
A policy rule that references a deleted address or counterparty in a matcher no longer matches any transaction. If it's the only rule for that asset, transfers that it covered are blocked. See [Policy reference](/pt-br/products/wallet/governance-and-controls/policies/policy-reference#matchers).

## Delete a counterparty via the API

**API reference:** [Delete counterparties](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/counterparties/counterpartyservice_deletecounterparty)

Deleting a counterparty removes it from your address book. Delete all of the counterparty's addresses first, because you can't delete a counterparty that still has addresses. A successful delete returns an empty JSON object.

```bash
curl -X DELETE https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

## Related documentation

- [Address book overview](/pt-br/products/wallet/governance-and-controls/address-book)
- [Manage address book via the console](/pt-br/products/wallet/governance-and-controls/address-book/manage-address-book)
- [Manage policy rules via the API](/pt-br/products/wallet/governance-and-controls/policies/manage-policies-api)
- [Ripple Custody (Wallet) API reference](/pt-br/products/wallet/api-docs/palisade-api/palisade-api)