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. To manage the address book in the console instead, see Manage address book via the console.
| Action | Console role | Console procedure | API procedure |
|---|---|---|---|
| Create a counterparty | Owner, Administrator | Create a counterparty | Create a counterparty |
| List and get counterparties | All except Viewer | List and get counterparties | List and get counterparties |
| Update a counterparty | - | - | Update a counterparty |
| Add an address | Owner, Administrator | Add an address | Add an address to a counterparty |
| List addresses | All except Viewer | List addresses | List addresses |
| Delete an address | Owner, Administrator | Delete a counterparty or address | Get or delete an address |
| Delete a counterparty | Owner, Administrator | Delete a counterparty or address | Delete a counterparty |
| Require approval for new addresses | Owner, Administrator | Require approval for new entries | - |
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. The API procedures need an API credential of type CONTROLS. See Prerequisites.
- An API credential of type
CONTROLS. This credential type covers counterparties, address book entries, and policy rules. See API credentials overview and Manage API credentials. - An access token. Exchange your credential's
clientIdandclientSecretfor a token. See Getting started with the API.
For the base URLs, token lifetime, pagination, filtering, and error format that every endpoint shares, see API conventions.
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.
API reference: Create counterparties
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. |
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.
{
"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
}API reference: List counterparties, List counterparties with a request body, Get counterparties
List the counterparties in your organization:
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) andpageToken. Passfilter.nextPageTokenfrom the response as the nextpageToken. - Filters:
filter.typetakesORGANIZATION,INDIVIDUAL, orDAPP.filter.id,filter.name,filter.description,filter.createdAt, andfilter.updatedAttake an operator, for examplefilter.name.contains=acme. - Search:
searchmatches 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:
curl https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID \
-H "Authorization: Bearer $ACCESS_TOKEN"API reference: Update counterparties
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.
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.
API reference: Create addresses
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. |
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:
{
"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.
API reference: List counterparty addresses, List counterparty addresses with a request body, List organization addresses, List organization addresses with a request body
To list the addresses that belong to one counterparty:
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:
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:
pageSizeandpageToken. The organization-level list returns up to 1,000 addresses for each page. - Filters:
filter.statustakes one address status, for exampleENABLED.filter.addressId,filter.counterpartyId,filter.address,filter.name,filter.description,filter.active,filter.blockchain,filter.createdAt, andfilter.updatedAttake an operator, for examplefilter.counterpartyId.eq=<id>. - Search:
searchmatches 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.
API reference: Get addresses, Delete addresses
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.
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"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.
API reference: Delete counterparties
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.
curl -X DELETE https://api.sandbox.palisade.co/v2/counterparties/$COUNTERPARTY_ID \
-H "Authorization: Bearer $ACCESS_TOKEN"