Skip to main content

Get latest lending data (paginated by lender)

GET 

/v1/data/lending/latest

Returns latest per-market lending data for the requested chains, scoped to a specific page of lender keys.

Pagination

Both chains and lenders are required. A maximum of 20 lender keys may be supplied per request. Use GET /v1/data/lending/lenders to enumerate available lender keys (sorted by TVL) and page through them in batches of up to 20:

GET /v1/data/lending/lenders?chains=1,8453            → enumerate keys
GET /v1/data/lending/latest?chains=1,8453&lenders=k1,…,k20 → page 1
GET /v1/data/lending/latest?chains=1,8453&lenders=k21,…,k40 → page 2

Breaking changes vs previous /lending/latest

  • lenders is now required.
  • Hard cap of 20 lender keys per request.
  • Top-level lenderKey field is removed from items — use lenderInfo.key.

Lista DAO fixed-term (brokered) markets: a market is brokered when its terms[] rate card is non-empty and flags.variableBorrowDisabled === true. Such markets report variableBorrowRate = 0 but cannot be borrowed variably through 1delta — read terms[] for the available fixed terms and their APRs, and broker for the gateway contract. See the MarketTerm schema.

Morpho Midnight order-book markets (MORPHO_MIDNIGHT_<id>): liquidity is an order book of maker offers, not a pool. Pass includeOffers=true to attach the live two-sided ladder to each such market's loan leg: offers (bids — the demand a borrower TAKES) and lendOffers (asks — the supply a lender TAKES), both best-first with per-level aprPct, assets, assetsUsd, and cumulativeAssets. Plain pool markets return no offers (their single rate suffices). This is the read side of TAKE; to fill offers use the standard deposit/borrow actions, and to MAKE your own offer see /v1/actions/midnight/make.

Teller markets (TELLER_<pool>): fixed-term, fixed-APR pool loans with TIME-based liquidation — collateral is seized only on a missed payment past the market window, never on a price move (no margin calls). fixedTerm.model = "teller", provider.kind = "pool", rolling duration up to teller.maxLoanDuration. ⚠ AGGRESSIVE default terms — surface these prominently: on default the borrower can lose their ENTIRE escrowed collateral (a liquidator seizes all of it, not just the amount owed — at a 50% LTV that's ~2× the borrowed value), and the grace window after the term can be very short (params.market.teller.paymentDefaultDuration, observed as low as 300 s / 5 min). There is also an upfront origination fee (teller.originationFeePercent = marketFeeBps + protocolFeeBps, also on fixedTerm.fees.originationFeePercent). The market descriptor (params.market.teller) carries the read-side facts the UI should surface: implications (a ready-to-display string list — lead with the full-collateral-liquidation warning), paymentDefaultDuration, originationFeePercent, requiresBorrowerAttestation (this market only lets whitelisted borrowers open loans — a non-attested account is rejected at borrow time, so gate the borrow CTA on this flag), and marketOpen (a closed market reports borrowingEnabled = false). Borrowing is one atomic POST /v1/actions/lending/deposit-and-borrow; closing is a FULL POST /v1/actions/lending/withdraw-and-repay (repays everything and releases all collateral — Teller has no partial collateral withdrawal; posId = the bidId to close). Borrower positions are bidId-keyed sub-accounts.

Term Finance markets (TERM_FINANCE_<termRepoId>): fixed-rate, fixed-maturity tri-party repo. One repo per maturity, so a pair has many lender keys that differ only by date — read lenderInfo.name (e.g. "Term USDC / wstETH — 2026-09-03") rather than the raw key. fixedTerm.model = "term", provider.kind = "auction", flags.variableBorrowDisabled = true (there is no variable rate — a variableBorrowRate of 0 is NOT a free borrow).

Borrowing is only possible inside a scheduled sealed-bid auction round, and most repos are between rounds at any given time (live Ethereum book: typically ~3 of ~84). fixedTerm.auction carries the window and is the gate:

  • canBorrow — gate the borrow CTA on this, NOT on status or on the presence of a rate. It is true only while a round is accepting submissions.
  • canLend — deliberately independent of canBorrow: lending also works between rounds by buying repo tokens on the secondary market, so a closed round leaves the market lend-only, not inert. Do not grey out the whole market.
  • statusupcoming | open | revealing (bidding shut, prices revealing) | closed (no round listed).
  • secondsUntilClose, startTime, revealTime (the deadline to act), endTime — unix seconds; derive a live countdown from revealTime rather than trusting secondsUntilClose against a cached response.
  • minBorrowAmount / minLendAmount — a real per-round floor in loan-token base units (e.g. 1000 USDC). A smaller amount cannot be submitted at all, so validate before building.
  • implications — ready-to-display string list, most important first (same convention as params.market.teller.implications).

terms[] is emitted ONLY while canBorrow is true, so an empty rate card on a Term market means "not borrowable right now", not "no offers". When a round is open on a repo that has never cleared, terms[] is legitimately empty and variableBorrowRate is 0: the rate is whatever you bid, set at clearing. Any rate shown outside an open round is the previous round's clearing rate — historical, not obtainable (it still prices the secondary lend book, which is why it is reported at all).

Term sheets (termSheet): every market carries a structured description of its lend and borrow offer under one shape, for every lender we serve — pool lenders, fixed-term lenders, CDPs and vaults alike. termSheet.supply and termSheet.borrow each answer rate, maturity, fees, exit terms, liquidation, counterparty and availability; termSheet.governance, .oracle, .utilization and .constraints describe the market as a whole. Absence of a side is meaningful: no borrow means the market cannot be borrowed.

Read info.headline and info.tags for a ready-to-render summary, and info.implications[] (ordered most-important-first) for the consequences that a rate alone hides — a Teller borrow can lose its ENTIRE collateral after a grace window as short as 300 s, a TermMax lender can be settled in collateral instead of the asset they lent, and a Liquity trove can be redeemed at par while perfectly healthy. coverage distinguishes "does not apply here" (notApplicable, e.g. Teller genuinely has no oracle) from "not classified yet" (pending) — a missing block is never a claim of absence.

Every string field is an OPEN enum: new members are added additively and MUST NOT break a client. Give every switch a default branch and fall back to info.headline, which is always populated.

Oracle risk: each market carries an oracleInfo object classifying its price oracle's feed correctness (provider, reported vs intended pair, a 0–100 worstScore/worstBand, and flags such as wrong-asset/correlated-proxy/cross-numeraire). This is distinct from the price-staleness signal in risk.breakdown[oracle]. See the OracleInfo schema for the full scoring model.

Plain-text reference — GET /v1/data/lending/latest

Parameters

ParameterInTypeRequiredDescription
chainsquerystring[]yesChain IDs to query (repeatable, CSV also accepted)
lendersquerystring[]yesLender keys to fetch (repeatable, CSV also accepted). Max 20 per request. See the LenderId schema for the full set of accepted values.
maxRiskScorequeryintegernoMax risk score (1–5). Defaults to 4.
termsquerydigest, full, nonenoTerm-sheet depth attached to every market as termSheet. digest (default) is the compact form — headline, tags, rate/maturity/exit/liquidation summary and the exposure ROLLUP, but no items[] and no long prose. full inlines the complete sheet including backedBy.items[] / acceptedCollateral.items[] and info.description + info.implications[]. none omits the field entirely. Every exposure item carries its own marketUid, so digest is not a dead end — resolve the ones you need in one call.
includeOffersquerybooleannoOrder-book markets (Morpho Midnight) only. When true, attach the live maker-offer ladder to each order-book market’s loan leg (offers = bids, lendOffers = asks). Ignored for pool markets. Defaults to false.

Response 200

FieldTypeDescription
successTrue
dataobjectLatest lending market data as a flat list of lender/chain entries. Returns only the lender keys requested via lenders=… (max 20 per request).
data.countintegerNumber of lender/chain entries
data.itemsobject[]Flat array of lender/chain entries
data.items[].chainIdstringEVM chain id, as a decimal string. See the ChainId schema.
data.items[].lenderInfoobjectProtocol/lender metadata (name, logo).
data.items[].lenderInfo.keystringLender key identifier
data.items[].lenderInfo.namestringHuman-readable lender name
data.items[].lenderInfo.logoURIstringLender logo URL
data.items[].lastFetchednumberEpoch ms of latest snapshot
data.items[].totalDepositsUsdnumberTotal deposits across all markets in USD
data.items[].totalDebtUsdnumberTotal debt across all markets in USD
data.items[].tvlUsdnumberTotal value locked in USD (deposits - debt)
data.items[].paramsobjectLender-specific parameters. Only present for Morpho/Lista lenders (e.g. { market: { … } }).
data.items[].fixedTermobjectFixed-term descriptor for this lender key. Absent/null on variable-rate lenders. For Term Finance read fixedTerm.auction.canBorrow before offering a borrow — most repos sit between auction rounds and cannot be borrowed even though they quote a rate.
data.items[].marketsobject[]Individual lending markets for this lender on this chain
data.items[].markets[].lenderKeystringProtocol identifier
data.items[].markets[].poolIdstringPool/vault address or protocol-specific ID
data.items[].markets[].depositRatenumberDeposit APR (percent)
data.items[].markets[].variableBorrowRatenumberVariable borrow APR (percent)
data.items[].markets[].stableBorrowRatenumberStable borrow APR (percent)
data.items[].markets[].intrinsicYieldnumberIntrinsic yield APR from underlying asset (e.g. stETH staking)
data.items[].markets[].totalDepositsnumberTotal deposits in token units
data.items[].markets[].totalDebtStablenumberTotal stable debt in token units
data.items[].markets[].totalDebtnumberTotal variable debt in token units
data.items[].markets[].totalLiquiditynumberAvailable liquidity (totalDeposits - totalDebt) in token units
data.items[].markets[].totalDepositsUsdnumberTotal deposits in USD
data.items[].markets[].totalDebtStableUsdnumberTotal stable debt in USD
data.items[].markets[].totalDebtUsdnumberTotal variable debt in USD
data.items[].markets[].totalLiquidityUsdnumberAvailable liquidity in USD
data.items[].markets[].utilizationnumberUtilization ratio (totalDebt / totalDeposits)
data.items[].markets[].decimalsintegerToken decimals — divide raw amounts by 10 ** decimals.
data.items[].markets[].underlyingInfoobjectNested asset metadata, oracle prices, and market prices for a lending market.
data.items[].markets[].oracleInfoobjectOracle feed-correctness classification for the market's price oracle(s). null when the market has no oracle classification. This is feed correctness — does the oracle price the right asset in the right unit — and is distinct from the price-staleness signal carried in risk.breakdown[oracle] (a 1–5 score). A market can have several feeds (Compound comets price each collateral asset; Fluid prices each vault side), so feeds is an array and worstScore/worstBand summarize the riskiest one. Scoring (per feed, additive): score = provider base + flag penalties, clamped 0–100. Provider base (oracle mechanism; first match wins): | Provider | Base | |---|---| | chainlink, price-cap | 10 | | redstone/pyth/chronicle/… and unrecognized | 18 | | composite / cross-feed | 22 | | exchange-rate / pendle-pt / LST rate adapters | 28 | | twap/uniswap/DEX | 30 | | fixed-rate / constant | 55 | Flag penalties (added on top): wrong-asset +45 · correlated-proxy +18 · cross-numeraire +18 · undecoded-source +8. Bands: LOW < 25 · MEDIUM 25–49 · HIGH 50–74 · CRITICAL ≥ 75.
data.items[].markets[].capsobjectSupply, borrow, and debt ceiling caps for a lending market.
data.items[].markets[].flagsobjectBoolean flags describing the operational status of a lending market. Values may be null if unavailable from the protocol.
data.items[].markets[].rewardsobject[]Active reward programs. Defaults to [] when none.
data.items[].markets[].configobjectRisk config keyed by mode/category ID (e.g. "0" for default, "1" for e-mode)
data.items[].markets[].termsobject[]Fixed-term rate card for Lista DAO brokered markets. Non-empty ⇒ the market is brokered (borrow via the broker, pick a termId); null ⇒ a regular variable-rate market. Together with flags.variableBorrowDisabled this is the canonical brokered-market signal.
data.items[].markets[].brokerstringLista DAO LendingBroker contract address — the mandatory gateway for the debt side (borrow/repay) of a brokered market. Present (non-zero) only for brokered markets. The borrow/repay calldata routes through this contract (the SDK and worker resolve it automatically).

Request

Responses

Latest lending data