Borrowing
Close Loan
Close a debt-free loan and release the collateral
POST
/
lending-external-securities-v2
/
api
/
positions
/
{marketId}
/
close-loan
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/close-loan" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"loanId": 5}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/close-loan`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5 })
});
const { data } = await res.json();
if (data.collateralRelease) {
console.warn(data.warning);
}
const tx = await borrowerWallet.sendTransaction(data.transaction);
await tx.wait();
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, txHash: tx.hash })
});
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "closeLoan",
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/close-loan",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
}
}
}
{
"success": true,
"data": {
"txHash": "0x3b7d9e1f5a2c4086b8e0d6f4a2c1e9b7d5f3a1c0e8b6d4f2a0c9e7b5d3f1a2c4",
"loanId": "5",
"collateralReturned": "1000.0",
"collateralReturnEscrowed": false
}
}
{
"success": false,
"error": {
"code": "DEBT_OUTSTANDING",
"message": "Loan has 0.184220 USDC outstanding. Repay in full before closing."
}
}
{
"success": false,
"error": {
"code": "LOAN_ALREADY_CLOSED",
"message": "Loan is already closed"
}
}
Closes an active loan whose debt is zero and releases the pledged collateral. In
The endpoint validates loan state on-chain before offering a transaction, so a loan with any outstanding balance is refused with a clear reason rather than an opaque revert.
Confirming with
FREEZE markets the tokens are unfrozen in the borrower’s wallet. In CUSTODY markets they are transferred back from the adapter. Only the loan’s borrower can sign it, and closing moves no settlement money and charges no fee.
A repayment that clears the whole debt already closes the loan in the same transaction. A loan repaid through Repay Loan with all: true therefore needs no close call, and closing it again returns LOAN_ALREADY_CLOSED.
On a
CUSTODY market whose collateral token refuses the return, closing does not revert. The adapter escrows the collateral instead, so the borrower signs a transaction that confirms and delivers nothing. The calldata response then carries collateralRelease and warning. Show them before the borrower signs, and reclaim the collateral through Claim Escrowed Collateral once the restriction is lifted.Path Parameters
string
required
Body Parameters
integer
required
On-chain loan ID. A positive integer. Accepted as a JSON number or as a numeric string, so the value Get Loan returns passes straight back.
string
Hash of the transaction you broadcast for this operation. Send it to confirm the transaction and record the result. Omit it to receive the calldata.
Response Fields
object
Show child attributes
Show child attributes
string
SIGN_TRANSACTION when txHash is omitted.object
Unsigned transaction,
{ to, data, value, chainId }, for the closeLoan call. Returned when txHash is omitted.string
closeLoan. Returned when txHash is omitted.object
Present on a
CUSTODY market when the collateral token would refuse to return the collateral to the borrower, or when its verdict cannot be read before signing. willEscrow is true in the first case, and null with verdictUnreadable: true in the second. Also carries holder, code, reason, message, adapterAddress, marketId and claimAction.string
Human-readable form of
collateralRelease, present alongside it.object
{ endpoint, field, body }: this route, txHash as the field, and a body carrying loanId with txHash: null. Returned when txHash is omitted.string
Transaction hash. Returned when confirming with
txHash.string
Loan ID, echoed back as a string. Returned when confirming with
txHash.string
Collateral the close released, read from the
LoanClosed event. Present when the loan held collateral. Returned when confirming with txHash.boolean
true when that return was escrowed on the adapter instead of delivered. Returned alongside collateralReturned.Interest accrues until the moment of repayment, so a loan repaid with a stale quote almost always carries a small residual balance.
DEBT_OUTSTANDING reports the exact remainder. Repay the rest with all: true, which closes the loan itself.A confirmed close also marks the Trusset position with a
closedAt timestamp and the status REPAID, or LIQUIDATED when the position was liquidated and nothing was repaid since. A position already marked LIQUIDATED keeps that status. Without a confirm call, the position is reconciled on the next sync.curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/close-loan" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"loanId": 5}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/close-loan`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5 })
});
const { data } = await res.json();
if (data.collateralRelease) {
console.warn(data.warning);
}
const tx = await borrowerWallet.sendTransaction(data.transaction);
await tx.wait();
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, txHash: tx.hash })
});
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "closeLoan",
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/close-loan",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
}
}
}
{
"success": true,
"data": {
"txHash": "0x3b7d9e1f5a2c4086b8e0d6f4a2c1e9b7d5f3a1c0e8b6d4f2a0c9e7b5d3f1a2c4",
"loanId": "5",
"collateralReturned": "1000.0",
"collateralReturnEscrowed": false
}
}
{
"success": false,
"error": {
"code": "DEBT_OUTSTANDING",
"message": "Loan has 0.184220 USDC outstanding. Repay in full before closing."
}
}
{
"success": false,
"error": {
"code": "LOAN_ALREADY_CLOSED",
"message": "Loan is already closed"
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
NO_MARKET_ADDRESS | 400 | The market has no on-chain address recorded |
MISSING_MARKET_ID | 400 | marketId is longer than 100 characters |
VALIDATION_ERROR | 400 | loanId is not a positive integer |
DEBT_OUTSTANDING | 400 | Principal or accrued interest remains. The message states the exact amount |
LOAN_ALREADY_CLOSED | 400 | The loan is no longer active, for example because a full repayment already closed it |
LOAN_NOT_FOUND | 404 | No loan with that ID exists on this market |
MARKET_NOT_FOUND | 404 | No market with this ID on your instance |
LOAN_STATE_UNAVAILABLE | 503 | The loan could not be read from the network, so no transaction was prepared. Retry shortly |
txHash can also return any transaction verification error.⌘I
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/close-loan" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"loanId": 5}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/close-loan`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5 })
});
const { data } = await res.json();
if (data.collateralRelease) {
console.warn(data.warning);
}
const tx = await borrowerWallet.sendTransaction(data.transaction);
await tx.wait();
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, txHash: tx.hash })
});
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "closeLoan",
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/close-loan",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
}
}
}
{
"success": true,
"data": {
"txHash": "0x3b7d9e1f5a2c4086b8e0d6f4a2c1e9b7d5f3a1c0e8b6d4f2a0c9e7b5d3f1a2c4",
"loanId": "5",
"collateralReturned": "1000.0",
"collateralReturnEscrowed": false
}
}
{
"success": false,
"error": {
"code": "DEBT_OUTSTANDING",
"message": "Loan has 0.184220 USDC outstanding. Repay in full before closing."
}
}
{
"success": false,
"error": {
"code": "LOAN_ALREADY_CLOSED",
"message": "Loan is already closed"
}
}
