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

# Liquidate

> Calldata that withdraws from the sale of a defaulted loan and settles the escrow

> [!NOTE]
>
> Seller Financing is in beta and runs on Ethereum Sepolia instances only for now (`DEVELOPMENT` instances on Ethereum). A `PRODUCTION` instance, or one on another network, answers `503 SELLER_FINANCING_UNAVAILABLE`. See [Seller Financing](/endpoints/seller-financing/introduction.md).

Builds the seller's withdrawal from the sale of a loan in default. The seller or the market's operator signs it. Once mined, the listing reads `LIQUIDATED`, the asset is released back to the seller, and the escrow is split:

* The seller is credited the compensation, 1.5 percent of the downpayment rounded up, plus the interest still owed, capped at the escrow, less Trusset's 20 percent of that sum.
* Trusset is credited that 20 percent.
* The buyer is credited the rest of the escrow as a refund.

The escrow is the downpayment plus the principal paid so far. Interest the buyer paid before the default stays with the seller. Nothing is paid out by the liquidation itself: the seller and the buyer each withdraw with [Withdraw](/endpoints/seller-financing/withdraw.md).

In freeze mode the adapter unfreezes the amount in the seller's wallet. In custody mode it returns the asset to the seller, or keeps it in escrow for the seller when the token refuses the return. Before building, the API simulates that return from the adapter: when the token refuses it, the answer carries `assetReturn` with `willEscrow: true` and the same text in `warning`, and the seller later takes the asset back with [Claim Escrowed Collateral](/endpoints/seller-financing/claim-escrowed-collateral.md). See [What each party receives](/endpoints/seller-financing/introduction.md#what-each-party-receives) for a worked example.

A loan is in default one second after the grace period of a due date whose interest is unpaid, or one second after maturity plus the grace period while principal is outstanding. Before that, the API answers `409 TX_WOULD_REVERT` with `NotLiquidatable` and the moment the loan becomes liquidatable. A liquidation is refused while the market is paused.

> [!WARNING]
>
> The asset is released before any money settles. While the freeze adapter lacks its agent role on the token, or the custody adapter holds less than it recorded, the liquidation reverts and the escrow waits until the token issuer restores the role or the holdings.

## Path Parameters

**marketId** `string` *required*

The market's record ID, as `id` on [List Markets](/endpoints/seller-financing/list-markets.md).

**listingId** `string` *required*

The listing's ID on the market.

## Body Parameters

**from** `string` *required*

The wallet that signs: the seller or a holder of `OPERATOR_ROLE`. Without it the answer is `400 FROM_REQUIRED`. Any other wallet answers `409 TX_WOULD_REVERT` with `NotSeller`, and the message names the seller and the current operators, also in `details.seller` and `details.roleHolders`.

## Response Fields

**data** `object`

**action** `string`

`SIGN_TRANSACTIONS`.

**chainId** `integer`

The chain the step is built for.

**steps** `array`

One step, `liquidate` on the market, with `gasLimit`.

**confirmStepIndex** `integer`

`0`.

**preflight** `object`

`{ simulated: true, gasEstimate }`.

**loanStatus** `object`

The loan when the request was built: `interestDue`, `payoff`, `nextDue`, `isLiquidatable` and `liquidatableAt`, as on [Get Loan Status](/endpoints/seller-financing/get-loan-status.md#response-fields). `null` when unread.

**signer** `object`

`{ role: "SELLER_OR_OPERATOR_ROLE", seller }`: the seller of the listing, or a holder of `OPERATOR_ROLE`, signs.

**assetReturn** `object`

Custody mode only, present when the asset token refuses the return to the seller: `{ willEscrow: true, reason, message }`. `reason` is the token's refusal when it gave one, otherwise `null`. The liquidation still settles the escrow. Absent when the return goes through or could not be checked.

**warning** `string`

`assetReturn.message`, present with it.

```bash cURL theme={null}
curl -X POST "https://api.trusset.org/seller-financing/api/markets/cmsg4x7k20003sf9q1d8v6b2e/listings/4/liquidate" \
  -H "X-API-Key: trusset_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"from": "0x3E22FdfA28e880239541d9c5B66B3b161F9ED77b"}'
```

```typescript TypeScript theme={null}
const res = await fetch(
  `https://api.trusset.org/seller-financing/api/markets/${marketId}/listings/${listingId}/liquidate`,
  {
    method: 'POST',
    headers: { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' },
    body: JSON.stringify({ from: await seller.getAddress() })
  }
);
const body = await res.json();
if (!body.success && body.error.details?.error === 'NotLiquidatable') {
  console.log(`Liquidatable from ${new Date(body.error.details.liquidatableAt * 1000).toISOString()}`);
}
```

```json Response theme={null}
{
  "success": true,
  "data": {
    "action": "SIGN_TRANSACTIONS",
    "chainId": 11155111,
    "steps": [
      {
        "to": "0xc35e5f74eC4C1dfB8cE2b8798D6161B706F9B5E1",
        "data": "0x415f1240...",
        "value": "0",
        "functionName": "liquidate",
        "label": "Withdraw from the sale of listing 4 and settle the escrow",
        "description": "Withdraw from the sale of listing 4 and settle the escrow",
        "gasLimit": "406127",
        "chainId": 11155111
      }
    ],
    "confirmStepIndex": 0,
    "preflight": {
      "simulated": true,
      "gasEstimate": "312406"
    },
    "loanStatus": {
      "interestDue": "140139154",
      "interestDueFormatted": "140.139154",
      "payoff": {
        "interest": "140139154",
        "principal": "8000000000",
        "fee": "1500000",
        "total": "8141639154",
        "totalFormatted": "8141.639154"
      },
      "nextDue": {
        "dueAt": 1793005200,
        "interestAmount": "115781947",
        "interestAmountFormatted": "115.781947",
        "principalAmount": "0",
        "principalAmountFormatted": "0.0"
      },
      "isLiquidatable": true,
      "liquidatableAt": 1793178001
    },
    "signer": {
      "role": "SELLER_OR_OPERATOR_ROLE",
      "seller": "0x3E22FdfA28e880239541d9c5B66B3b161F9ED77b"
    }
  },
  "error": null,
  "metadata": {
    "timestamp": "2026-10-29T09:00:00.000Z",
    "requestId": "3f7c2a91-6d84-4b0e-9a15-c2e8f4d7b603",
    "instanceId": "inst_abc123"
  }
}
```

```json Error - Not in Default theme={null}
{
  "success": false,
  "data": null,
  "error": {
    "code": "TX_WOULD_REVERT",
    "message": "The loan is not in default. It becomes liquidatable at 2026-10-28T09:00:01.000Z (unix 1793178001) unless the buyer pays.",
    "details": {
      "action": "liquidation",
      "error": "NotLiquidatable",
      "liquidatableAt": 1793178001
    }
  },
  "metadata": {
    "timestamp": "2026-10-22T09:00:00.000Z",
    "requestId": "3f7c2a91-6d84-4b0e-9a15-c2e8f4d7b603",
    "instanceId": "inst_abc123"
  }
}
```

Liquidated at this moment, the loan's 2,000 USDC escrow splits into 136.111324 USDC for the seller, 34.02783 USDC for Trusset and 1,829.860846 USDC for the buyer.

## Error Codes

| Code | HTTP | Cause |
| - | - | - |
| `INVALID_LISTING_ID` | `400` | `listingId` is not a positive integer of up to 19 digits |
| `VALIDATION_ERROR` | `400` | `from` is malformed, or the body carries another field. `error.details` names it |
| `FROM_REQUIRED` | `400` | `from` is missing. The message names who signs: the seller of the listing or a wallet that holds `OPERATOR_ROLE` |
| `MARKET_NOT_FOUND` | `404` | No market with this ID that your instance reaches on its network |
| `LISTING_NOT_FOUND` | `404` | No listing with this ID on the market |
| `INVALID_STATUS` | `409` | The listing is not `ACTIVE`. `details.status` names its status |
| `TX_WOULD_REVERT` | `409` | The liquidation would revert: `NotLiquidatable` with `details.liquidatableAt`, `NotSeller` with `details.requiredRole`, `details.seller` and `details.roleHolders`, `EnforcedPause`, `InsufficientLocked` when the custody adapter holds less than it recorded, or the token's own refusal of the unfreeze, for example when the freeze adapter lost its agent role |
| `CHAIN_UNAVAILABLE` | `503` | The chain could not be read. Nothing was built. Retry shortly |
| `SELLER_FINANCING_UNAVAILABLE` | `503` | The instance is a `PRODUCTION` instance or not on Ethereum |
| `LIQUIDATE_BUILD_FAILED` | `500` | Unexpected failure. Nothing was built. Retry, or contact support with the request ID |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.