Markets
Get Market Metrics
Read live pool metrics directly from the market contract
GET
/
lending-external-securities-v2
/
api
/
markets
/
{marketId}
/
metrics
curl "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/metrics" \
-H "X-API-Key: trusset_your_key_here"
const res = await fetch(
`https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}/metrics`,
{ headers: { 'X-API-Key': 'trusset_your_key_here' } }
);
const { data } = await res.json();
if (!data.isOnChain) throw new Error('Market metrics unavailable');
console.log(`Borrow APR ${(Number(data.borrowRate) / 100).toFixed(2)}%`);
{
"success": true,
"data": {
"isOnChain": true,
"paused": false,
"liquidationContract": "0x067A3FeEA46649AdAd8e31c33B3a4D8774b8d8cF",
"priceSource": "NAV",
"totalDeposits": "1000000.0",
"totalBorrows": "250000.0",
"availableLiquidity": "750000.0",
"utilizationRate": "2500",
"borrowRate": "450",
"supplyRate": "83.1938",
"curveBorrowRate": "450",
"totalShares": "998712.4",
"totalCollateral": "5000.0",
"activeLoans": 4,
"totalLoansCreated": 11,
"activeAuctions": 0,
"totalAuctions": 0,
"pendingLiquidations": 0,
"pendingLiquidationDebt": "0.0",
"auctionModule": null,
"useVaultLiquidity": true,
"operatorFeesPayable": "264.03",
"operatorFeesPayableRaw": "264030000",
"protocolFeesPayable": "0.0",
"protocolFeesPayableRaw": "0",
"infrastructureFeesPayable": "130.09",
"infrastructureFeesPayableRaw": "130090000",
"distributorFeesPayable": "22.43",
"distributorFeesPayableRaw": "22430000",
"operatorWallet": "0x4e91a7c05d3b62f18a0c94e7db2358f1c60a4e93",
"feeShareGeneration": "FIXED_SHARES",
"distributorShare": "500",
"vaultOnlyLiquidity": true,
"rateMode": "CLAMPED",
"rateFloor": "200",
"rateCap": "1200",
"maxFixedRate": null,
"reserveRatio": "500",
"maxLoanDuration": "15552000",
"termGracePeriod": "432000",
"terminalDueDate": null,
"termPenalty": "300",
"marketDueFloor": null,
"allowExtension": true,
"fixedStampRateBps": 0,
"stampsFixedRate": false,
"reserveRatioBps": 500,
"borrowableLiquidity": "700000.0",
"latestDueAt": "1805616000",
"exitHorizon": {
"horizon": "1806048000",
"bounded": true,
"applies": true,
"basis": "OPEN_LOANS"
},
"newLoansClosed": false,
"newLoansClosedReason": null,
"termConfig": {
"maxLoanDuration": "15552000",
"termGracePeriod": "432000",
"terminalDueDate": "0",
"marketDueFloor": "0",
"termPenaltyBps": 300,
"allowExtension": true,
"termStamping": "PER_LOAN"
}
}
}
{
"success": true,
"data": {
"isOnChain": false,
"totalDeposits": "0",
"totalBorrows": "0",
"availableLiquidity": "0",
"utilizationRate": "0",
"borrowRate": "200",
"supplyRate": "0",
"pendingLiquidations": 0,
"pendingLiquidationDebt": "0",
"paused": null,
"readFailed": true
}
}
{
"success": false,
"error": {
"code": "NO_MARKET_ADDRESS",
"message": "No on-chain address"
}
}
Returns current liquidity, borrows, utilization, rates, fee balances and liquidation counters read from the chain at request time. This is the endpoint to poll for a live market dashboard. A healthy read is shared for up to 15 seconds, and any successful write request drops it, so the next poll after a write reads the chain again.
These are balances waiting on the market, and anyone may sweep them. See Sweep Operator Fees, Sweep Distributor Fees, Sweep Protocol Fees and Sweep Infrastructure Fees. The split itself is on Get Fee Split.
When the chain is unavailable the endpoint returns
200 with isOnChain: false rather than an error status, and every figure is a placeholder: zeros, and a borrowRate of "200". Branch on isOnChain before rendering any figure.paused is null, never false, when the pause flag could not be read. Rendering null as false can show a paused market as live.Path Parameters
string
required
Response Fields
object
Show child attributes
Show child attributes
boolean
Whether the contract read succeeded. When
false, every other field is a placeholder and must not be displayed as real data.boolean
Whether the market contract is paused, or
null when unreadable.string
Liquidation router the market is wired to, or
null if unreadable.string
NAV, MARKET, ORACLE or FIXED, read from the contract. null when unreadable.string
Total pool liquidity, in borrow asset units.
string
Total outstanding principal, in borrow asset units.
string
Free liquidity, in borrow asset units: the pool’s cash less every booked liability (fee balances, escrowed surplus, held sale proceeds), capped at liquidity minus borrows.
string
Utilization in basis points.
2500 is 25 percent.string
Annualized borrow rate in basis points. On a
FIXED market it is the rate every new loan is stamped with. Otherwise it is the interest model’s rate at the current utilization.string
The interest model’s rate at the current utilization, in basis points. On a
FIXED market it prices only loans that carry no stamp, and borrowRate differs from it.string
Annualized supply rate in basis points, derived from
borrowRate as described below. It can carry up to four decimal places.string
Total LP shares outstanding, always formatted at 18 decimals regardless of the borrow asset.
string
Total collateral locked, in collateral token units.
integer
Loans Trusset’s position records hold as
ACTIVE.integer
Lifetime loan counter from the contract.
integer
Dutch auctions currently accepting bids on the market’s auction venue.
integer
Lifetime auction counter from the auction venue.
0 when the market has none.integer
Recorded liquidations not yet settled or written off.
string
Debt awaiting settlement proceeds, in borrow asset units, from the contract.
string
The market’s auction venue, lowercased, or
null when the market has none.boolean
Present and
true when a side read failed. The named figures are still the contract’s, but a counter may be short. Absent on a clean read.Rate offering
Present when the market’s interest model could be read. These describe how the market prices new loans.object
Show child attributes
Show child attributes
string
CURVE, CLAMPED or FIXED.string
Floor in basis points.
"0" on CURVE.string
Cap in basis points.
"0" on CURVE.string
Ceiling on any fixed rate the rate model owner can set, in basis points, or
null when none is set. It can only move down.integer
The rate a loan opened right now would be stamped with.
0 when the model stamps nothing.boolean
Whether the model stamps a rate onto each new loan. When
true, borrowRate equals fixedStampRateBps.Terms and exit
object
Show child attributes
Show child attributes
object
The market’s term offering read from the contract, or
null when unreadable. A market with maxLoanDuration and terminalDueDate both "0" makes open-ended loans.Show child attributes
Show child attributes
string
Seconds a loan may run.
string
Seconds after the due date before an unpaid loan can be liquidated on its term.
string
Unix seconds every loan falls due by,
"0" when unset.string
Market-wide extension floor in unix seconds,
"0" when unset.integer
Penalty on a term liquidation, in basis points.
boolean
Whether a borrower may be granted more time.
string
PER_LOAN when the implementation stamps the grace period and term penalty onto each loan at signing, so a term change reaches new loans only. MARKET_CONFIG when open loans follow the live grace period and penalty. UNKNOWN when it could not be read.string
Same value as
termConfig.maxLoanDuration, flattened onto the response. termGracePeriod, terminalDueDate, marketDueFloor, termPenalty and allowExtension are flattened alongside it. terminalDueDate and marketDueFloor are null rather than "0" when unset here, and termPenalty is basis points.string
Unix seconds of the furthest due date stamped on any loan so far. It only moves forward, so it can name a loan that has since closed.
"0" when no loan has carried a term.object
When the book could in principle have turned liquid, absent new borrows.
null when unreadable.Show child attributes
Show child attributes
string
Unix seconds: the latest due date plus the longest grace period.
null when no loan carries a term.boolean
false while any open-ended principal is outstanding. No horizon exists then, and withdrawals depend on borrower repayment.boolean
true when the horizon is bounded, set and the book holds loans.string
Present when
applies is true. OPEN_LOANS when the horizon was tightened to the open loans’ own due dates, HIGH_WATER_MARK when it rests on latestDueAt.boolean
true when the market’s terminal due date has passed. The contract then refuses every new loan, while repayment, collateral release and withdrawals stay open. null when unreadable.string
Why, in words, when
newLoansClosed is true. Otherwise null.Liquidity routing
object
Show child attributes
Show child attributes
string
What a new loan can draw from the pool itself right now, in borrow asset units:
availableLiquidity less the reserve earmark. Vault liquidity is not in this figure.boolean
Whether the market may draw on its registered vaults at the moment a loan opens and its own pool runs short.
null when unreadable.boolean
true on current markets, where only the operator wallet and the vaults the market admin registered may add liquidity directly. false on the earlier generation. null when unreadable.string
Share of the pool’s liquidity held back from borrowing, in basis points. Withdrawals may still consume it.
integer
The same value as an integer.
Gate a borrow control on
borrowableLiquidity plus, on a market with useVaultLiquidity, what its vaults can still draw. Open Loan checks both before it returns calldata and refuses a loan neither can fund with INSUFFICIENT_LIQUIDITY.Fees
object
Show child attributes
Show child attributes
string
FIXED_SHARES on current markets, which pay the fixed 8 percent operator share and 5 percent distributor share. OFFERED_SHARE on the earlier generation, which pays the operator share offered at deployment and no distributor share. null when unreadable.string
The distributor share in basis points:
"500" on FIXED_SHARES, "0" on OFFERED_SHARE, null when unreadable.string
Present only when the stored operator share had to be corrected from the factory on this read. Get Market always carries it.
string
The wallet operator fees are paid to, lowercased, or
null before a lender of record takes the market.string
Operator fees accrued and not yet swept, in borrow asset units.
null when unreadable. operatorFeesPayableRaw carries the same figure in base units.string
Distributor fees accrued and not yet swept, in borrow asset units.
distributorFeesPayableRaw carries base units.string
The insurance fund’s share of interest, accrued and not yet swept into the fund, in borrow asset units.
protocolFeesPayableRaw carries base units.string
Trusset infrastructure fees accrued and not yet swept, in borrow asset units.
infrastructureFeesPayableRaw carries base units.Rate Derivation
The interest model’s rate at the current utilization iscurveBorrowRate. When the contract reports a zero rate, it is computed from a default curve instead. borrowRate is that figure, unless the model stamps a fixed rate onto new loans, in which case it is the stamp.
supplyRate is borrowRate * utilization * lpFactor, where lpFactor is the share of repaid interest that reaches the liquidity providers. The chain answers for that share. On a FIXED_SHARES market the 15 percent Trusset infrastructure fee comes off first. The 8 percent operator share and the 5 percent distributor share are taken from the remainder, and the market’s protocolFeeRate from what is left after them. On an OFFERED_SHARE market the operator share offered at deployment takes the place of the two fixed shares.
When the chain has never answered for the factor, the calculation falls back to a flat 0.75. That is an estimate, not the market’s economics.
All rates are basis points, so divide by 100 to get a percentage.
On a
FIXED market an outstanding loan pays the rate stamped when it opened. That can differ from today’s stamp if the rate model owner has changed it since. borrowRate and fixedStampRateBps describe the loan that would open now.curl "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/metrics" \
-H "X-API-Key: trusset_your_key_here"
const res = await fetch(
`https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}/metrics`,
{ headers: { 'X-API-Key': 'trusset_your_key_here' } }
);
const { data } = await res.json();
if (!data.isOnChain) throw new Error('Market metrics unavailable');
console.log(`Borrow APR ${(Number(data.borrowRate) / 100).toFixed(2)}%`);
{
"success": true,
"data": {
"isOnChain": true,
"paused": false,
"liquidationContract": "0x067A3FeEA46649AdAd8e31c33B3a4D8774b8d8cF",
"priceSource": "NAV",
"totalDeposits": "1000000.0",
"totalBorrows": "250000.0",
"availableLiquidity": "750000.0",
"utilizationRate": "2500",
"borrowRate": "450",
"supplyRate": "83.1938",
"curveBorrowRate": "450",
"totalShares": "998712.4",
"totalCollateral": "5000.0",
"activeLoans": 4,
"totalLoansCreated": 11,
"activeAuctions": 0,
"totalAuctions": 0,
"pendingLiquidations": 0,
"pendingLiquidationDebt": "0.0",
"auctionModule": null,
"useVaultLiquidity": true,
"operatorFeesPayable": "264.03",
"operatorFeesPayableRaw": "264030000",
"protocolFeesPayable": "0.0",
"protocolFeesPayableRaw": "0",
"infrastructureFeesPayable": "130.09",
"infrastructureFeesPayableRaw": "130090000",
"distributorFeesPayable": "22.43",
"distributorFeesPayableRaw": "22430000",
"operatorWallet": "0x4e91a7c05d3b62f18a0c94e7db2358f1c60a4e93",
"feeShareGeneration": "FIXED_SHARES",
"distributorShare": "500",
"vaultOnlyLiquidity": true,
"rateMode": "CLAMPED",
"rateFloor": "200",
"rateCap": "1200",
"maxFixedRate": null,
"reserveRatio": "500",
"maxLoanDuration": "15552000",
"termGracePeriod": "432000",
"terminalDueDate": null,
"termPenalty": "300",
"marketDueFloor": null,
"allowExtension": true,
"fixedStampRateBps": 0,
"stampsFixedRate": false,
"reserveRatioBps": 500,
"borrowableLiquidity": "700000.0",
"latestDueAt": "1805616000",
"exitHorizon": {
"horizon": "1806048000",
"bounded": true,
"applies": true,
"basis": "OPEN_LOANS"
},
"newLoansClosed": false,
"newLoansClosedReason": null,
"termConfig": {
"maxLoanDuration": "15552000",
"termGracePeriod": "432000",
"terminalDueDate": "0",
"marketDueFloor": "0",
"termPenaltyBps": 300,
"allowExtension": true,
"termStamping": "PER_LOAN"
}
}
}
{
"success": true,
"data": {
"isOnChain": false,
"totalDeposits": "0",
"totalBorrows": "0",
"availableLiquidity": "0",
"utilizationRate": "0",
"borrowRate": "200",
"supplyRate": "0",
"pendingLiquidations": 0,
"pendingLiquidationDebt": "0",
"paused": null,
"readFailed": true
}
}
{
"success": false,
"error": {
"code": "NO_MARKET_ADDRESS",
"message": "No on-chain address"
}
}
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 |
MARKET_NOT_FOUND | 404 | No market with this ID on your instance |
⌘I
curl "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/metrics" \
-H "X-API-Key: trusset_your_key_here"
const res = await fetch(
`https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}/metrics`,
{ headers: { 'X-API-Key': 'trusset_your_key_here' } }
);
const { data } = await res.json();
if (!data.isOnChain) throw new Error('Market metrics unavailable');
console.log(`Borrow APR ${(Number(data.borrowRate) / 100).toFixed(2)}%`);
{
"success": true,
"data": {
"isOnChain": true,
"paused": false,
"liquidationContract": "0x067A3FeEA46649AdAd8e31c33B3a4D8774b8d8cF",
"priceSource": "NAV",
"totalDeposits": "1000000.0",
"totalBorrows": "250000.0",
"availableLiquidity": "750000.0",
"utilizationRate": "2500",
"borrowRate": "450",
"supplyRate": "83.1938",
"curveBorrowRate": "450",
"totalShares": "998712.4",
"totalCollateral": "5000.0",
"activeLoans": 4,
"totalLoansCreated": 11,
"activeAuctions": 0,
"totalAuctions": 0,
"pendingLiquidations": 0,
"pendingLiquidationDebt": "0.0",
"auctionModule": null,
"useVaultLiquidity": true,
"operatorFeesPayable": "264.03",
"operatorFeesPayableRaw": "264030000",
"protocolFeesPayable": "0.0",
"protocolFeesPayableRaw": "0",
"infrastructureFeesPayable": "130.09",
"infrastructureFeesPayableRaw": "130090000",
"distributorFeesPayable": "22.43",
"distributorFeesPayableRaw": "22430000",
"operatorWallet": "0x4e91a7c05d3b62f18a0c94e7db2358f1c60a4e93",
"feeShareGeneration": "FIXED_SHARES",
"distributorShare": "500",
"vaultOnlyLiquidity": true,
"rateMode": "CLAMPED",
"rateFloor": "200",
"rateCap": "1200",
"maxFixedRate": null,
"reserveRatio": "500",
"maxLoanDuration": "15552000",
"termGracePeriod": "432000",
"terminalDueDate": null,
"termPenalty": "300",
"marketDueFloor": null,
"allowExtension": true,
"fixedStampRateBps": 0,
"stampsFixedRate": false,
"reserveRatioBps": 500,
"borrowableLiquidity": "700000.0",
"latestDueAt": "1805616000",
"exitHorizon": {
"horizon": "1806048000",
"bounded": true,
"applies": true,
"basis": "OPEN_LOANS"
},
"newLoansClosed": false,
"newLoansClosedReason": null,
"termConfig": {
"maxLoanDuration": "15552000",
"termGracePeriod": "432000",
"terminalDueDate": "0",
"marketDueFloor": "0",
"termPenaltyBps": 300,
"allowExtension": true,
"termStamping": "PER_LOAN"
}
}
}
{
"success": true,
"data": {
"isOnChain": false,
"totalDeposits": "0",
"totalBorrows": "0",
"availableLiquidity": "0",
"utilizationRate": "0",
"borrowRate": "200",
"supplyRate": "0",
"pendingLiquidations": 0,
"pendingLiquidationDebt": "0",
"paused": null,
"readFailed": true
}
}
{
"success": false,
"error": {
"code": "NO_MARKET_ADDRESS",
"message": "No on-chain address"
}
}
