This guide shows you how to use the Ripple Custody (Wallet) API to freeze an incoming transaction, so that its funds move to the wallet's frozen balance, and to unfreeze it, so that the funds become available again. For how freeze controls work, freeze types, and automatic freeze, see Configure transaction freeze controls.
| Action | Console role | Console procedure | API procedure |
|---|---|---|---|
| Freeze deposits by default | Owner, Administrator, Proposer | Enable automatic freeze on a wallet | Update wallet settings |
| Freeze a transaction | Owner, Administrator, Auditor | Freeze an individual transaction | Freeze a transaction |
| Unfreeze a transaction | Owner, Administrator, Auditor | Unfreeze a transaction | Unfreeze a transaction |
| Check frozen funds | All roles | Monitor frozen balances | Check freeze state |
Permissions: In the console, owners, administrators, and auditors can freeze and unfreeze transactions. Owners, administrators, and proposers can turn on freeze by default, which is a wallet setting. See User roles and permissions. Freezing and unfreezing through the API needs an API credential of type TRANSACTIONS. Changing wallet settings through the API needs a WALLETS credential.
- An API credential of type
TRANSACTIONS. This credential type covers creating and managing transactions, including freezing and unfreezing them. See API credentials overview and Manage API credentials. - An access token. Exchange your credential's
clientIdandclientSecretfor a token. See Getting started with the API. - An incoming transaction. You need its
vaultId,walletId, and transactionid. To find deposits, list the wallet's transactions withGET /v2/vaults/{vaultId}/wallets/{walletId}/transactions. See List transactions, and List wallet transactions in the API reference.
For the base URLs, token lifetime, pagination, filtering, and error format that every endpoint shares, see API conventions.
API reference: Freeze a transaction
Send a PUT request to the transaction's freeze path. The request has no body. Pass the required reason as a URL-encoded query parameter. Ripple Custody (Wallet) records the reason in the freeze history.
curl -X PUT "https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/transactions/$TRANSACTION_ID/freeze?reason=AML%20review&mutationId=$MUTATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"mutationId is optional. Set it to a UUID that you generate to make the request safe to retry. If the request fails or times out, retry it with the same mutationId and the same reason: the API returns the transaction in its current state and doesn't add another history entry. If you omit mutationId, Ripple Custody (Wallet) generates one. A mutationId that isn't a UUID, or a missing reason, fails with PAL000.020 ("invalid request"). Reusing a mutationId with a different reason, or for the opposite action, fails with HTTP 500 and PAL000.019.
Freezing a transaction that's already frozen, or unfreezing one that isn't frozen, succeeds: Ripple Custody (Wallet) adds a history entry and increases freezeRevision.
If the transaction can't be frozen, for example because it's a rejected outgoing transaction, the request fails with PAL010.008 ("cannot freeze/unfreeze transaction").
The response is the full transaction. This excerpt shows its freezeInfo object, in place in the transaction, which holds the current freeze state and the history of freeze and unfreeze actions:
{
"freezeInfo": {
"isFrozen": true,
"authority": "FREEZE_AUTHORITY_CUSTOMER_MANUAL",
"freezeRevision": "1",
"mutationId": "5b0e3c1a-7d2f-4e8a-9c61-2f4d8b7a0e93",
"history": [
{
"id": "ce4918bf-a199-4ce2-85a3-d0d296855384",
"action": "FREEZE_ACTION_FREEZE",
"reason": "AML review",
"userId": "7f2a1b0c-9d8e-4f3a-b2c1-0d9e8f7a6b5c",
"organizationId": "a9a1de05-0b19-4fca-8597-1199353bd569",
"performedAt": "2026-10-05T10:22:22.420Z",
"freezeType": "FREEZE_TYPE_MANUAL",
"authority": "FREEZE_AUTHORITY_CUSTOMER_MANUAL",
"mutationId": "5b0e3c1a-7d2f-4e8a-9c61-2f4d8b7a0e93",
"freezeRevision": "1"
}
]
}
}The freeze takes effect when Ripple Custody (Wallet) confirms the request, and the wallet's balances reflect it straight away. The wallet's frozenBalance holds the transaction's full amount, even if the wallet has already spent part of those funds, so availableBalance can be negative while the transaction is frozen.
API reference: Unfreeze a transaction
Send a PUT request to the transaction's unfreeze path, with the required reason and an optional mutationId:
curl -X PUT "https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/transactions/$TRANSACTION_ID/unfreeze?reason=Reviewed%20and%20cleared&mutationId=$MUTATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"Use a new mutationId for each freeze or unfreeze. Reuse a value only to retry the same request.
You can unfreeze a transaction whatever froze it, including the wallet's Freeze transactions by default setting, a Travel Rule check, or Ripple. A manual unfreeze stays in place even if an automatic process would later freeze the transaction again. For the full rules, see Freeze types and who can change them.
The response is the full transaction, with freezeInfo.isFrozen set to false and a FREEZE_ACTION_UNFREEZE entry added at the start of freezeInfo.history. This excerpt shows its freezeInfo object, in place in the transaction:
{
"freezeInfo": {
"isFrozen": false,
"authority": "FREEZE_AUTHORITY_CUSTOMER_MANUAL",
"freezeRevision": "2",
"mutationId": "0c8f2a6e-1b3d-4f7a-8e5c-9d2b4a6f1e07",
"history": [
{
"id": "3e7a9c2b-5f1d-4a8e-b6c0-7d2f9e4a1b58",
"action": "FREEZE_ACTION_UNFREEZE",
"reason": "Reviewed and cleared",
"userId": "7f2a1b0c-9d8e-4f3a-b2c1-0d9e8f7a6b5c",
"organizationId": "a9a1de05-0b19-4fca-8597-1199353bd569",
"performedAt": "2026-10-05T11:05:41.002Z",
"freezeType": "FREEZE_TYPE_MANUAL",
"authority": "FREEZE_AUTHORITY_CUSTOMER_MANUAL",
"mutationId": "0c8f2a6e-1b3d-4f7a-8e5c-9d2b4a6f1e07",
"freezeRevision": "2"
},
{
"id": "ce4918bf-a199-4ce2-85a3-d0d296855384",
"action": "FREEZE_ACTION_FREEZE",
"reason": "AML review",
"userId": "7f2a1b0c-9d8e-4f3a-b2c1-0d9e8f7a6b5c",
"organizationId": "a9a1de05-0b19-4fca-8597-1199353bd569",
"performedAt": "2026-10-05T10:22:22.420Z",
"freezeType": "FREEZE_TYPE_MANUAL",
"authority": "FREEZE_AUTHORITY_CUSTOMER_MANUAL",
"mutationId": "5b0e3c1a-7d2f-4e8a-9c61-2f4d8b7a0e93",
"freezeRevision": "1"
}
]
}
}On an unfreeze that you perform through the console or API, freezeType is FREEZE_TYPE_MANUAL, whatever type of freeze the action released.
API reference: Get a transaction
Every transaction response includes freezeInfo. To check one transaction, get it by ID:
curl "https://api.sandbox.palisade.co/v2/vaults/$VAULT_ID/wallets/$WALLET_ID/transactions/$TRANSACTION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"| Field | Description |
|---|---|
freezeInfo.isFrozen | Whether the transaction is frozen now. |
freezeInfo.authority | The authority that owns the current freeze state: FREEZE_AUTHORITY_CUSTOMER_MANUAL, FREEZE_AUTHORITY_AUTOMATIC_POLICY, or FREEZE_AUTHORITY_MANAGEMENT_COMPLIANCE. A transaction that was never frozen or unfrozen has FREEZE_AUTHORITY_UNSPECIFIED, freezeRevision "0", an empty history, and no mutationId. |
freezeInfo.freezeRevision | The revision of the transaction's freeze state. It increases with each change. |
freezeInfo.mutationId | The identifier of the latest freeze or unfreeze. |
freezeInfo.history | Every freeze and unfreeze action, newest first. When the transaction is frozen, the first entry holds the current freeze details. |
history[].id | The identifier of that freeze or unfreeze action. |
history[].action | Whether the entry is a freeze (FREEZE_ACTION_FREEZE) or an unfreeze (FREEZE_ACTION_UNFREEZE). |
history[].reason | The reason supplied with the freeze or unfreeze request. |
history[].performedAt | When the freeze or unfreeze took effect. |
history[].authority, history[].mutationId, history[].freezeRevision | The authority, mutation identifier, and freeze revision of that freeze or unfreeze action. |
history[].freezeType | Why the transaction was frozen, for example FREEZE_TYPE_MANUAL, FREEZE_TYPE_AUTO_WALLET_SETTING, FREEZE_TYPE_TRAVEL_RULE, or FREEZE_TYPE_COMPLIANCE. See Freeze types. |
history[].userId, history[].organizationId | The user who performed the action, and the organization. Automatic actions, such as an unfreeze after compliance checks pass, have no userId. |
To see the frozen amount for each asset, get the wallet's balances with a WALLETS credential. Each balance includes frozenBalance alongside availableBalance and pendingBalance. See Understanding balances.