# Get latest lending data (paginated by lender)

Endpoint reference for the 1delta API. Index: https://docs.1delta.io/llms.txt · every endpoint: https://docs.1delta.io/llms-full.txt

---

### GET /v1/data/lending/latest

- operationId: `lending-latest`
- docs: https://docs.1delta.io/1delta-api/lending-latest/
- markdown: https://docs.1delta.io/1delta-api/lending-latest.md
- tags: Lending (Data)

Get latest lending data (paginated by lender)

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`](https://docs.1delta.io/1delta-api/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](https://docs.1delta.io/1delta-api/lending-deposit/)/[borrow](https://docs.1delta.io/1delta-api/lending-borrow/) actions, and to **MAKE** your own offer see [`/v1/actions/midnight/make`](https://docs.1delta.io/1delta-api/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.
- **`status`** — `upcoming` | `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.

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `chains` | query | string[] | yes | Chain IDs to query (repeatable, CSV also accepted) |
| `lenders` | query | string[] | yes | Lender keys to fetch (repeatable, CSV also accepted). Max 20 per request. See the `LenderId` schema for the full set of accepted values. |
| `maxRiskScore` | query | integer | no | Max risk score (1–5). Defaults to 4. |
| `terms` | query | "digest" \| "full" \| "none" | no | Term-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. |
| `includeOffers` | query | boolean | no | Order-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`** — Latest lending data

| Field | Type | Description |
| --- | --- | --- |
| `success` | true |  |
| `data` | object | Latest lending market data as a flat list of lender/chain entries. Returns only the lender keys requested via `lenders=…` (max 20 per request). |
| `data.count` | integer | Number of lender/chain entries |
| `data.items` | object[] | Flat array of lender/chain entries |
| `data.items[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. |
| `data.items[].lenderInfo` | object | Protocol/lender metadata (name, logo). |
| `data.items[].lenderInfo.key` | string | Lender key identifier |
| `data.items[].lenderInfo.name` | string | Human-readable lender name |
| `data.items[].lenderInfo.logoURI` | string | Lender logo URL |
| `data.items[].lastFetched` | number | Epoch ms of latest snapshot |
| `data.items[].totalDepositsUsd` | number | Total deposits across all markets in USD |
| `data.items[].totalDebtUsd` | number | Total debt across all markets in USD |
| `data.items[].tvlUsd` | number | Total value locked in USD (deposits - debt) |
| `data.items[].params` | object | Lender-specific parameters. Only present for Morpho/Lista lenders (e.g. `{ market: { … } }`). |
| `data.items[].fixedTerm` | object | Fixed-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[].fixedTerm.model` | "lista" \| "midnight" \| "term" \| "exactly" \| "teller" \| "termmax" | Underlying fixed-term protocol shape. |
| `data.items[].fixedTerm.maturity` | integer | Single fixed calendar maturity, unix seconds. Absent for rolling-duration menus (Lista) and multi-maturity markets (Exactly — the menu lives on `terms[]`). |
| `data.items[].fixedTerm.fees` | object | Market-level fees: `continuousFeeApr` (%/yr lender-side haircut, Midnight), `settlementFee` (fraction at the current TTM, Midnight), `latePenaltyApr` (%/yr on overdue debt, Exactly), `originationFeePercent` (upfront % of principal, Teller). Empty for lenders without them. |
| `data.items[].fixedTerm.earlyRepay` | object | Early-repayment policy: `{ kind: "none" \| "penalty" \| "discount" }`. `none` = exit any time at market price; `penalty` = per-loan penalty (amount is position-level); `discount` = repaying early costs LESS than face value (Exactly). |
| `data.items[].fixedTerm.provider` | object | Who fronts the term: `{ kind: "broker" \| "orderbook" \| "auction" \| "pool", address? }`. `auction` markets carry the `auction` window below and can only be borrowed inside a round. |
| `data.items[].fixedTerm.auction` | object | Origination window for a fixed-term market whose terms are only obtainable during a bounded round rather than continuously — Term Finance (`fixedTerm.provider.kind = "auction"`). Served on `fixedTerm.auction`; ABSENT on lenders whose terms are continuously available, and absent is NOT the same as `closed`. This is the difference between "the rate card is empty right now" and "this market cannot be borrowed at all": between rounds a Term repo still has a maturity, collateral params and a last-cleared rate, but nothing can be borrowed. Most repos are between rounds at any given time. |
| `data.items[].fixedTerm.auction.status` | "upcoming" \| "open" \| "revealing" \| "closed" | `upcoming` — a round is listed but not yet accepting submissions. `open` — accepting sealed bids/offers. `revealing` — bidding shut, sealed prices revealing and the round clearing. `closed` — no round is listed. Snapshot at fetch time; re-derive from the timestamps against the current clock when reading a cached response. |
| `data.items[].fixedTerm.auction.canBorrow` | boolean | Can a NEW borrow be opened right now? **Gate the borrow CTA on this**, not on `status` and not on the presence of a rate — it stays correct if more statuses are added. True only inside an open round: Term borrow origination is a sealed bid, so there is no other entry point. |
| `data.items[].fixedTerm.auction.canLend` | boolean | Can a NEW lend position be opened right now? Deliberately independent of `canBorrow` — the primary auction is only one of two lend surfaces, and buying repo tokens on the secondary market works between rounds. A closed round therefore leaves the market **lend-only**, not inert; greying out the whole market would be wrong. |
| `data.items[].fixedTerm.auction.secondsUntilClose` | integer | Seconds until submissions close (`revealTime − now`). Absent unless a round is open. A snapshot — for a live countdown derive from `revealTime`, since responses are cached. |
| `data.items[].fixedTerm.auction.implications` | string[] | Ready-to-display consequences of this market's origination model, most important first (same convention as `params.market.teller.implications`). Auction mechanics are unusual enough that showing only a rate misleads. |
| `data.items[].fixedTerm.auction.id` | string | Auction round id. Absent when `status: "closed"`. |
| `data.items[].fixedTerm.auction.startTime` | integer | Submissions open, unix seconds. Absent when closed. |
| `data.items[].fixedTerm.auction.revealTime` | integer | Submissions CLOSE and sealed prices begin revealing, unix seconds — **the deadline to act**. Absent when closed. |
| `data.items[].fixedTerm.auction.endTime` | integer | Round clears, unix seconds. Equal to `revealTime` on current deployments. Absent when closed. |
| `data.items[].fixedTerm.auction.minBorrowAmount` | string | Minimum bid (borrow) size for this round, loan-token BASE units. A real floor (e.g. `"1000000000"` = 1000 USDC) — a smaller amount cannot be submitted at all, so validate before building the action rather than surfacing a failed transaction. |
| `data.items[].fixedTerm.auction.minLendAmount` | string | Minimum offer (lend) size for this round, loan-token BASE units. |
| `data.items[].markets` | object[] | Individual lending markets for this lender on this chain |
| `data.items[].markets[].lenderKey` | string | Protocol identifier |
| `data.items[].markets[].poolId` | string | Pool/vault address or protocol-specific ID |
| `data.items[].markets[].depositRate` | number | Deposit APR (percent) |
| `data.items[].markets[].variableBorrowRate` | number | Variable borrow APR (percent) |
| `data.items[].markets[].stableBorrowRate` | number | Stable borrow APR (percent) |
| `data.items[].markets[].intrinsicYield` | number | Intrinsic yield APR from underlying asset (e.g. stETH staking) |
| `data.items[].markets[].totalDeposits` | number | Total deposits in token units |
| `data.items[].markets[].totalDebtStable` | number | Total stable debt in token units |
| `data.items[].markets[].totalDebt` | number | Total variable debt in token units |
| `data.items[].markets[].totalLiquidity` | number | Available liquidity (totalDeposits - totalDebt) in token units |
| `data.items[].markets[].totalDepositsUsd` | number | Total deposits in USD |
| `data.items[].markets[].totalDebtStableUsd` | number | Total stable debt in USD |
| `data.items[].markets[].totalDebtUsd` | number | Total variable debt in USD |
| `data.items[].markets[].totalLiquidityUsd` | number | Available liquidity in USD |
| `data.items[].markets[].utilization` | number | Utilization ratio (totalDebt / totalDeposits) |
| `data.items[].markets[].decimals` | integer | Token decimals — divide raw amounts by `10 ** decimals`. |
| `data.items[].markets[].underlyingInfo` | object | Nested asset metadata, oracle prices, and market prices for a lending market. |
| `data.items[].markets[].underlyingInfo.asset` | object | Token metadata for an underlying asset. |
| `data.items[].markets[].underlyingInfo.oraclePrice` | object | On-chain oracle price data. |
| `data.items[].markets[].underlyingInfo.prices` | object | Market prices for an asset with 24h comparison. |
| `data.items[].markets[].oracleInfo` | object | Oracle 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[].oracleInfo.feeds` | object[] | Per-feed classifications, ordered worst-first. |
| `data.items[].markets[].oracleInfo.worstScore` | integer | Highest (worst) `score` across `feeds`. |
| `data.items[].markets[].oracleInfo.worstBand` | "LOW" \| "MEDIUM" \| "HIGH" \| "CRITICAL" | Band of the worst feed. |
| `data.items[].markets[].caps` | object | Supply, borrow, and debt ceiling caps for a lending market. |
| `data.items[].markets[].caps.borrowCap` | number | Maximum borrowable amount (token units) |
| `data.items[].markets[].caps.supplyCap` | number | Maximum depositable amount (token units) |
| `data.items[].markets[].caps.debtCeiling` | string | Isolation-mode debt ceiling |
| `data.items[].markets[].flags` | object | Boolean flags describing the operational status of a lending market. Values may be null if unavailable from the protocol. |
| `data.items[].markets[].flags.isActive` | boolean | Whether the market is active |
| `data.items[].markets[].flags.isFrozen` | boolean | Whether the market is frozen (no new deposits/borrows) |
| `data.items[].markets[].flags.hasStable` | boolean | Whether stable-rate borrowing is available |
| `data.items[].markets[].flags.borrowingEnabled` | boolean | Whether borrowing is enabled |
| `data.items[].markets[].flags.depositsEnabled` | boolean | Whether deposits are enabled |
| `data.items[].markets[].flags.collateralActive` | boolean | Whether the asset can be used as collateral |
| `data.items[].markets[].flags.variableBorrowDisabled` | boolean | Whether variable-rate borrowing is unavailable through 1delta for this market. `true` for Lista DAO fixed-term (brokered) markets, where borrows must go through the broker and pick a fixed term from `terms[]`. Together with a non-empty `terms[]` this is the canonical "brokered market" signal — such markets report `variableBorrowRate = 0` but cannot be borrowed variably. |
| `data.items[].markets[].rewards` | object[] | Active reward programs. Defaults to [] when none. |
| `data.items[].markets[].rewards[].asset` | string | Reward token address, lowercased. For a points program (`kind: "points"`) there is no token and this is a synthetic `points:<sourceId>` key. |
| `data.items[].markets[].rewards[].symbol` | string | Reward token symbol. Denormalized deliberately — reward tokens are routinely absent from the asset table (aMonUSDe, WMON, aHorRwaRLUSD are live examples), so a join would leave them unnamed. |
| `data.items[].markets[].rewards[].decimals` | integer | Token decimals — divide raw amounts by `10 ** decimals`. |
| `data.items[].markets[].rewards[].logoURI` | string | URL of the logo image. |
| `data.items[].markets[].rewards[].depositRate` | number | Reward APR on deposits |
| `data.items[].markets[].rewards[].variableBorrowRate` | number | Reward APR on variable borrows |
| `data.items[].markets[].rewards[].stableBorrowRate` | number | Reward APR on stable borrows |
| `data.items[].markets[].rewards[].kind` | string | `token` \| `points`. Points are NOT priceable and must be shown separately from any headline APR. |
| `data.items[].markets[].rewards[].claim` | string | How the reward is realized, i.e. whether the APR is bankable. `accrual` — claimable from the protocol on-chain; `merkl` — off-chain merkle distribution; `manual`. |
| `data.items[].markets[].rewards[].source` | string | LEGACY mechanism tag (`merkle`, `onchain-incentives`, `native`) — it cannot distinguish two programs on the same platform. Prefer `sourceId`. |
| `data.items[].markets[].rewards[].sourceId` | string | Stable program identifier, safe to key on: `merkl:aave`, `merkl:euler`, `merkl:morpho`, `dtrinity:rebate`. |
| `data.items[].markets[].rewards[].sourceLabel` | string | Display string for the program, e.g. `Merkl · Aave`. |
| `data.items[].markets[].rewards[].link` | string | Deep link to THIS program — the exact Merkl opportunity page, not a protocol homepage. |
| `data.items[].markets[].rewards[].endsAt` | number | Unix seconds the program stops paying. An APR with two weeks left is not the same product as a standing rate, so render it. |
| `data.items[].markets[].rewards[].startsAt` | number |  |
| `data.items[].markets[].rewards[].dailyRewardsUsd` | number | Program-wide payout rate in USD/day, as the source reports it. |
| `data.items[].markets[].rewards[].refs` | object | Platform identifiers verbatim — Merkl campaign ids and opportunity type, or the incentives-controller address for an on-chain program. For support and deduplication, not display. |
| `data.items[].markets[].config` | object | Risk config keyed by mode/category ID (e.g. "0" for default, "1" for e-mode) |
| `data.items[].markets[].terms` | object[] | Fixed-term rate card. Non-empty ⇒ this market offers fixed terms and a borrower picks a `termId`; `null` ⇒ a regular variable-rate market. Served by every fixed-term lender, not only Lista — on Exactly each entry is a maturity. On a Lista brokered market it is also the brokered-market signal (with `flags.variableBorrowDisabled`), and it sits only on the LOAN-token row, never the collateral one. This is the value DOMAIN a `capabilities[]` entry points at via `domainField`. |
| `data.items[].markets[].terms[].termId` | integer | Term identifier — MEANING IS LENDER-SPECIFIC. Exactly and TermMax: the pool/market unix MATURITY timestamp. Lista: the broker-defined product id. Teller: the duration in seconds (rolling term). Midnight and Term Finance: `0`, a placeholder (single maturity per market, so the id carries no information). Pass to `/v1/actions/lending/borrow?termId=…`. Numeric on-chain; some upstream feeds serialize it as a string — coerce with `Number()` when comparing. |
| `data.items[].markets[].terms[].depositApr` | number | Annualised fixed LEND rate at this maturity, in percent (Exactly only — its fixed pools quote both sides). |
| `data.items[].markets[].terms[].available` | number | Borrowable liquidity at this maturity in loan-token human units (Exactly only). |
| `data.items[].markets[].terms[].durationDays` | number | How long the position is locked at the fixed rate, in days (e.g. 7, 14, 30). |
| `data.items[].markets[].terms[].durationSecs` | number | Term duration in seconds (raw on-chain value). |
| `data.items[].markets[].terms[].apr` | number | Annualised borrow APR for this term, in **percent** (e.g. `3.85` = 3.85%). Same unit as `variableBorrowRate` / `stableBorrowRate`. For order-book markets (Midnight) this is the 0-notional top-of-book (cheapest) rate — see `aprAtAmount` for the size-weighted rate. |
| `data.items[].markets[].terms[].aprAtAmount` | number | Size-weighted (VWAP) borrow APR % at the supplied debt notional, for order-book fixed-term markets (Morpho Midnight): the borrow book filled cheapest-first, `(Σ filledᵢ·aprᵢ)/amount`. Present only when an amount is supplied AND the term carries an order-book `ladder`; broker rate cards (Lista, single flat rate) omit it and `apr` already applies at any size. |
| `data.items[].markets[].terms[].fillable` | number | Total loan-token depth in this term's order book — the maximum borrow openable at this maturity. Present only for order-book terms with an amount supplied. |
| `data.items[].markets[].terms[].capped` | boolean | True when the supplied debt notional exceeds `fillable` — the book can't fully fund the borrow at this maturity (`aprAtAmount` is then the drain-the-book VWAP). |
| `data.items[].markets[].terms[].ladder` | object[] | Order-book borrow ladder (best-borrow first) for order-book fixed-term markets (Midnight). Only serialized when `depth=true` (bulky). `aprAtAmount` is the pre-computed size-weighted rate; use this to re-derive it at any amount. |
| `data.items[].markets[].capabilities` | object[] | Actions this row supports, declared rather than inferred. Complete over the actions it models — see `MarketCapability`. Defaults to `[]`. |
| `data.items[].markets[].capabilities[].action` | "refinance" \| "set-mode" | `refinance` — move this market's debt into a different term without changing the assets or the size (called "roll-over" when the source is itself a fixed loan); builds at `/v1/actions/loop/refinance`. `set-mode` — switch the ACCOUNT's active risk mode (Aave e-mode); builds at `/v1/actions/lending/mode`. Absent on lenders with no switchable mode — including LlamaLend, whose mode slot carries a BAND COUNT fixed at open, and every Morpho/Lista-shaped market, which has no mode at all. |
| `data.items[].markets[].capabilities[].parameter` | "term" \| "mode" | Which parameter the action changes. `rate` (the Liquity family's interest-rate adjust) is the same verb on a third knob and appears here when built. |
| `data.items[].markets[].capabilities[].scope` | "position" \| "account" | What the change applies to. `position` — acts on ONE loan, which the caller must identify. `account` — one value for the whole (lender, chain, account); it is declared on every row of that lender because it is true of all of them, so a consumer showing one account-level control per lender should read it off any row rather than per market. |
| `data.items[].markets[].capabilities[].endpoint` | string | The endpoint that builds this action. |
| `data.items[].markets[].capabilities[].requires` | string[] | Params required BEYOND the universal set (`marketUid`, `operator`, `amount`). For `refinance`: `termId` (the TARGET term) — `fromLoanId` is optional by design, omitted means the float/dynamic position. For `set-mode`: `lender`, `chainId` and `mode`, since it is account-scoped and takes no market. |
| `data.items[].markets[].capabilities[].domainField` | "terms" \| "config" | Which field on this row holds the allowed values for `requires` — never a second copy of it. `terms` is the published rate card; `config` is the risk-config map, whose KEYS are the mode ids and whose `label` is each mode's name. |
| `data.items[].markets[].broker` | string | Lista 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). |
| `data.items[].markets[].collateralProvider` | string | Lista DAO collateral-provider contract for this market. When set (non-zero), Moolah gates `supplyCollateral`/`withdrawCollateral` behind it, so collateral deposits/withdrawals must route through this provider rather than calling Moolah directly (the SDK/worker handle this). Set for markets whose collateral is a Lista-managed token (e.g. slisBNB); `null` for plain ERC-20 collateral. |
| `data.items[].markets[].loanProvider` | string | Lista DAO loan-token provider contract for this market (e.g. the native-WBNB wrapper provider). When set, loan-token operations are gated behind it; for brokered markets the broker handles the debt side. Informational — consumers do not pass it; the SDK/worker resolve routing automatically. |
| `data.items[].markets[].closeFactor` | number | Max fraction of a borrower's debt repayable in a single liquidation (0-1). Aave ~0.5 (rises to 1 below the close-factor health threshold), Compound V2 closeFactorMantissa; 1 (full liquidation) for isolated / credit-account protocols (Compound V3, Morpho, Euler, Fluid, Gearbox, Dolomite, Silo). |
| `data.items[].markets[].targetHealthFactor` | number | Liquidation target health factor (e.g. 1.05). Set only by protocols that liquidate to a target HF rather than a fixed close factor (Aave V4, spoke-level); omitted otherwise. |
| `data.items[].markets[].lenderInfo` | object | Protocol/lender metadata (name, logo). |
| `data.items[].markets[].lenderInfo.key` | string | Lender key identifier |
| `data.items[].markets[].lenderInfo.name` | string | Human-readable lender name |
| `data.items[].markets[].lenderInfo.logoURI` | string | Lender logo URL |
| `data.items[].markets[].termSheet` | object | Structured description of this market’s lend and borrow offer. Shape depends on the `terms` query param: `digest` (default) or `full`. Absent when `terms=none`. |
| `data.items[].markets[].termSheet.schemaVersion` | integer |  |
| `data.items[].markets[].termSheet.profileId` | string |  |
| `data.items[].markets[].termSheet.marketUid` | string | Market identifier, formatted `lender:chainId:address`. |
| `data.items[].markets[].termSheet.supply` | object |  |
| `data.items[].markets[].termSheet.borrow` | object |  |
| `data.items[].markets[].termSheet.oracle` | object |  |
| `data.items[].markets[].termSheet.governance` | object |  |
| `data.items[].markets[].termSheet.utilization` | number | Market utilization, as a fraction between 0 and 1. |
| `actions` | null |  |

**Example response**

```json
{
  "success": true,
  "data": {
    "count": 1,
    "items": [
      {
        "chainId": "8453",
        "lenderInfo": {
          "key": "AAVE_V3",
          "name": "Aave V3",
          "logoURI": "https://raw.githubusercontent.com/1delta-DAO/protocol-icons/main/lender/aave_v3.webp"
        },
        "lastFetched": 1,
        "totalDepositsUsd": 1,
        "totalDebtUsd": 1,
        "tvlUsd": 1,
        "params": {},
        "fixedTerm": {
          "model": "term",
          "maturity": 1,
          "fees": {},
          "earlyRepay": {},
          "provider": {},
          "auction": {
            "status": "open",
            "canBorrow": true,
            "canLend": true,
            "secondsUntilClose": 263000,
            "implications": [
              "string"
            ],
            "id": "string",
            "startTime": 1,
            "revealTime": 1,
            "endTime": 1,
            "minBorrowAmount": "1000000000",
            "minLendAmount": "1000000000"
          }
        },
        "markets": [
          {
            "lenderKey": "AAVE_V3",
            "poolId": "string",
            "depositRate": 1,
            "variableBorrowRate": 1,
            "stableBorrowRate": 1,
            "intrinsicYield": 1,
            "totalDeposits": 1,
            "totalDebtStable": 1,
            "totalDebt": 1,
            "totalLiquidity": 1,
            "totalDepositsUsd": 1,
            "totalDebtStableUsd": 1,
            "totalDebtUsd": 1,
            "totalLiquidityUsd": 1,
            "utilization": 1,
            "decimals": 1,
            "underlyingInfo": {
              "asset": {
                "chainId": "1",
                "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
                "symbol": "USDC",
                "name": "USD Coin",
                "decimals": 6,
                "logoURI": "string",
                "assetGroup": "USDC",
                "currencyId": "string",
                "props": {}
              },
              "oraclePrice": {
                "oraclePrice": 1,
                "oraclePriceUsd": 1
              },
              "prices": {
                "priceUsd": 1,
                "priceTs": "2026-01-01T00:00:00Z",
                "priceUsd24h": 1,
                "priceTs24h": "2026-01-01T00:00:00Z",
                "priceChange24h": 1
              }
            },
            "oracleInfo": {
              "feeds": [
                {
                  "asset": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
                  "oracle": "string",
                  "provider": "string",
                  "priceDescription": "string",
                  "intendedPair": "string",
                  "correctOracle": true,
                  "denominatorMatch": true,
                  "fixedRate": true,
                  "score": 1,
                  "band": "LOW",
                  "flags": []
                }
              ],
              "worstScore": 1,
              "worstBand": "LOW"
            },
            "caps": {
              "borrowCap": 1,
              "supplyCap": 1,
              "debtCeiling": "string"
            },
            "flags": {
              "isActive": true,
              "isFrozen": true,
              "hasStable": true,
              "borrowingEnabled": true,
              "depositsEnabled": true,
              "collateralActive": true,
              "variableBorrowDisabled": true
            },
            "rewards": [
              {
                "asset": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
                "symbol": "string",
                "decimals": 1,
                "logoURI": "string",
                "depositRate": 1,
                "variableBorrowRate": 1,
                "stableBorrowRate": 1,
                "kind": "string",
                "claim": "string",
                "source": "string",
                "sourceId": "string",
                "sourceLabel": "string",
                "link": "string",
                "endsAt": 1,
                "startsAt": 1,
                "dailyRewardsUsd": 1,
                "refs": {}
              }
            ],
            "config": {},
            "terms": [
              {
                "termId": 2,
                "depositApr": 1,
                "available": 1,
                "durationDays": 7,
                "durationSecs": 604800,
                "apr": 3.85,
                "aprAtAmount": 1,
                "fillable": 1,
                "capped": true,
                "ladder": [
                  {}
                ]
              }
            ],
            "capabilities": [
              {
                "action": "refinance",
                "parameter": "term",
                "scope": "position",
                "endpoint": "/v1/actions/loop/refinance",
                "requires": [
                  "termId"
                ],
                "domainField": "terms"
              }
            ],
            "broker": "0x1fa26015286d1270343d7526c60bd57ab6be8b54",
            "collateralProvider": "0x33f7a980a246f9b8fea2254e3065576e127d4d5f",
            "loanProvider": "0x367384c54756a25340c63057d87ea22d47fd5701",
            "closeFactor": 0.5,
            "targetHealthFactor": 1.05,
            "lenderInfo": {
              "key": "AAVE_V3",
              "name": "Aave V3",
              "logoURI": "https://raw.githubusercontent.com/1delta-DAO/protocol-icons/main/lender/aave_v3.webp"
            },
            "termSheet": {
              "schemaVersion": 1,
              "profileId": "string",
              "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
              "supply": {},
              "borrow": {},
              "oracle": {},
              "governance": {},
              "utilization": 1
            }
          }
        ]
      }
    ]
  }
}
```

**Response `400`** — Validation error

**Response `429`** — Rate limited. Unauthenticated callers share a per-IP budget; send an `x-api-key` header to lift it. Retry with exponential backoff.

**Response `500`** — Unexpected server error. Safe to retry with backoff.

**Response `502`** — An upstream data source or protocol origin failed (`error.code` is `ORIGIN_FAILED`). `error.details` carries the per-origin status. This is also what a missing or malformed required parameter currently returns, rather than a 400.
