Liquidation Settlement
Report Partial Sale
Deposit interim sale proceeds into the router
POST
/
lending-external-securities-v2
/
api
/
liquidations
/
report-partial-sale
/
{liquidationId}
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/liquidations/report-partial-sale/14" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"marketId": "clx_secmarket_001",
"collateralSold": "100",
"usdcProceeds": "9800.00"
}'
const base = 'https://api.trusset.org/lending-external-securities-v2/api/liquidations';
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
for (const tranche of tranches) {
const body = { marketId, collateralSold: tranche.units, usdcProceeds: tranche.proceeds };
const res = await fetch(`${base}/report-partial-sale/${liquidationId}`, {
method: 'POST',
headers,
body: JSON.stringify(body)
});
const { data } = await res.json();
let reportHash = '';
for (const step of data.steps) {
const tx = await wallet.sendTransaction(step.transaction);
await tx.wait();
reportHash = tx.hash;
}
await fetch(`${base}/report-partial-sale/${liquidationId}`, {
method: 'POST',
headers,
body: JSON.stringify({ ...body, txHash: reportHash })
});
}
{
"success": true,
"data": {
"success": true,
"liquidationId": "14",
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x1c7d4b196cb0c7b01d743fbc6116a902379c7238",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Approve the router to pull USDC"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x067a3feea46649adad8e31c33b3a4d8774b8d8cf",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "reportPartialSale"
}
]
}
}
{
"success": true,
"data": {
"liquidationId": "14",
"collateralSold": "100",
"usdcProceeds": "9800.0",
"txHash": "0x4b8e2f71c09a53d6e8b1f47c2a9d05e36b7c18f4a2d9e0b53c6f17a84e2d9b06"
}
}
{
"success": false,
"error": {
"code": "ALREADY_SETTLED",
"message": "Already settled"
}
}
Records proceeds from a partial sale of seized collateral and transfers them from the signing wallet into the liquidation router. Use it when a position is being sold down in tranches and you want proceeds banked as they arrive, rather than held off-platform until the final settlement.
The endpoint is repeatable. Each call increases the router’s
Proceeds deposited here stay in the router until Settle Liquidation forwards the cumulative total to the market. Reporting partial sales alone never closes a liquidation, and the record stays
Confirming with
proceedsCollected. Once deposited, the proceeds can leave the router only through Settle Liquidation: the router’s emergency withdrawal refuses the borrow asset.
The signing wallet must be holding the proceeds. This call pulls the borrow asset from that wallet into the router, so fund it before broadcasting. An insufficient balance reverts on-chain.
Path Parameters
string
required
Liquidation ID on the market’s router.
Body Parameters
string
Names the market whose liquidation you mean. Every market runs its own liquidation router and IDs restart at
1 on each of them, so the same liquidationId can exist on several markets in one instance. Supply this when it does, otherwise the call is refused with AMBIGUOUS_LIQUIDATION_ID and the response lists the candidates. Also accepted as a query parameter. At most 100 characters.string
required
Collateral disposed of in this tranche, as a decimal string in collateral token units, at most as many decimals as the collateral token has. Must be greater than zero. Required on the confirm call too.
string
required
Proceeds realised, as a decimal string in the market’s borrow asset, at most as many decimals as that asset has. Must be greater than zero. Required on the confirm call too.
string
Hash of the
reportPartialSale transaction you broadcast, not of the approval. Send it with the same body to confirm the transaction and record the result. Omit it to receive the calldata. A value that is not 0x followed by 64 hex characters is refused with 400 VALIDATION_ERROR and nothing is built or recorded. null or an empty string counts as omitted.The wallet that signs must hold
OPERATOR_ROLE on the router. This endpoint checks the role against your instance’s primary verified wallet, since it takes no signer address. If that wallet lacks the role, the calldata is not returned: the response carries ROUTER_OPERATOR_ROLE_MISSING along with the calldata that grants it.Response Fields
object
Show child attributes
Show child attributes
string
Liquidation ID, echoed back.
boolean
Nested inside
data on the calldata response.string
SIGN_TRANSACTIONS. Returned when txHash is omitted.array
Ordered
approve on the borrow asset for the router, then reportPartialSale. Returned when txHash is omitted.string
Collateral reported, echoed from the request. Returned when confirming with
txHash.string
Proceeds deposited, read from the mined transaction. Returned when confirming with
txHash.string
Transaction hash. Returned when confirming with
txHash.collateralSold is recorded in the on-chain event as an audit trail. It does not reduce collateralRemaining on the router, because the collateral left the router when you called Withdraw Collateral for Sale. Only that endpoint moves the balance.PENDING.
Settle After Partial Sales
Once every unit of collateral has left the router and every tranche has been reported, call Settle Liquidation withusdcProceeds of "0". Settlement forwards the full proceedsCollected balance already sitting at the router, so a zero final payment is valid and expected in this flow. Settlement is refused with COLLATERAL_UNSOLD while any collateral is still on the router.
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/liquidations/report-partial-sale/14" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"marketId": "clx_secmarket_001",
"collateralSold": "100",
"usdcProceeds": "9800.00"
}'
const base = 'https://api.trusset.org/lending-external-securities-v2/api/liquidations';
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
for (const tranche of tranches) {
const body = { marketId, collateralSold: tranche.units, usdcProceeds: tranche.proceeds };
const res = await fetch(`${base}/report-partial-sale/${liquidationId}`, {
method: 'POST',
headers,
body: JSON.stringify(body)
});
const { data } = await res.json();
let reportHash = '';
for (const step of data.steps) {
const tx = await wallet.sendTransaction(step.transaction);
await tx.wait();
reportHash = tx.hash;
}
await fetch(`${base}/report-partial-sale/${liquidationId}`, {
method: 'POST',
headers,
body: JSON.stringify({ ...body, txHash: reportHash })
});
}
{
"success": true,
"data": {
"success": true,
"liquidationId": "14",
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x1c7d4b196cb0c7b01d743fbc6116a902379c7238",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Approve the router to pull USDC"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x067a3feea46649adad8e31c33b3a4d8774b8d8cf",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "reportPartialSale"
}
]
}
}
{
"success": true,
"data": {
"liquidationId": "14",
"collateralSold": "100",
"usdcProceeds": "9800.0",
"txHash": "0x4b8e2f71c09a53d6e8b1f47c2a9d05e36b7c18f4a2d9e0b53c6f17a84e2d9b06"
}
}
{
"success": false,
"error": {
"code": "ALREADY_SETTLED",
"message": "Already settled"
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
VALIDATION_ERROR | 400 | collateralSold or usdcProceeds is not a positive decimal string, collateralSold has more decimals than the collateral token, marketId is longer than 100 characters, or txHash is present but malformed |
AMBIGUOUS_LIQUIDATION_ID | 400 | This ID exists on more than one market in your instance. The error carries candidates; resend with marketId |
ALREADY_SETTLED | 400 | The liquidation is settled or written off |
WALLET_NOT_CONFIGURED | 400 | No verified wallet is registered on this instance to resolve the signer against |
ROUTER_OPERATOR_ROLE_MISSING | 400 | Your instance’s primary verified wallet lacks OPERATOR_ROLE. The error carries grant calldata |
TX_NOT_VERIFIED | 400 | The confirmed transaction targets a different liquidation |
PARTIAL_SALE_TX_REVERTED | 400 | The report could not be prepared or recorded, for example because usdcProceeds has more decimals than the borrow asset or a chain read failed. error.txHash carries the hash when one exists |
ROLE_UNVERIFIABLE | 400 | The role check could not read the router. Nothing was built. Retry shortly |
LIQUIDATION_NOT_FOUND | 404 | No liquidation with that ID on your instance, and none could be adopted from chain |
MARKET_NOT_FOUND | 404 | marketId was supplied but names no market on your instance |
LIQUIDATION_ON_VENUE | 409 | The record’s Dutch auction is still open, so the router holds none of its collateral |
ROUTER_UNRESOLVED | 503 | The market’s liquidation router could not be read. Retry shortly |
txHash can also return any transaction verification error. A report that reverted on-chain is refused there with TX_REVERTED.⌘I
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/liquidations/report-partial-sale/14" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"marketId": "clx_secmarket_001",
"collateralSold": "100",
"usdcProceeds": "9800.00"
}'
const base = 'https://api.trusset.org/lending-external-securities-v2/api/liquidations';
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
for (const tranche of tranches) {
const body = { marketId, collateralSold: tranche.units, usdcProceeds: tranche.proceeds };
const res = await fetch(`${base}/report-partial-sale/${liquidationId}`, {
method: 'POST',
headers,
body: JSON.stringify(body)
});
const { data } = await res.json();
let reportHash = '';
for (const step of data.steps) {
const tx = await wallet.sendTransaction(step.transaction);
await tx.wait();
reportHash = tx.hash;
}
await fetch(`${base}/report-partial-sale/${liquidationId}`, {
method: 'POST',
headers,
body: JSON.stringify({ ...body, txHash: reportHash })
});
}
{
"success": true,
"data": {
"success": true,
"liquidationId": "14",
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x1c7d4b196cb0c7b01d743fbc6116a902379c7238",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Approve the router to pull USDC"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x067a3feea46649adad8e31c33b3a4d8774b8d8cf",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "reportPartialSale"
}
]
}
}
{
"success": true,
"data": {
"liquidationId": "14",
"collateralSold": "100",
"usdcProceeds": "9800.0",
"txHash": "0x4b8e2f71c09a53d6e8b1f47c2a9d05e36b7c18f4a2d9e0b53c6f17a84e2d9b06"
}
}
{
"success": false,
"error": {
"code": "ALREADY_SETTLED",
"message": "Already settled"
}
}
