> ## Documentation Index
> Fetch the complete documentation index at: https://docs.glider.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Prepare Liquidate-All (Stage 1)

> Stage 1 of the two-stage liquidate-all flow — enumerates every holding on the recipient's chain above the swap threshold and returns the authorization to swap them all to the chosen settlement asset (USDC, or USDT on EVM).

Stage 1 of the two-stage liquidate-all flow. Reads the portfolio's live
positions on the recipient's chain, selects every holding whose value is above
the tenant's swap threshold, and returns a signable authorization that swaps
the assets to one settlement asset and delivers it to `recipientAccountId`.
Stage 2 (`POST /v2/portfolios/{portfolioId}/liquidate-all`) submits the signed
authorization.

This is the whole-portfolio counterpart of
[`POST .../withdraw/signature`](./v2-withdraw-signature) with `liquidate: true`
— you don't list assets; the server enumerates them. The signed message it
returns is a standard withdrawal authorization with `liquidate: true`, so it
behaves identically at stage 2.

* Auth: `x-api-key` header (required)
* Scope: `portfolios:withdraw`
* Chains: **EVM** and **Solana** (Solana requires the tenant's Solana B2B API
  access — without it, a Solana recipient returns `403`).

`recipientAccountId` is a chain-bound [CAIP-10](https://chainagnostic.org/CAIPs/caip-10)
identifier — `eip155:<chainId>:<address>` (EVM) or
`solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:<base58>` (Solana). Liquidation is
scoped to that one chain — holdings on other chains are untouched. To
liquidate a multi-chain portfolio fully, call this once per chain.

`recipientAccountId` selects the portfolio vault and chain to liquidate. If the
portfolio has no vault on that chain, stage 1 returns
`400 API_215 PORTFOLIO_HAS_NO_VAULT_ON_CHAIN`. For a multi-chain portfolio,
only holdings on the selected chain are liquidated; holdings on other chains
remain untouched. The settlement asset and recipient must be on the selected
chain, and this endpoint does not bridge proceeds between chains.

The shape of the returned authorization matches the withdraw flow: EVM
portfolios receive an EIP-712 typed-data object under `data.typedData`; Solana
portfolios receive an off-chain authorization under `data.authorization`
(`kind: "ecdsa"` — EVM-rooted owner, sign `raw` via EIP-191 `personal_sign`;
`kind: "solana-message"` — Solana-rooted owner, sign `text` via ed25519). See
[Prepare Withdrawal](./v2-withdraw-signature) for the signing details.

### Settlement asset

By default every holding is swapped to **USDC** on the recipient's chain. Pass
an optional `settlementAssetId` whose CAIP-19 chain matches
`recipientAccountId`: configured **USDC** or **USDT** for an EVM liquidation,
or **USDC** for a Solana liquidation. Any asset that isn't an allowed
settlement asset on the chain returns
`400 API_221 UNSUPPORTED_SETTLEMENT_ASSET`. The chosen asset is bound into
the signed message.

On Solana the proceeds are swapped inside the portfolio's smart account and
delivered to the recipient in one engine operation; native SOL positions are
liquidated too (a small rent reserve stays behind so the account remains
rent-exempt).

**Ondo tokenized stocks** (`TSLAon`, `SPCXon`, …) redeem through Ondo directly
and settle only in the chain's Ondo cash asset — **USDT on BNB Chain (56)**,
**USDC on Ethereum (1)**. If the portfolio holds Ondo tokens and the requested
settlement asset doesn't match, this endpoint rejects with
`400 API_221 UNSUPPORTED_SETTLEMENT_ASSET` before anything is signed. See the
[stage-2 notes](./v2-liquidate-all#portfolios-holding-ondo-tokenized-stocks)
for market-hours behavior.

### Best-effort empty

Holdings whose value is below the tenant swap threshold (or that have no swap
route) are **left in the vault** — forcing uneconomical swaps would lose more
to gas than they recover. The portfolio is emptied of everything worth
swapping, not necessarily down to zero. If nothing clears the threshold, the
call returns `400 API_220 NOTHING_TO_LIQUIDATE`.

The authorization is valid for **10 minutes** and, like all withdrawals, binds
the portfolio, recipient, the enumerated assets + amounts, the nonce, and the
expiry into the user's signature.

Common error responses:

* `400 API_211 INVALID_RECIPIENT` — zero address or a self-transfer to the
  smart account being debited.
* `400 API_215 PORTFOLIO_HAS_NO_VAULT_ON_CHAIN` — portfolio has no smart
  account on the recipient's chain.
* `400 API_219 WITHDRAW_AS_USDC_UNSUPPORTED_CHAIN` — the recipient's chain has
  no canonical USDC to swap into (the default settlement asset).
* `400 API_221 UNSUPPORTED_SETTLEMENT_ASSET` — `settlementAssetId` is not an allowed
  settlement asset on the chain (configured USDC or USDT for an EVM
  liquidation, or USDC for a Solana liquidation).
* `400 API_220 NOTHING_TO_LIQUIDATE` — no holding on the chain clears the swap
  threshold.
* `401` when `x-api-key` is missing or invalid.
* `403` when the API key lacks the `portfolios:withdraw` scope, or the
  recipient is Solana and the tenant's Solana B2B API access is not enabled.
* `404 API_200 PORTFOLIO_NOT_FOUND` — `portfolioId` doesn't exist or belongs
  to a different tenant.
* `500` on unexpected server errors.

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.glider.fi/v2/portfolios/a1b2c3d4/liquidate-all/signature' \
    --header 'x-api-key: gldr_sk_your_api_key' \
    --header 'Content-Type: application/json' \
    --data '{
      "recipientAccountId": "eip155:1:0x4444444444444444444444444444444444444444"
    }'
  ```

  ```bash cURL (settle to USDT on BNB) theme={null}
  curl --request POST \
    --url 'https://api.glider.fi/v2/portfolios/a1b2c3d4/liquidate-all/signature' \
    --header 'x-api-key: gldr_sk_your_api_key' \
    --header 'Content-Type: application/json' \
    --data '{
      "recipientAccountId": "eip155:56:0x4444444444444444444444444444444444444444",
      "settlementAssetId": "eip155:56/erc20:0x55d398326f99059fF775485246999027B3197955"
    }'
  ```

  ```bash cURL (Solana) theme={null}
  curl --request POST \
    --url 'https://api.glider.fi/v2/portfolios/a1b2c3d4/liquidate-all/signature' \
    --header 'x-api-key: gldr_sk_your_api_key' \
    --header 'Content-Type: application/json' \
    --data '{
      "recipientAccountId": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "data": {
      "authorizationId": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
      "expiresAt": "2026-04-17T12:10:00.000Z",
      "typedData": {
        "primaryType": "Withdrawal",
        "domain": {
          "name": "Glider Withdrawal Authorization",
          "version": "2",
          "chainId": 1,
          "verifyingContract": "0x2222222222222222222222222222222222222222"
        },
        "types": {
          "Withdrawal": [
            { "name": "portfolioId", "type": "string" },
            { "name": "recipientAccountId", "type": "string" },
            { "name": "assets", "type": "WithdrawalAsset[]" },
            { "name": "nonce", "type": "bytes32" },
            { "name": "expiresAt", "type": "uint256" },
            { "name": "liquidate", "type": "bool" },
            { "name": "settlementAssetId", "type": "string" }
          ],
          "WithdrawalAsset": [
            { "name": "assetId", "type": "string" },
            { "name": "amountRaw", "type": "string" }
          ]
        },
        "message": {
          "portfolioId": "a1b2c3d4",
          "recipientAccountId": "eip155:1:0x4444444444444444444444444444444444444444",
          "assets": [
            {
              "assetId": "eip155:1/erc20:0x6b175474e89094c44da98b954eedeac495271d0f",
              "amountRaw": "5000000000000000000"
            },
            {
              "assetId": "eip155:1/erc20:0x514910771af9ca656af840dff83e8264ecf986ca",
              "amountRaw": "12000000000000000000"
            }
          ],
          "nonce": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
          "expiresAt": 1744898400,
          "liquidate": true,
          "settlementAssetId": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
        }
      }
    }
  }
  ```

  ```json 200 — Solana (Model B owner) theme={null}
  {
    "success": true,
    "data": {
      "authorizationId": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
      "expiresAt": "2026-04-17T12:10:00.000Z",
      "authorization": {
        "kind": "solana-message",
        "text": "Glider — authorize Solana liquidation to a settlement asset\n\nPortfolio: a1b2c3d4\n…\nDomain: glider:svm-withdraw-liquidate:solana:v1",
        "message": {
          "portfolioId": "a1b2c3d4",
          "recipientAccountId": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj",
          "assets": [
            {
              "assetId": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/spl:JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN",
              "amountRaw": "2500000000"
            }
          ],
          "nonce": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
          "expiresAt": 1744898400,
          "liquidate": true,
          "settlementAssetId": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/spl:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
        }
      }
    }
  }
  ```

  ```json 400 — nothing to liquidate theme={null}
  {
    "success": false,
    "error": {
      "code": "API_220",
      "message": "No assets above the liquidation threshold (1 USD) on the recipient's chain"
    }
  }
  ```
</ResponseExample>
