Skip to content

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.

Freeze actions

ActionConsole roleConsole procedureAPI procedure
Freeze deposits by defaultOwner, Administrator, ProposerEnable automatic freeze on a walletUpdate wallet settings
Freeze a transactionOwner, Administrator, AuditorFreeze an individual transactionFreeze a transaction
Unfreeze a transactionOwner, Administrator, AuditorUnfreeze a transactionUnfreeze a transaction
Check frozen fundsAll rolesMonitor frozen balancesCheck 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.

Prerequisites

  • 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 clientId and clientSecret for a token. See Getting started with the API.
  • An incoming transaction. You need its vaultId, walletId, and transaction id. To find deposits, list the wallet's transactions with GET /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.

Freeze a transaction via the API

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.

Unfreeze a transaction via the API

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.

Check freeze state via the API

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"
FieldDescription
freezeInfo.isFrozenWhether the transaction is frozen now.
freezeInfo.authorityThe 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.freezeRevisionThe revision of the transaction's freeze state. It increases with each change.
freezeInfo.mutationIdThe identifier of the latest freeze or unfreeze.
freezeInfo.historyEvery freeze and unfreeze action, newest first. When the transaction is frozen, the first entry holds the current freeze details.
history[].idThe identifier of that freeze or unfreeze action.
history[].actionWhether the entry is a freeze (FREEZE_ACTION_FREEZE) or an unfreeze (FREEZE_ACTION_UNFREEZE).
history[].reasonThe reason supplied with the freeze or unfreeze request.
history[].performedAtWhen the freeze or unfreeze took effect.
history[].authority, history[].mutationId, history[].freezeRevisionThe authority, mutation identifier, and freeze revision of that freeze or unfreeze action.
history[].freezeTypeWhy 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[].organizationIdThe 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.