# Freeze and unfreeze transactions via the API

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](/pt-br/products/wallet/compliance/transaction-freeze).

## Freeze actions

| Action | Console role | Console procedure | API procedure |
|  --- | --- | --- | --- |
| Freeze deposits by default | Owner, Administrator, Proposer | [Enable automatic freeze on a wallet](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions#enable-automatic-freeze-on-a-wallet-via-the-console) | [Update wallet settings](/pt-br/products/wallet/vaults-and-wallets/wallets/manage-wallets-api#update-wallet-settings-via-the-api) |
| Freeze a transaction | Owner, Administrator, Auditor | [Freeze an individual transaction](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions#freeze-an-individual-transaction-via-the-console) | [Freeze a transaction](#freeze-a-transaction-via-the-api) |
| Unfreeze a transaction | Owner, Administrator, Auditor | [Unfreeze a transaction](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions#unfreeze-a-transaction-via-the-console) | [Unfreeze a transaction](#unfreeze-a-transaction-via-the-api) |
| Check frozen funds | All roles | [Monitor frozen balances](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions#monitor-frozen-balances-via-the-console) | [Check freeze state](#check-freeze-state-via-the-api) |


**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](/pt-br/products/wallet/organization-and-access/users-and-roles#transactions). 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](/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).
- **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](/pt-br/products/wallet/transactions/view-and-track-transactions#list-transactions-via-the-api), and [List wallet transactions](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/transactions/transactionsservice_listwallettransactions) in the API reference.


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).

## Freeze a transaction via the API

**API reference:** [Freeze a transaction](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/transactions/transactionsservice_freezetransaction)

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.

```bash
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:

```json
{
  "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](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/transactions/transactionsservice_unfreezetransaction)

Send a `PUT` request to the transaction's `unfreeze` path, with the required `reason` and an optional `mutationId`:

```bash
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](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions#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:

```json
{
  "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](/pt-br/products/wallet/api-docs/palisade-api/palisade-api/transactions/transactionsservice_gettransaction)

Every transaction response includes `freezeInfo`. To check one transaction, get it by ID:

```bash
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](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions#freeze-types-and-who-can-change-them). |
| `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](/pt-br/products/wallet/vaults-and-wallets/wallets/understanding-balances).

## Related documentation

- [Configure transaction freeze controls](/pt-br/products/wallet/compliance/transaction-freeze)
- [Freeze and unfreeze transactions via the console](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions)
- [Freeze types and who can change them](/pt-br/products/wallet/compliance/freeze-and-unfreeze-transactions#freeze-types-and-who-can-change-them)
- [Travel Rule transactions](/pt-br/products/wallet/compliance/travel-rule/travel-rule-transactions)
- [Ripple Custody (Wallet) API reference](/pt-br/products/wallet/api-docs/palisade-api/palisade-api)