Positions & Queries
Get Loan
Read a loan directly from the market contract
GET
/
lending-external-securities-v2
/
api
/
positions
/
{marketId}
/
loan
/
{loanId}
curl "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/loan/5" \
-H "X-API-Key: trusset_your_key_here"
const res = await fetch(
`https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/loan/5`,
{ headers: { 'X-API-Key': 'trusset_your_key_here' } }
);
const { data } = await res.json();
const liquidatable =
data.active && ((data.healthFactor !== null && parseFloat(data.healthFactor) < 1) || data.term?.enforceable === true);
{
"success": true,
"data": {
"loanId": "5",
"borrower": "0xaBc7f1093D5E26B804a1C3f78dE025916B47C0d3",
"payee": null,
"collateralAmount": "1000.0",
"principal": "50000.0",
"accruedInterest": "961.643835",
"healthFactor": "1.842",
"active": true,
"debtFree": false,
"fixedRateBps": 650,
"dueAt": "1796630400",
"term": {
"dueAt": "1796630400",
"effectiveDueAt": "1796630400",
"graceEnd": "1796889600",
"enforceable": false,
"termGracePeriod": "259200",
"termPenaltyBps": 300,
"stamped": true,
"termSource": "STAMPED"
},
"compliance": {
"mode": "FREEZE",
"holder": "0xabc7f1093d5e26b804a1c3f78de025916b47c0d3",
"restricted": false,
"code": null,
"reason": null,
"collateralReturnable": true,
"willEscrowOnRelease": false,
"escrowedCollateral": null,
"escrowedCollateralRaw": null,
"holderVerified": true,
"holderAddressFrozen": false,
"tokenPaused": false,
"checkedAt": "2026-09-26T11:58:12.000Z"
}
}
}
{
"success": false,
"error": {
"code": "LOAN_NOT_FOUND",
"message": "Loan not found"
}
}
{
"success": false,
"error": {
"code": "INVALID_LOAN_ID",
"message": "Valid loan ID required"
}
}
Returns live loan state by on-chain loan ID, read from the market contract rather than from Trusset’s position records. Use this when you need authoritative figures for a payoff quote, a health check, or a liquidation decision.
The read also carries the loan’s term: when it falls due, when its grace period ends, and whether it can already be liquidated on term alone. On a market that makes open-ended loans those fields are null.
On a
Path Parameters
string
required
integer
required
On-chain loan ID. Must be a positive integer.
Response Fields
object
Show child attributes
Show child attributes
string
Loan ID, echoed back.
string
Borrower address, checksummed as the contract returns it. The borrower of record, also when the loan pays another wallet.
string
The wallet the market pays this loan’s draws to, lowercased, when the loan was opened with a
payToAddress. null when the loan pays its borrower. Absent when the market’s implementation predates pay-to, or when the payee could not be read. See Pay the proceeds to another wallet.string
Collateral pledged, in collateral token units.
string
Outstanding principal, in borrow asset units.
string
Interest owed and unpaid, in borrow asset units, projected to the current block.
string
Health factor as a decimal string.
1.0 is the liquidation boundary. null on a loan that is no longer active and on an open loan with no debt left, where the contract reports no finite value.boolean
Whether the loan is open.
false once it is repaid, closed, or fully liquidated.boolean
true for an open loan whose principal and interest are both zero. Such a loan still locks its collateral until Close Loan releases it.integer
The rate stamped on this loan when it opened, in basis points. A stamped rate prices the loan by time alone and does not move with the pool’s rate.
0 when the market’s rate model was not in FIXED mode at signing, so the loan pays the floating rate. null when the loan record could not be read.string
Unix seconds the loan falls due, as stamped at signing and moved by any extension of this loan.
null on an open-ended loan.object
The loan’s term state.
null on an open-ended loan, or when the term could not be read.Show child attributes
Show child attributes
string
Unix seconds the loan falls due.
string
The due date actually applied: the later of
dueAt and the market-wide due floor, which a confirmed market-wide extension raises.string
Unix seconds the grace period after
effectiveDueAt ends.boolean
true once graceEnd has passed on an open loan. The loan can then be liquidated on term alone, whatever its health factor.string
The grace period in seconds this loan is enforced under.
null when it could not be read.integer
The term penalty in basis points that caps what a term realization retains above the debt.
null when it could not be read.boolean
true when the grace period and term penalty were stamped on the loan at signing, so later term changes on the market do not reach it. false for a loan opened before stamping existed. null when the market does not expose the stamp.string
Where
termGracePeriod and termPenaltyBps come from: STAMPED (the loan’s own stamp), MARKET_CONFIG (the market’s live term configuration), or UNKNOWN.object
What the collateral token would currently permit for this borrower. See below.
null when the market records no collateral token, or when the probe could not run.payee, debtFree, fixedRateBps, dueAt and term come from one batched chain read. When that read fails and the loan is read on its own instead, the response carries only loanId, borrower, collateralAmount, principal, accruedInterest, healthFactor, active and compliance.Compliance
The collateral is a third-party security token whose issuer can freeze an address, revoke an identity, or pause the token after the loan opened. This block is that state, probed at request time. It is the difference between a loan that looks healthy and one whose collateral can actually be released.object
Show child attributes
Show child attributes
string
FREEZE or CUSTODY, the market’s collateral mode.string
The borrower this verdict is about, lowercased.
boolean
true when any check found a block. false when the evidence is complete and clear: on a CUSTODY market the token allows the adapter’s return, or exposes no holder rule at all (basis below), on a FREEZE market all three holder checks read clear. null when that evidence is missing, which is unknown rather than clear.integer
The collateral token’s own restriction code when it refuses the adapter’s return to the borrower.
null when nothing refuses it, on a FREEZE market, when the token answers the probe with a bare yes or no, and on an ERC-1400 token, whose ERC-1066 status reason quotes.string
One sentence naming what is blocking, or why the state could not be established.
null when nothing is blocking.boolean
Whether the token would accept the adapter’s return of this collateral to the borrower right now. Always
true on a FREEZE market, where a release moves nothing. The probe asks canTransfer and checkTransfer, ERC-1404 detectTransferRestriction, and ERC-1594 canTransfer(address,uint256,bytes) on an ERC-1400 token. true also when the token answers none of them and exposes no holder rule (basis: unrestricted_token). null when the token does not answer the transfer probe and that cannot be ruled out.boolean
true when a release would be escrowed on the adapter rather than delivered, because the token would refuse the transfer. Always false on a FREEZE market. null on a CUSTODY market whose token does not answer the transfer probe, unless basis is unrestricted_token.string
Collateral already sitting in escrow for this holder, in collateral units.
CUSTODY markets only, and null when the escrow could not be read. Claim it with Claim Escrowed Collateral.string
The same figure in base units.
boolean
Whether the collateral token would deliver that escrow to the holder now. When the token’s transfer verdict cannot be read, the exact claim is simulated from the holder’s wallet (
estimateGas) and its outcome answers instead. false keeps restricted at true with the escrow’s refusal in reason, so a claim would be refused with COLLATERAL_TRANSFER_RESTRICTED. null when there is no escrow, or neither the verdict nor the simulation gave an answer.string
Why the escrow cannot be delivered when
escrowClaimable is false: the token’s words, or the reason the simulated claim reverts. null otherwise.string
CUSTODY only. unrestricted_token when the token answers none of the transfer checks and exposes no holder rule the platform reads (no identity registry, allow-list or transfer rule, as on a plain ERC-20). collateralReturnable is then true and restricted false. Absent otherwise.boolean
Whether the borrower is still a verified identity on the identity registry the collateral token names.
null when the token names no registry or it could not be read.boolean
Whether the token has frozen this address.
null when unreadable.boolean
Whether the collateral token is paused.
null when unreadable.string
When this verdict was established. It does not move while the verdict is unchanged, so it reads as the age of the finding rather than the age of the request.
CUSTODY market, the three holder checks run only when the transfer probe is unavailable or refuses the return. When the token allows the return, holderVerified, holderAddressFrozen and tokenPaused are null because they were not needed, not because they failed.
Treat
restricted: null as unknown, never as unrestricted. It means the collateral token did not answer enough of the probes to establish its compliance state.A full payoff is
principal plus accruedInterest, plus the market’s repay fee where one is set, capped at 0.5 percent of the debt. Interest accrues every second, so add a small margin when quoting. The contract never takes more than the closing amount, so a slight overpayment is not transferred. Repay with all: true sizes the payment, fee included.curl "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/loan/5" \
-H "X-API-Key: trusset_your_key_here"
const res = await fetch(
`https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/loan/5`,
{ headers: { 'X-API-Key': 'trusset_your_key_here' } }
);
const { data } = await res.json();
const liquidatable =
data.active && ((data.healthFactor !== null && parseFloat(data.healthFactor) < 1) || data.term?.enforceable === true);
{
"success": true,
"data": {
"loanId": "5",
"borrower": "0xaBc7f1093D5E26B804a1C3f78dE025916B47C0d3",
"payee": null,
"collateralAmount": "1000.0",
"principal": "50000.0",
"accruedInterest": "961.643835",
"healthFactor": "1.842",
"active": true,
"debtFree": false,
"fixedRateBps": 650,
"dueAt": "1796630400",
"term": {
"dueAt": "1796630400",
"effectiveDueAt": "1796630400",
"graceEnd": "1796889600",
"enforceable": false,
"termGracePeriod": "259200",
"termPenaltyBps": 300,
"stamped": true,
"termSource": "STAMPED"
},
"compliance": {
"mode": "FREEZE",
"holder": "0xabc7f1093d5e26b804a1c3f78de025916b47c0d3",
"restricted": false,
"code": null,
"reason": null,
"collateralReturnable": true,
"willEscrowOnRelease": false,
"escrowedCollateral": null,
"escrowedCollateralRaw": null,
"holderVerified": true,
"holderAddressFrozen": false,
"tokenPaused": false,
"checkedAt": "2026-09-26T11:58:12.000Z"
}
}
}
{
"success": false,
"error": {
"code": "LOAN_NOT_FOUND",
"message": "Loan not found"
}
}
{
"success": false,
"error": {
"code": "INVALID_LOAN_ID",
"message": "Valid loan ID required"
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
NO_MARKET_ADDRESS | 400 | The market has no on-chain address recorded |
INVALID_LOAN_ID | 400 | loanId is not a positive integer |
MISSING_MARKET_ID | 400 | The market ID is longer than 100 characters |
LOAN_NOT_FOUND | 404 | The market holds no loan with this ID, or the loan could not be read from the network |
MARKET_NOT_FOUND | 404 | No market with this ID on your instance |
⌘I
curl "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/loan/5" \
-H "X-API-Key: trusset_your_key_here"
const res = await fetch(
`https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/loan/5`,
{ headers: { 'X-API-Key': 'trusset_your_key_here' } }
);
const { data } = await res.json();
const liquidatable =
data.active && ((data.healthFactor !== null && parseFloat(data.healthFactor) < 1) || data.term?.enforceable === true);
{
"success": true,
"data": {
"loanId": "5",
"borrower": "0xaBc7f1093D5E26B804a1C3f78dE025916B47C0d3",
"payee": null,
"collateralAmount": "1000.0",
"principal": "50000.0",
"accruedInterest": "961.643835",
"healthFactor": "1.842",
"active": true,
"debtFree": false,
"fixedRateBps": 650,
"dueAt": "1796630400",
"term": {
"dueAt": "1796630400",
"effectiveDueAt": "1796630400",
"graceEnd": "1796889600",
"enforceable": false,
"termGracePeriod": "259200",
"termPenaltyBps": 300,
"stamped": true,
"termSource": "STAMPED"
},
"compliance": {
"mode": "FREEZE",
"holder": "0xabc7f1093d5e26b804a1c3f78de025916b47c0d3",
"restricted": false,
"code": null,
"reason": null,
"collateralReturnable": true,
"willEscrowOnRelease": false,
"escrowedCollateral": null,
"escrowedCollateralRaw": null,
"holderVerified": true,
"holderAddressFrozen": false,
"tokenPaused": false,
"checkedAt": "2026-09-26T11:58:12.000Z"
}
}
}
{
"success": false,
"error": {
"code": "LOAN_NOT_FOUND",
"message": "Loan not found"
}
}
{
"success": false,
"error": {
"code": "INVALID_LOAN_ID",
"message": "Valid loan ID required"
}
}
