Skip to content

Use the Ripple Custody (Wallet) Wallets endpoints to create HSM and MPC wallets inside a vault, retrieve and filter them, update their details, settings, and tags, read a wallet's sequence number, and read fiat-denominated balances for your organization, a vault, or a wallet. To manage wallets in the console instead, see Manage wallets via the console.

Wallet actions

ActionConsole roleConsole procedureAPI procedure
Create a walletOwner, Administrator, ProposerCreate a walletCreate a wallet
View wallet detailsAll rolesGeneral settingsGet a wallet
List walletsAll rolesList walletsList wallets
Update wallet detailsOwner, Administrator, ProposerDetails settingsUpdate a wallet
Enable outgoing transactionsOwner, Administrator, ProposerEnable outgoing transactions from a walletUpdate wallet settings
Turn on raw signingOwner, Administrator, ProposerRaw signingUpdate wallet settings
Freeze deposits by defaultOwner, Administrator, ProposerFreeze transactions by defaultUpdate wallet settings
Enable sweepingOwner, Administrator, ProposerSweeping settingsUpdate wallet settings
Get a wallet's sequence--Get a wallet's sequence
Tag a walletOwner, Administrator, ProposerTag a walletTag a wallet
Check organization balancesAll rolesList vaultsGet organization balances
Check vault balancesAll rolesViewing balancesGet vault balances
Check wallet balancesAll rolesViewing balancesGet wallet balances
Refresh wallet balancesOwner, Administrator, ProposerRefreshing balancesRefresh wallet balances
Delete a failed walletOwner, AdministratorDelete a walletDelete a wallet

Permissions: In the console, owners, administrators, and proposers can create wallets and update wallet settings, and every role can view wallets. See User roles and permissions. The API procedures need an API credential of type WALLETS. See Prerequisites.

Prerequisites

For the base URLs, token lifetime, pagination, filtering, and error format that every endpoint shares, see API conventions.

Create a wallet via the API

API reference: Create a wallet

Send a POST request to /v2/vaults/{vaultId}/wallets. The request requires name, keystore, and blockchain.

FieldDescription
nameRequired. The wallet name.
keystoreRequired. MPC or HSM. HSM wallets are available in sandbox only.
blockchainRequired. The network, for example ETHEREUM, XRP_LEDGER, or SOLANA. For the chains you can create wallets on, see Blockchains and tokens.
quorumIdThe ID of a confirmed MPC quorum. Required for MPC wallets; not used for HSM wallets.
descriptionA description of the wallet's purpose.
keyAlgorithmSECP256K1 or ED25519.
externalIdAn identifier from your own systems. It must be unique within your organization. If it's already in use, the API returns the existing wallet with HTTP 200 instead of creating a new one.
correlationIdAn identifier you can use to correlate this request with related actions.
recoveryPublicKeyOptional. A hex-encoded, PKCS #1-formatted public key of a 4096-bit RSA key pair.
walletTypeWALLET_TYPE_BLOCKCHAIN, the only value. You can omit it. Responses return walletType as WALLET_TYPE_UNSPECIFIED.
curl -X POST https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "USD Issuing wallet",
    "description": "Main USD issuing account used internally",
    "keystore": "MPC",
    "blockchain": "XRP_LEDGER",
    "quorumId": "4f1c2b7e-8d3a-4e6b-9c51-0a2f7d9e3b18"
  }'
{
  "id": "1fc5cd6b-cf4b-4d33-88ce-b6a45e6ba342",
  "vaultId": "ce4918bf-a199-4ce2-85a3-d0d296855384",
  "organizationId": "7c2d9e41-5b8a-4f3c-9d6e-2a1b0c8f4e73",
  "quorumId": "4f1c2b7e-8d3a-4e6b-9c51-0a2f7d9e3b18",
  "createdBy": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "createdAt": "2026-07-23T10:22:22.420Z",
  "updatedAt": "2026-07-23T10:22:22.420Z",
  "name": "USD Issuing wallet",
  "description": "Main USD issuing account used internally",
  "address": "",
  "publicKey": "",
  "keystore": "MPC",
  "blockchain": "XRP_LEDGER",
  "settings": {
    "enabled": false,
    "rawSigningEnabled": false,
    "sweepingEnabled": false,
    "defaultFreezeEnabled": false
  },
  "status": "CREATED",
  "reasons": [],
  "keyAlgorithm": "SECP256K1",
  "walletType": "WALLET_TYPE_UNSPECIFIED"
}
MPC wallets need quorum approval

For an MPC wallet, pass the ID of a quorum in the Confirmed state as quorumId. If you omit quorumId, the request fails with HTTP 400 and reason PAL009.108. Get the ID from the console's Controls section, where the quorum's status must be Confirmed. When you create the wallet, every device in the quorum must approve key generation within 5 minutes. If a device rejects it, Ripple Custody (Wallet) doesn't create the wallet. HSM wallets don't need a quorum, and they return quorumId as 00000000-0000-0000-0000-000000000000.

Provisioning is asynchronous. Poll the wallet until status is PROVISIONED. Until then, address and publicKey are empty strings. If status is PROVISIONING_FAILED, check the reasons array.

New wallets are deposit-only

A new wallet has settings.enabled set to false, so it can receive funds but can't send them. Before a wallet can send, it needs a transaction policy, an address book entry for the destination, and outgoing transactions enabled. See Enable outgoing transactions from a wallet.

Get a wallet via the API

API reference: Get a wallet, Get a wallet by ID

Send a GET request to /v2/vaults/{vaultId}/wallets/{walletId}, or to /v2/wallets/{id} when you know only the wallet ID. Both return the wallet object.

curl https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN"

List wallets via the API

API reference: List vault wallets, List vault wallets with a request body, List organization wallets, List organization wallets with a request body

Send a GET request to /v2/vaults/{vaultId}/wallets to list the wallets in a vault, or to /v2/wallets to list every wallet in your organization. Both accept these query parameters:

  • search: a case-insensitive match over wallet ID, name, address, alias, external ID, and correlation ID.
  • Field filters on id, vaultId, name, address, alias, externalId, and correlationId, using the operators eq, notEq, contains, startsWith, endsWith, in, notIn, and isNull. For example, filter.name.contains=issuing.
  • filter.blockchain.eq, .notEq, .in, and .notIn, which take blockchain values such as XRP_LEDGER.
  • filter.status, which takes a single wallet status such as PROVISIONED. It has no operators: filter.status.eq returns HTTP 400.
  • Timestamp filters on createdAt and updatedAt, such as filter.createdAt.after.
  • pagination.pageSize (default 50, maximum 1,000) and pagination.pageToken.
  • pagination.orderBy (name, address, blockchain, status, created_at, or updated_at) and pagination.order (SORT_ORDER_ASC or SORT_ORDER_DESC).

The filters you set are combined with AND.

curl "https://api.sandbox.palisade.co/v2/wallets?filter.blockchain.eq=XRP_LEDGER&filter.status=PROVISIONED" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "filter": { "total": 1 },
  "wallets": [
    {
      "id": "1fc5cd6b-cf4b-4d33-88ce-b6a45e6ba342",
      "vaultId": "ce4918bf-a199-4ce2-85a3-d0d296855384",
      "organizationId": "7c2d9e41-5b8a-4f3c-9d6e-2a1b0c8f4e73",
      "quorumId": "4f1c2b7e-8d3a-4e6b-9c51-0a2f7d9e3b18",
      "createdBy": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
      "createdAt": "2026-07-23T10:22:22.420Z",
      "updatedAt": "2026-07-23T10:24:05.112Z",
      "name": "USD Issuing wallet",
      "description": "Main USD issuing account used internally",
      "address": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
      "publicKey": "025eb9c81a436bd69f5d8b79b52b82c4b2cdf21bdd68200a967559930fec60b929",
      "keystore": "MPC",
      "blockchain": "XRP_LEDGER",
      "settings": {
        "enabled": false,
        "rawSigningEnabled": false,
        "sweepingEnabled": false,
        "defaultFreezeEnabled": false
      },
      "status": "PROVISIONED",
      "reasons": [],
      "keyAlgorithm": "SECP256K1",
      "walletType": "WALLET_TYPE_UNSPECIFIED"
    }
  ]
}

To fetch the next page, pass the filter.nextPageToken value as pagination.pageToken. Pages after the first also include filter.previousPageToken. For complex filters, send the same search, filter, and pagination options as a JSON body in a POST request to /v2/vaults/{vaultId}/wallets:list or /v2/wallets:list.

Update a wallet via the API

API reference: Update a wallet

Send a PUT request to /v2/vaults/{vaultId}/wallets/{walletId} to change the wallet's name and description. The request requires name, even if you're only changing the description. The update replaces both fields: if you omit description, the update clears the wallet's existing description, so send the current description when you change only the name. You can also pass an optional correlationId; if you omit it, the wallet keeps its existing correlationId.

curl -X PUT https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "USD Issuing wallet",
    "description": "Primary USD issuing account"
  }'

The response is the updated wallet object.

Update wallet settings via the API

API reference: Update a wallet's settings

Send a PUT request to /v2/vaults/{vaultId}/wallets/{walletId}/settings. The request replaces all four settings: any setting you omit from the settings object is set to false. Send the full settings object, with the current values of the settings you aren't changing, even when you change only one value.

SettingControls
enabledWhether the wallet can send outgoing transactions.
rawSigningEnabledWhether the wallet can sign raw transactions.
sweepingEnabledWhether the wallet is a source for asset sweeping.
defaultFreezeEnabledWhether inbound transactions are frozen by default.
curl -X PUT https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/settings \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "settings": {
      "enabled": true,
      "rawSigningEnabled": true,
      "sweepingEnabled": false,
      "defaultFreezeEnabled": false
    }
  }'

The response is the updated wallet object.

Get a wallet's sequence via the API

API reference: Get a wallet nonce/sequence

Send a GET request to /v2/vaults/{vaultId}/wallets/{walletId}/sequence to read the wallet's current blockchain nonce or sequence number. This is useful when you build raw transactions. The value is a string, and it's "0" for an account that has no on-chain history. For a wallet that isn't provisioned, the request fails with HTTP 400 and reason PAL009.106.

curl https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/sequence \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{ "sequence": "2" }

Delete a wallet via the API

API reference: Delete a wallet

Send a DELETE request to /v2/vaults/{vaultId}/wallets/{walletId}. You can delete only a wallet whose status is PROVISIONING_FAILED; you can't delete a provisioned wallet. A successful response is an empty JSON object.

curl -X DELETE https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Tag a wallet via the API

API reference: Add a wallet tag, List wallet tags, List wallet tags in a vault, List all wallet tags, Delete a wallet tag

Tags are free-form labels for grouping and finding wallets. Adding a wallet tag needs key:update, listing needs key:read, and deleting one needs key:delete. A WALLETS credential without key:delete can add and list tags but gets 403 (PAL000.002) when it deletes one.

Add a tag with a POST request to /v2/vaults/{vaultId}/wallets/{walletId}/tags; the request requires tag. List a wallet's tags with a GET request to the same path, and remove a tag with a DELETE request that passes it in the required tag query parameter. To see the tags of every wallet in a vault, send a GET request to /v2/vaults/{vaultId}/wallets/tags, or to /v2/tags for every wallet tag in your organization.

curl -X POST https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/tags \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "tag": "Issuing wallet" }'

The response lists the wallet's tags after the change:

[
  {
    "walletId": "1fc5cd6b-cf4b-4d33-88ce-b6a45e6ba342",
    "vaultId": "ce4918bf-a199-4ce2-85a3-d0d296855384",
    "tags": ["Issuing wallet"]
  }
]

A successful DELETE returns an empty JSON object.

Check balances via the API

Use the Balances endpoints to read fiat-denominated balances at three levels: your whole organization, a single vault, or a single wallet with a per-asset breakdown. To learn how Ripple Custody (Wallet) calculates and displays balances, see Understanding balances.

All three endpoints accept an optional currencyCode query parameter that sets the fiat currency for the values. If you omit it, Ripple Custody (Wallet) uses USD. Currently USD is the only supported value.

Balances and fiat values are decimal strings. Fiat values can carry many decimal places, for example "28.4000000000000000000000000000000000000000000000000000000000000000000000000002", so round them before you display them.

Get organization balances via the API

API reference: Get organization balances

Send a GET request to /v2/balances for the aggregated fiat value of your organization, broken down by vault. Vaults with no value can appear with an aggregatedFiatValue of "0".

curl "https://api.sandbox.palisade.co/v2/balances?currencyCode=USD" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "currencyCode": "USD",
  "aggregatedFiatValue": "100.00",
  "balances": [
    {
      "vaultId": "ce4918bf-a199-4ce2-85a3-d0d296855384",
      "aggregatedFiatValue": "100.00"
    }
  ]
}

Get vault balances via the API

API reference: Get vault balances

Send a GET request to /v2/vaults/{vaultId}/balances for the aggregated fiat value of one vault, broken down by wallet.

curl https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/balances \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "currencyCode": "USD",
  "aggregatedFiatValue": "100.00",
  "balances": [
    {
      "walletId": "1fc5cd6b-cf4b-4d33-88ce-b6a45e6ba342",
      "aggregatedFiatValue": "100.00"
    }
  ]
}

Get wallet balances via the API

API reference: Get wallet balances

Send a GET request to /v2/vaults/{vaultId}/wallets/{walletId}/balances for a per-asset breakdown. Each entry shows:

  • balance: the total on-chain balance. When the breakdown fields are present, it equals availableBalance + pendingBalance + frozenBalance.
  • availableBalance: the balance you can spend.
  • pendingBalance: the balance tied up in pending transactions.
  • frozenBalance: the balance frozen by policy actions.
  • rate: the exchange rate between the asset and currencyCode.
  • fiatValue: the asset's value in currencyCode.
curl https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/balances \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "currencyCode": "USD",
  "aggregatedFiatValue": "100.00",
  "balances": [
    {
      "asset": {
        "id": "3::XRP",
        "standard": "NATIVE",
        "symbol": "XRP",
        "name": "XRP",
        "blockchain": "XRP_LEDGER",
        "decimals": 6,
        "vetted": false,
        "enabled": true,
        "contract": "",
        "createdAt": null,
        "source": "ASSET_SOURCE_UNSPECIFIED",
        "syncVersion": 0,
        "iconUrl": "https://static.palisade.co/registry/assets/coingecko/ripple.png",
        "displaySymbol": "XRP"
      },
      "balance": "200",
      "rate": "0.5",
      "fiatValue": "100",
      "availableBalance": "150",
      "pendingBalance": "30",
      "frozenBalance": "20"
    }
  ],
  "pagination": null
}

Use asset.displaySymbol when you show the symbol to users. It keeps the capitalization the asset's source uses, for example weETH.

Filter, search, and page wallet balances via the API

The wallet balances endpoint also accepts these optional query parameters:

  • filter.blockchain, filter.standard, and filter.source, each with the operators eq, notEq, in, and notIn. Standards are NATIVE, ERC20, ISSUED_CURRENCY, ERC721, SPL, and CUSTOM. Sources are ASSET_SOURCE_LEGACY, ASSET_SOURCE_AUTO, ASSET_SOURCE_COINGECKO, ASSET_SOURCE_PALISADE, and ASSET_SOURCE_CUSTOMER; for example, filter.source.eq=ASSET_SOURCE_CUSTOMER returns only your organization's custom asset entries. The filter matches each asset's resolved source, so a balance can match filter.source even when an unfiltered response shows its asset.source as ASSET_SOURCE_UNSPECIFIED. ASSET_SOURCE_UNSPECIFIED isn't a valid filter value.
  • filter.contract and filter.symbol, with the operators eq, notEq, in, notIn, contains, startsWith, endsWith, and isNull. eq is case-sensitive; contains, startsWith, and endsWith aren't. To return native assets only, set filter.contract.isNull=true or filter.standard.in=NATIVE. Native assets match filter.contract.isNull=true even though the response shows contract as an empty string.
  • search: a case-insensitive match over asset ID, symbol, name, contract address, blockchain value (such as XRP_LEDGER), source label (such as coingecko), and standard label (such as native).
  • pagination.pageSize (default 50, maximum 1,000), pagination.pageToken, pagination.orderBy (symbol, name, blockchain, contract_address, source, or standard), and pagination.order (SORT_ORDER_ASC or SORT_ORDER_DESC).
  • refreshRegistryMetadata: when true, bypasses cached registry metadata for this wallet's assets. If registry resolution fails, the request fails. Use it only for a read immediately after you change the asset registry.

A balance must match every filter you set, and search if you set it. Setting any pagination parameter turns on paging, and the response then includes a pagination object with total and, when there are more pages, page tokens. Without paging, pagination is null. aggregatedFiatValue always covers every matching balance, not only the current page, and is "0" when nothing matches. For a full example, see Filter, search, and page balances.

curl "https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/balances?filter.standard.eq=ERC20&pagination.pageSize=20&pagination.orderBy=symbol" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Refresh wallet balances via the API

API reference: Sync wallet balances

Balances update automatically. To trigger a refresh, send a POST request to /v2/vaults/{vaultId}/wallets/{walletId}/balances/sync. The request takes no body, and a successful response is an empty JSON object.

curl -X POST https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/balances/sync \
  -H "Authorization: Bearer $ACCESS_TOKEN"

A refresh syncs only assets that Ripple Custody (Wallet) already tracks for the wallet. It doesn't discover new tokens that the wallet received but Ripple Custody (Wallet) doesn't yet track.

Errors

Failed requests return an HTTP error status and an error object with code, message, and details fields. See Error codes. For the causes of and fixes for the errors these endpoints return, see Troubleshoot common errors.

Next steps