# 1delta — Lending (Data) endpoints The Lending (Data) slice of https://docs.1delta.io/llms-full.txt (Data), split out so a single topic fits a small context window. Index: https://docs.1delta.io/llms.txt · this whole group: see the llms-*.txt files listed there · everything: https://docs.1delta.io/llms-full.txt --- ### GET /v1/data/lending/comparables - operationId: `comparable-rates-for-one-pair` - docs: https://docs.1delta.io/1delta-api/comparable-rates-for-one-pair/ - markdown: https://docs.1delta.io/1delta-api/comparable-rates-for-one-pair.md - tags: Lending (Data) Comparable rates for one pair The **N best comparable rates for a single pair**, priced at the caller’s size and holding period. One round-trip, small payload — built to sit behind a rate pill next to a borrow input. Unlike `/pairs/optimize` (rank every leveraged pair), this answers the question a borrow form asks: *I am about to borrow X of asset D against collateral C — what are the best rates for that same trade, at my size, over my horizon?* ## Three rates, deliberately kept apart - `aprPct` — what the venue advertises: spot at 0 notional, or top of book. - `aprAtAmountPct` — the same rate at **your size**. A utilization pool re-prices its whole balance to the post-borrow rate (marginal == average); an order book fills cheapest-first, so this is the VWAP of the tiers consumed. Null without an amount. - `effectiveAprPct` — the size-priced rate normalized to `horizonDays`. **This is what `rank` sorts on.** ## Horizon normalization A 4-week fixed rate and a floating pool are not comparable until both are priced over the same holding period. Each venue supplies a repayment rule: a Lista loan exited early pays roughly half the remaining term’s interest (`r·(T+h)/(2h)` — 1%/1yr exited at 6 months is **1.5% effective**); Midnight/Term charge no penalty but exiting means a resale at the then-current price (`horizon.priceRisk`); Exactly rebates unassigned earnings; a CDP’s one-time origination fee amortizes over the horizon, so it dominates on short holds. A horizon that outlasts the term assumes a roll at today’s rate and reports `locked: false`. Always render `horizon.locked` and `horizon.assumptions` next to the number — a normalized rate is not a contractual one. ## Obtainability is part of the answer Term Finance originates only inside periodic sealed-bid rounds; between rounds its rate card still quotes the LAST round’s clearing rate — real, but not takeable. Those rows are dropped by default and, with `includeUnobtainable=true`, returned flagged (`obtainable: false`, `quoteBasis: "last-clearing"`) and ranked last. A venue that cannot fund the requested size is marked `depth.capped` and demoted rather than ranked on a rate it can’t honour. ## Comparability filters (what makes this a comparison rather than a list) **Depth band** — `floor = min(minLiquidityRatio × anchor, liquidityFloorCapUsd)`, default `min(50% × anchor, $10M)`. A venue an order of magnitude shallower is a different product, and it is exactly those markets that quote absurd rates — a near-empty isolated market with reward emissions prices borrowing at **−25%**, a real number and a useless comparison against a $5B pool. The cap is not optional: a pure ratio breaks on the biggest pairs, where half of a $5B pool is a $2.5B floor nothing clears, so the comparison would come back empty exactly where alternatives matter most. The anchor is `referenceMarketUid`'s own depth when given, else the deepest candidate. `droppedIlliquid` + `liquidityFloorUsd` report it — the filter is never silent; `minLiquidityUsd` replaces the formula and `includeIlliquid=true` turns it off. **Stale venues.** A lender whose ingest lagged past the freshness window drops out of the underlying pairs view — which reads exactly like "that lender doesn't offer this pair". Those rows are excluded from ranking but **counted** (`droppedStale`, `staleMaxHours`), because a $19B deployment vanishing with no signal is worse than a short list. `includeStale=true` ranks them anyway. **One collateral basis.** When the caller pins no collateral (a standalone borrow form knows none), comparing "borrow USDC" across every collateral in existence is not a comparison. The server picks ONE representative collateral per chain — first hit in `collateralPreference` (default `ETH,BTC,USDC,USDT`), else the collateral group backing the deepest markets, which resolves to the wrapped native where neither is listed — and compares only venues backed by it. The choice comes back as `collateralBasis` (e.g. `{"1":"ETH"}`) so the UI can say *"vs WETH-backed"*. An explicit `collateral`/`collateralGroups` always wins and disables this. ## Rewards The headline rate folds in reward emissions (same composition as `/pairs/optimize`), which is why a borrow rate can be **negative**. That is real but transient, so each row also carries `rewardAprPct` and `aprExRewardsPct` — the structural cost without emissions. Ranking stays on the headline; showing both is the caller's job. ## Ranking `obtainable` first, then non-`capped`, then best `effectiveAprPct` (cheapest for a borrow, highest for a supply), then deepest liquidity as tie-break. Results are deduped to one row per `(chain, lender, market, term)` — the pairs view is combinatorial in the other leg, so without it the "5 best rates" would be five copies of the same market. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chainId` | query | string | no | Single chain ID. When set, asset filters operate on token addresses. Pass one for an actionable list — cross-chain rows are a comparison, not one executable position. See the `ChainId` schema for the full set of supported chains. | | `chainIds` | query | string | no | CSV of chain IDs. When two or more, asset filters operate on asset groups. See the `ChainId` schema for the full set of supported chains. | | `side` | query | "borrow" \| "supply" | no | Which leg to compare. | | `debt` | query | string | no | The borrowed asset — address (single chain) or asset group. Required for `side=borrow`. Aliases: `debts`, `debtGroups`. | | `debtGroups` | query | string | no | CSV of debt-side asset groups (works in any chain mode). | | `collateral` | query | string | no | The collateral asset. Required for `side=supply`; strongly recommended for `side=borrow` — a market that will not take your collateral is not a comparable. Aliases: `collaterals`, `collateralGroups`. | | `collateralGroups` | query | string | no | CSV of collateral-side asset groups (works in any chain mode). | | `amount` | query | number | no | Notional in TOKEN UNITS of the priced leg (the debt asset for a borrow). Requires exactly one asset on that side. | | `amountUsd` | query | number | no | Same notional in USD. Works with multi-asset selections. Mutually exclusive with `amount`. | | `horizonDays` | query | number | no | Holding period every venue is repriced to. At 365 a floating pool’s effective rate equals its sticker rate. | | `rateType` | query | "all" \| "fixed" \| "float" | no | Post-filter applied before dedupe and ranking. | | `limit` | query | integer | no | How many comparables to return (max 25). | | `referenceMarketUid` | query | string | no | The venue the caller is already on. Returned as `reference` and excluded from `items`, so the pill can render "you: X% · best: Y%". | | `referenceTermId` | query | string | no | Disambiguates which term of the reference market is the caller’s own. | | `includeUnobtainable` | query | boolean | no | Keep quotes that cannot be taken right now (closed Term auction rounds), flagged and ranked last. | | `minLiquidityRatio` | query | number | no | Ratio side of the depth floor `min(ratio × anchor, cap)`. | | `liquidityFloorCapUsd` | query | number | no | Cap side of the depth floor — stops a huge anchor from demanding a comparably huge venue and returning nothing. | | `minLiquidityUsd` | query | number | no | Absolute USD depth floor that REPLACES the computed `min(ratio × anchor, cap)`. | | `includeStale` | query | boolean | no | Rank venues whose market data is older than the freshness window. Excluded but counted (`droppedStale`) by default. | | `includeIlliquid` | query | boolean | no | Disable the depth band entirely and rank every venue regardless of size. | | `collateralPreference` | query | string | no | CSV of collateral asset groups tried in order when picking the comparison basis (only used when no collateral is pinned). | | `lenders` | query | string | no | CSV of lender keys (prefix-expanded) to restrict the comparison to. See the `LenderId` schema for the full set of accepted values. | | `excludeLenders` | query | string | no | CSV of lender keys to exclude (prefix-expanded). | | `maxConfigRiskScore` | query | number | no | Config-risk ceiling (default 4, as on the pair endpoints). | | `maxTokenRiskScore` | query | number | no | Token-risk ceiling across both legs. | **Response `200`** — Comparable rates | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | | | `data.side` | "borrow" \| "supply" | | | `data.horizonDays` | number | | | `data.amount` | number | | | `data.amountUsd` | number | | | `data.chainIds` | string[] | EVM chain ids, as decimal strings. See the `ChainId` schema. | | `data.scanned` | integer | Pair rows considered before ranking. | | `data.truncated` | boolean | The candidate guard cap bound, so ranking saw only the deepest rows — narrow the filter. Never a silent trim. | | `data.available` | integer | Distinct comparables that existed before `limit` was applied. | | `data.liquidityFloorUsd` | number | Venues below this USD depth were dropped as not comparable (0 = no floor applied). | | `data.droppedIlliquid` | integer | How many venues the depth band removed. An opinionated filter must never be silent — surface this rather than implying nothing else exists. | | `data.droppedStale` | integer | Venues excluded because their market data is older than `staleMaxHours` — an ingest lag, not an absent lender. Non-zero is the difference between "no one else offers this pair" and "we cannot currently see who does". `includeStale=true` ranks them anyway. | | `data.staleMaxHours` | number | The freshness window `droppedStale` was measured against. | | `data.collateralBasis` | object | The single collateral group each chain's rows were compared against when the caller pinned none, e.g. `{"1":"ETH"}`. Empty when a collateral was supplied, or on the supply side. | | `data.reference` | object | The venue the caller is already on (`referenceMarketUid`), pulled out of `items` so the UI can render "you: X% · best: Y%". | | `data.reference.rank` | integer | 1-based position in the ranking. `0` on the `reference` item. | | `data.reference.chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.reference.lender` | string | Raw lender key — stable, use it for keying and deeplinks. Per-market lenders (Morpho Blue, Silo, Euler) encode a hashed market id here, so it is NOT presentable. | | `data.reference.lenderName` | string | Display name from the lender registry, falling back to the raw key when none is registered. This is what a UI should render. | | `data.reference.lenderLogoUri` | string | | | `data.reference.marketUid` | string | The market the rate belongs to: the debt market for a borrow quote, the collateral market for a supply quote. | | `data.reference.marketName` | string | | | `data.reference.curatorName` | string | | | `data.reference.eMode` | string | | | `data.reference.rateType` | "fixed" \| "float" | | | `data.reference.rateModel` | "variable" \| "lista" \| "midnight" \| "term" \| "exactly" \| "teller" \| … (9 values) | Which repayment rule priced this quote. | | `data.reference.aprPct` | number | Sticker rate, APR %. Includes intrinsic yield and reward APR (same composition as `borrowAprShort` / `depositAprLong`); a one-time origination fee is NOT in it — the horizon model amortizes that separately. | | `data.reference.aprAtAmountPct` | number | The rate at the requested size. Null when no amount was supplied. A utilization pool re-prices its whole balance to the post-action rate; an order book fills cheapest-first, so this is the VWAP of the tiers consumed. | | `data.reference.rewardAprPct` | number | Reward emissions folded into the headline (positive = subsidising a borrow). Large emissions can push a borrow rate NEGATIVE. | | `data.reference.aprExRewardsPct` | number | The rate WITHOUT reward emissions — the structural, sustainable cost. Show it next to a reward-inflated headline; emissions are transient. | | `data.reference.effectiveAprPct` | number | Size-priced rate normalized to `horizonDays`. The ranking number. | | `data.reference.costPct` | number | Total cost over the horizon as a percent of principal. | | `data.reference.horizon` | object | How the effective rate was arrived at — the caveats a UI must show next to a normalized number. | | `data.reference.horizon.basis` | "flat-forward" \| "early-exit" \| "held-to-maturity" \| "rolled" | `flat-forward`: no maturity, today’s floating rate assumed to hold. `early-exit`: horizon shorter than the term, the venue’s exit rule applied. `held-to-maturity`: horizon matches the term (the clean case). `rolled`: horizon outlasts the term, a roll at today’s rate assumed. | | `data.reference.horizon.locked` | boolean | Is the rate contractually fixed for the WHOLE horizon? False for floating pools and for a fixed term that has to be rolled to cover the horizon. | | `data.reference.horizon.priceRisk` | boolean | Exiting early means unwinding on an order book at the then-current price (Midnight/Term), so the realized cost can land either side of the quote. Not priced in — flagged. | | `data.reference.horizon.assumptions` | string[] | Display-ready caveats, most important first. | | `data.reference.termId` | string | | | `data.reference.durationDays` | number | | | `data.reference.maturity` | number | Calendar maturity, unix seconds. Null for rolling menus and variable pools. | | `data.reference.termDays` | number | Remaining term in days for a position opened now. | | `data.reference.obtainable` | boolean | Can this rate be taken right now? False for a Term repo between auction rounds, whose rate card still quotes the last round’s clearing rate. | | `data.reference.obtainableReason` | string | | | `data.reference.quoteBasis` | "live" \| "last-clearing" | `last-clearing` marks a historical print, not an obtainable quote — never render it as an actionable rate. | | `data.reference.depth` | object | | | `data.reference.depth.fillable` | number | Depth ceiling in token units of the priced leg — borrow liquidity for a pool, total book depth for an order book. | | `data.reference.depth.capped` | boolean | The requested amount exceeds `fillable`: this venue cannot fund the position at that size, and the row is demoted below every non-capped one. | | `data.reference.depth.liquidityUsd` | number | | | `data.reference.depth.utilization` | number | Market utilization, as a fraction between 0 and 1. | | `data.reference.collateral` | object | | | `data.reference.collateral.address` | string | EVM contract address, lowercase or checksummed hex. | | `data.reference.collateral.assetGroup` | string | Group of economically equivalent assets, e.g. all USDC variants. | | `data.reference.collateral.symbol` | string | Token symbol, e.g. `WETH`. | | `data.reference.collateral.decimals` | number | Token decimals — divide raw amounts by `10 ** decimals`. | | `data.reference.collateral.logoUri` | string | URL of the logo image. | | `data.reference.collateral.marketUid` | string | Market identifier, formatted `lender:chainId:address`. | | `data.reference.debt` | object | | | `data.reference.debt.address` | string | EVM contract address, lowercase or checksummed hex. | | `data.reference.debt.assetGroup` | string | Group of economically equivalent assets, e.g. all USDC variants. | | `data.reference.debt.symbol` | string | Token symbol, e.g. `WETH`. | | `data.reference.debt.decimals` | number | Token decimals — divide raw amounts by `10 ** decimals`. | | `data.reference.debt.logoUri` | string | URL of the logo image. | | `data.reference.debt.marketUid` | string | Market identifier, formatted `lender:chainId:address`. | | `data.reference.maxLeverage` | number | Highest leverage multiple reachable in this market. | | `data.reference.ltv` | number | Loan-to-value ratio, as a fraction between 0 and 1. | | `data.reference.risk` | object | | | `data.reference.risk.configScore` | number | | | `data.reference.risk.maxTokenScore` | number | | | `data.count` | integer | Number of entries in `items`. | | `data.items` | object[] | The result set for this response. | | `data.items[].rank` | integer | 1-based position in the ranking. `0` on the `reference` item. | | `data.items[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.items[].lender` | string | Raw lender key — stable, use it for keying and deeplinks. Per-market lenders (Morpho Blue, Silo, Euler) encode a hashed market id here, so it is NOT presentable. | | `data.items[].lenderName` | string | Display name from the lender registry, falling back to the raw key when none is registered. This is what a UI should render. | | `data.items[].lenderLogoUri` | string | | | `data.items[].marketUid` | string | The market the rate belongs to: the debt market for a borrow quote, the collateral market for a supply quote. | | `data.items[].marketName` | string | | | `data.items[].curatorName` | string | | | `data.items[].eMode` | string | | | `data.items[].rateType` | "fixed" \| "float" | | | `data.items[].rateModel` | "variable" \| "lista" \| "midnight" \| "term" \| "exactly" \| "teller" \| … (9 values) | Which repayment rule priced this quote. | | `data.items[].aprPct` | number | Sticker rate, APR %. Includes intrinsic yield and reward APR (same composition as `borrowAprShort` / `depositAprLong`); a one-time origination fee is NOT in it — the horizon model amortizes that separately. | | `data.items[].aprAtAmountPct` | number | The rate at the requested size. Null when no amount was supplied. A utilization pool re-prices its whole balance to the post-action rate; an order book fills cheapest-first, so this is the VWAP of the tiers consumed. | | `data.items[].rewardAprPct` | number | Reward emissions folded into the headline (positive = subsidising a borrow). Large emissions can push a borrow rate NEGATIVE. | | `data.items[].aprExRewardsPct` | number | The rate WITHOUT reward emissions — the structural, sustainable cost. Show it next to a reward-inflated headline; emissions are transient. | | `data.items[].effectiveAprPct` | number | Size-priced rate normalized to `horizonDays`. The ranking number. | | `data.items[].costPct` | number | Total cost over the horizon as a percent of principal. | | `data.items[].horizon` | object | How the effective rate was arrived at — the caveats a UI must show next to a normalized number. | | `data.items[].horizon.basis` | "flat-forward" \| "early-exit" \| "held-to-maturity" \| "rolled" | `flat-forward`: no maturity, today’s floating rate assumed to hold. `early-exit`: horizon shorter than the term, the venue’s exit rule applied. `held-to-maturity`: horizon matches the term (the clean case). `rolled`: horizon outlasts the term, a roll at today’s rate assumed. | | `data.items[].horizon.locked` | boolean | Is the rate contractually fixed for the WHOLE horizon? False for floating pools and for a fixed term that has to be rolled to cover the horizon. | | `data.items[].horizon.priceRisk` | boolean | Exiting early means unwinding on an order book at the then-current price (Midnight/Term), so the realized cost can land either side of the quote. Not priced in — flagged. | | `data.items[].horizon.assumptions` | string[] | Display-ready caveats, most important first. | | `data.items[].termId` | string | | | `data.items[].durationDays` | number | | | `data.items[].maturity` | number | Calendar maturity, unix seconds. Null for rolling menus and variable pools. | | `data.items[].termDays` | number | Remaining term in days for a position opened now. | | `data.items[].obtainable` | boolean | Can this rate be taken right now? False for a Term repo between auction rounds, whose rate card still quotes the last round’s clearing rate. | | `data.items[].obtainableReason` | string | | | `data.items[].quoteBasis` | "live" \| "last-clearing" | `last-clearing` marks a historical print, not an obtainable quote — never render it as an actionable rate. | | `data.items[].depth` | object | | | `data.items[].depth.fillable` | number | Depth ceiling in token units of the priced leg — borrow liquidity for a pool, total book depth for an order book. | | `data.items[].depth.capped` | boolean | The requested amount exceeds `fillable`: this venue cannot fund the position at that size, and the row is demoted below every non-capped one. | | `data.items[].depth.liquidityUsd` | number | | | `data.items[].depth.utilization` | number | Market utilization, as a fraction between 0 and 1. | | `data.items[].collateral` | object | | | `data.items[].collateral.address` | string | EVM contract address, lowercase or checksummed hex. | | `data.items[].collateral.assetGroup` | string | Group of economically equivalent assets, e.g. all USDC variants. | | `data.items[].collateral.symbol` | string | Token symbol, e.g. `WETH`. | | `data.items[].collateral.decimals` | number | Token decimals — divide raw amounts by `10 ** decimals`. | | `data.items[].collateral.logoUri` | string | URL of the logo image. | | `data.items[].collateral.marketUid` | string | Market identifier, formatted `lender:chainId:address`. | | `data.items[].debt` | object | | | `data.items[].debt.address` | string | EVM contract address, lowercase or checksummed hex. | | `data.items[].debt.assetGroup` | string | Group of economically equivalent assets, e.g. all USDC variants. | | `data.items[].debt.symbol` | string | Token symbol, e.g. `WETH`. | | `data.items[].debt.decimals` | number | Token decimals — divide raw amounts by `10 ** decimals`. | | `data.items[].debt.logoUri` | string | URL of the logo image. | | `data.items[].debt.marketUid` | string | Market identifier, formatted `lender:chainId:address`. | | `data.items[].maxLeverage` | number | Highest leverage multiple reachable in this market. | | `data.items[].ltv` | number | Loan-to-value ratio, as a fraction between 0 and 1. | | `data.items[].risk` | object | | | `actions` | null | | **Example response** ```json { "success": true, "data": { "side": "borrow", "horizonDays": 1, "amount": 1, "amountUsd": 1, "chainIds": [ "1" ], "scanned": 1, "truncated": true, "available": 1, "liquidityFloorUsd": 1, "droppedIlliquid": 1, "droppedStale": 1, "staleMaxHours": 1, "collateralBasis": {}, "reference": { "rank": 1, "chainId": "1", "lender": "AAVE_V3", "lenderName": "AAVE_V3", "lenderLogoUri": "AAVE_V3", "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "marketName": "string", "curatorName": "string", "eMode": "string", "rateType": "fixed", "rateModel": "variable", "aprPct": 1, "aprAtAmountPct": 1, "rewardAprPct": 1, "aprExRewardsPct": 1, "effectiveAprPct": 1, "costPct": 1, "horizon": { "basis": "flat-forward", "locked": true, "priceRisk": true, "assumptions": [ "string" ] }, "termId": "string", "durationDays": 1, "maturity": 1, "termDays": 1, "obtainable": true, "obtainableReason": "string", "quoteBasis": "live", "depth": { "fillable": 1, "capped": true, "liquidityUsd": 1, "utilization": 1 }, "collateral": { "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "assetGroup": "string", "symbol": "string", "decimals": 1, "logoUri": "string", "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" }, "debt": { "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "assetGroup": "string", "symbol": "string", "decimals": 1, "logoUri": "string", "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" }, "maxLeverage": 1, "ltv": 1, "risk": { "configScore": 1, "maxTokenScore": 1 } }, "count": 1, "items": [ { "rank": 1, "chainId": "1", "lender": "AAVE_V3", "lenderName": "AAVE_V3", "lenderLogoUri": "AAVE_V3", "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "marketName": "string", "curatorName": "string", "eMode": "string", "rateType": "fixed", "rateModel": "variable", "aprPct": 1, "aprAtAmountPct": 1, "rewardAprPct": 1, "aprExRewardsPct": 1, "effectiveAprPct": 1, "costPct": 1, "horizon": { "basis": "flat-forward", "locked": true, "priceRisk": true, "assumptions": [ "string" ] }, "termId": "string", "durationDays": 1, "maturity": 1, "termDays": 1, "obtainable": true, "obtainableReason": "string", "quoteBasis": "live", "depth": { "fillable": 1, "capped": true, "liquidityUsd": 1, "utilization": 1 }, "collateral": { "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "assetGroup": "string", "symbol": "string", "decimals": 1, "logoUri": "string", "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" }, "debt": { "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "assetGroup": "string", "symbol": "string", "decimals": 1, "logoUri": "string", "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" }, "maxLeverage": 1, "ltv": 1, "risk": { "configScore": 1, "maxTokenScore": 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. ### GET /v1/data/lending/irm - operationId: `irm-rate-curves` - docs: https://docs.1delta.io/1delta-api/irm-rate-curves/ - markdown: https://docs.1delta.io/1delta-api/irm-rate-curves.md - tags: Lending (Data) IRM rate curves Return sampled borrow and deposit rate curves for one or more markets. Each curve is a series of `(utilization, borrowRate, depositRate)` points spanning 0% to 100% utilization. Rates are **APR %** (e.g. `5.5` = 5.5% APR). Supported protocols: `aave`, `aave_v4`, `compound_v2`, `compound_v3`, `morpho` (including Lista), `euler_v2`, `silo`, `fluid`, `gearbox`, `dolomite`. **Caching:** IRM parameters are quasi-static and cached server-side for 1 hour. Computed curves are also cached (keyed by market UIDs + data-point count). **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `marketUids` | query | string | yes | Comma-separated market UIDs, e.g. `AAVE_V3:1:0xa0b8...` | | `dataPoints` | query | integer | no | Number of curve sample points (1–20, default 20) | **Response `200`** — Rate curves per market | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Informational payload. `null` when the endpoint only builds calldata. | | `data.count` | integer | Number of markets returned | | `data.items` | object[] | The result set for this response. | | `data.items[].marketUid` | string | Unique market identifier (`lenderKey:chainId:address`) | | `data.items[].protocol` | "aave" \| "aave_v4" \| "compound_v2" \| "compound_v3" \| "morpho" \| "euler_v2" \| … (10 values) | IRM model type | | `data.items[].lenderKey` | string | | | `data.items[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.items[].underlyingAddress` | string | | | `data.items[].marketName` | string | | | `data.items[].points` | object[] | Sampled rate curve. Length = dataPoints + 1 (includes u=0 and u=1). | | `data.items[].points[].utilization` | number | Utilization ratio (0–1) | | `data.items[].points[].borrowRate` | number | Variable borrow rate (APR %, e.g. 7.67 = 7.67%) | | `data.items[].points[].depositRate` | number | Deposit/supply rate (APR %, e.g. 3.30 = 3.30%) | | `actions` | null | | **Example response** ```json { "success": true, "data": { "count": 1, "items": [ { "marketUid": "SPARK:100:0x2a22f9c3b484c3629090feed35f17ff8f88f76f0", "protocol": "aave", "lenderKey": "SPARK", "chainId": "100", "underlyingAddress": "0x2a22f9c3b484c3629090feed35f17ff8f88f76f0", "marketName": "Spark USDC.e", "points": [ { "utilization": 0.95, "borrowRate": 7.67, "depositRate": 3.3 } ] } ] } } ``` **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. ### GET /v1/data/lending/irm/depth - operationId: `rate-at-depth-rate-vs-borrow-supply-amount` - docs: https://docs.1delta.io/1delta-api/rate-at-depth-rate-vs-borrow-supply-amount/ - markdown: https://docs.1delta.io/1delta-api/rate-at-depth-rate-vs-borrow-supply-amount.md - tags: Lending (Data) Rate-at-depth (rate vs borrow/supply amount) Return rate-at-depth data — the amount-axis complement of `/v1/data/lending/irm` (rate vs utilization). Two shapes, both optional: - **grid** (default): a `borrow`/`supply` sweep from 0 to the fillable ceiling — for charts. Disable with `grid=false`. - **rateAtAmount**: pass `amount(s)` (token units) and/or `amount(s)Usd` (USD) to get the rate + resulting utilization + fillable ceiling at each specific size — the answer to *"what rate to borrow X"*. For a utilization pool the whole balance re-prices to one rate, so `rateAtAmount` is the marginal spot rate at the post-action utilization (marginal == average). Order-book venues (Midnight) fill best-first, so their `rateAtAmount` is a **volume-weighted average** over the consumed ladder. Lista's brokered borrow leg is a **flat fixed** rate up to capacity. Rates are **APR %**. **Caching:** computed grids/points cached server-side for 1 hour (keyed by UIDs + side + points + amounts). **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `marketUids` | query | string | yes | Comma-separated market UIDs, e.g. `GEARBOX_V3_0x…:9745:0x…` | | `side` | query | string | no | `borrow` \| `supply` \| `both` (default `borrow`) | | `dataPoints` | query | integer | no | Samples per grid (1–60, default 24) | | `amounts` | query | string | no | Comma-separated sizes in TOKEN units → adds `rateAtAmount[]`. `amount` is accepted as a singular alias. | | `amountsUsd` | query | string | no | Comma-separated sizes in USD (converted per market via its price). `amountUsd` alias accepted. | | `grid` | query | string | no | Set `false` to drop the 0→max grid sweep (points-only). | **Response `200`** — Depth grids and/or rate-at-amount points per market | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Informational payload. `null` when the endpoint only builds calldata. | | `data.count` | integer | Number of entries in `items`. | | `data.items` | object[] | The result set for this response. | | `data.items[].marketUid` | string | Market identifier, formatted `lender:chainId:address`. | | `data.items[].protocol` | string | | | `data.items[].lenderKey` | string | | | `data.items[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.items[].underlyingAddress` | string | | | `data.items[].utilization` | number | Current utilization (0–1) | | `data.items[].variableBorrowRate` | number | Current 0-notional borrow APR % | | `data.items[].borrow` | object | Rate-vs-amount sweep from size 0 to `fillable`. | | `data.items[].borrow.side` | "borrow" \| "supply" | | | `data.items[].borrow.currentUtilization` | number | | | `data.items[].borrow.currentBorrowAprPct` | number | | | `data.items[].borrow.currentDepositAprPct` | number | | | `data.items[].borrow.fillable` | number | Largest size sampled — the depth ceiling (token units). | | `data.items[].borrow.fillableUsd` | number | | | `data.items[].borrow.points` | object[] | | | `data.items[].borrow.points[].size` | number | Cumulative size (token units) | | `data.items[].borrow.points[].sizeUsd` | number | | | `data.items[].borrow.points[].utilization` | number | Market utilization, as a fraction between 0 and 1. | | `data.items[].borrow.points[].borrowAprPct` | number | | | `data.items[].borrow.points[].depositAprPct` | number | | | `data.items[].supply` | object | Rate-vs-amount sweep from size 0 to `fillable`. | | `data.items[].supply.side` | "borrow" \| "supply" | | | `data.items[].supply.currentUtilization` | number | | | `data.items[].supply.currentBorrowAprPct` | number | | | `data.items[].supply.currentDepositAprPct` | number | | | `data.items[].supply.fillable` | number | Largest size sampled — the depth ceiling (token units). | | `data.items[].supply.fillableUsd` | number | | | `data.items[].supply.points` | object[] | | | `data.items[].supply.points[].size` | number | Cumulative size (token units) | | `data.items[].supply.points[].sizeUsd` | number | | | `data.items[].supply.points[].utilization` | number | Market utilization, as a fraction between 0 and 1. | | `data.items[].supply.points[].borrowAprPct` | number | | | `data.items[].supply.points[].depositAprPct` | number | | | `data.items[].rateAtAmount` | object[] | Rate + fillable at each requested size (present only when `amount(s)`/`amount(s)Usd` is passed). | | `data.items[].rateAtAmount[].side` | "borrow" \| "supply" | | | `data.items[].rateAtAmount[].size` | number | Requested size (token units) | | `data.items[].rateAtAmount[].amountUsd` | number | | | `data.items[].rateAtAmount[].utilization` | number | Post-action utilization (0 for order books) | | `data.items[].rateAtAmount[].borrowAprPct` | number | | | `data.items[].rateAtAmount[].depositAprPct` | number | | | `data.items[].rateAtAmount[].fillable` | number | Max borrowable/suppliable before a cap binds (token units) | | `data.items[].rateAtAmount[].capped` | boolean | True when `size` exceeds `fillable` — rate is reported at the ceiling. | | `actions` | null | | **Example response** ```json { "success": true, "data": { "count": 1, "items": [ { "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "protocol": "string", "lenderKey": "AAVE_V3", "chainId": "1", "underlyingAddress": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "utilization": 1, "variableBorrowRate": 1, "borrow": { "side": "borrow", "currentUtilization": 1, "currentBorrowAprPct": 1, "currentDepositAprPct": 1, "fillable": 1, "fillableUsd": 1, "points": [ { "size": 1, "sizeUsd": 1, "utilization": 1, "borrowAprPct": 1, "depositAprPct": 1 } ] }, "supply": { "side": "borrow", "currentUtilization": 1, "currentBorrowAprPct": 1, "currentDepositAprPct": 1, "fillable": 1, "fillableUsd": 1, "points": [ { "size": 1, "sizeUsd": 1, "utilization": 1, "borrowAprPct": 1, "depositAprPct": 1 } ] }, "rateAtAmount": [ { "side": "borrow", "size": 1, "amountUsd": 1, "utilization": 1, "borrowAprPct": 1, "depositAprPct": 1, "fillable": 1, "capped": true } ] } ] } } ``` **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. ### GET /v1/data/lending/isolated-markets/meta - operationId: `get-isolated-market-metadata` - docs: https://docs.1delta.io/1delta-api/get-isolated-market-metadata/ - markdown: https://docs.1delta.io/1delta-api/get-isolated-market-metadata.md - tags: Lending (Data) Get isolated market metadata Returns Morpho isolated market metadata including fee, LLTV, oracle, IRM, and listing status for all markets, optionally filtered by chain. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chainIds` | query | string[] | no | Filter by chain IDs (repeatable) See the `ChainId` schema for the full set of supported chains. | **Response `200`** — Isolated market metadata | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Informational payload. `null` when the endpoint only builds calldata. | | `actions` | null | | **Example response** ```json { "success": true, "data": {} } ``` **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. ### 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`](/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_`):** 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](/1delta-api/lending-deposit)/[borrow](/1delta-api/lending-borrow) actions, and to **MAKE** your own offer see [`/v1/actions/midnight/make`](/1delta-api/midnight-make). **Teller markets (`TELLER_`):** 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_`):** 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:` 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. ### GET /v1/data/lending/lenders - operationId: `lending-lenders` - docs: https://docs.1delta.io/1delta-api/lending-lenders/ - markdown: https://docs.1delta.io/1delta-api/lending-lenders.md - tags: Lending (Data) Enumerate available lenders Lightweight enumeration of every `(chainId, lenderKey)` pair that has data for the requested chains, sorted by `tvlUsd` descending. Use this endpoint to discover the lender keys to page through [`GET /v1/data/lending/latest`](/1delta-api/lending-latest), which is hard-capped at 20 lender keys per request. ``` 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 ``` **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chains` | query | string[] | yes | Chain IDs to query (repeatable, CSV also accepted) | | `lenders` | query | string[] | no | Filter by lender keys (repeatable, CSV also accepted). Defaults to all lenders. See the `LenderId` schema for the full set of accepted values. | | `maxRiskScore` | query | integer | no | Max risk score (1–5). Defaults to 4. | | `minTvl` | query | number | no | Filter out lender entries with `tvlUsd` below this USD threshold. Applied as a HAVING clause after aggregation. Returns 400 if non-numeric. | | `count` | query | integer | no | Optional cap on the number of items returned. | **Response `200`** — Available lenders sorted by TVL | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Enumeration of available (chainId, lenderKey) pairs sorted by tvlUsd descending. | | `data.count` | integer | Number of items returned | | `data.items` | object[] | Lender entries sorted by tvlUsd descending | | `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[].tvlUsd` | number | Σ totalDepositsUsd − Σ totalDebtUsd over the lender's markets on this chain | | `data.items[].lastFetched` | number | Epoch ms of latest snapshot | | `actions` | null | | **Example response** ```json { "success": true, "data": { "count": 1, "items": [ { "chainId": "1", "lenderInfo": { "key": "AAVE_V3", "name": "Aave V3", "logoURI": "https://raw.githubusercontent.com/1delta-DAO/protocol-icons/main/lender/aave_v3.webp" }, "tvlUsd": 1234567890.12, "lastFetched": 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. ### GET /v1/data/lending/mode - operationId: `list-mode-categories` - docs: https://docs.1delta.io/1delta-api/list-mode-categories/ - markdown: https://docs.1delta.io/1delta-api/list-mode-categories.md - tags: Lending (Data) List mode categories Return the available risk-category ("mode") entries for the requested lenders and chains. Each entry contains the lender key, chain ID, and a list of mode categories (id + label) under the `eModes` field. The "mode" terminology is the protocol-agnostic generalization of Aave V3's "e-mode" (efficiency mode); other lenders expose analogous category mechanisms. Results are cached server-side (1 hour TTL) because mode categories rarely change. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `lenders` | query | string[] | yes | Protocol identifiers (repeatable) See the `LenderId` schema for the full set of accepted values. | | `chains` | query | string[] | yes | Chain IDs (repeatable) | **Response `200`** — Mode categories per lender/chain | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Informational payload. `null` when the endpoint only builds calldata. | | `actions` | null | | **Example response** ```json { "success": true, "data": {} } ``` **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. ### GET /v1/data/lending/mode/analysis - operationId: `mode-analysis-on-chain` - docs: https://docs.1delta.io/1delta-api/mode-analysis-on-chain/ - markdown: https://docs.1delta.io/1delta-api/mode-analysis-on-chain.md - tags: Lending (Data) Mode analysis (on-chain) Evaluate all mode-switching options for a user. The API fetches the user's current positions and balance data on-chain via multicall — no request body needed. **Output:** For each available mode on the specified lender/chain, returns: - **healthFactor** — the hypothetical health factor if the user switches to that mode (`null` if no debt) - **supportedAssets** — which marketUids are eligible as collateral or for borrowing in that mode - **canSwitch** — whether the switch is safe (health factor > 1 and no incompatible debt) Mode categories are cached server-side (1 hour TTL). Market configs are cached (3 minute TTL). The "mode" terminology is the protocol-agnostic generalization of Aave V3's "e-mode" (efficiency mode); other lenders expose analogous category mechanisms. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `lender` | query | string | yes | Protocol identifier See the `LenderId` schema for the full set of accepted values. | | `chain` | query | string | yes | Chain ID | | `operator` | query | string | yes | Wallet address of the user | | `accountId` | query | string | no | Sub-account ID (for multi-subaccount lenders like Init Capital). Defaults to first sub-account. | **Response `200`** — Mode analysis results | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Informational payload. `null` when the endpoint only builds calldata. | | `actions` | null | | **Example response** ```json { "success": true, "data": {} } ``` **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. ### POST /v1/data/lending/mode/analysis - operationId: `mode-analysis-with-body` - docs: https://docs.1delta.io/1delta-api/mode-analysis-with-body/ - markdown: https://docs.1delta.io/1delta-api/mode-analysis-with-body.md - tags: Lending (Data) Mode analysis (with body) Evaluate all mode-switching options for a user sub-account. **Input:** POST a `UserDataForSubAccount` object (the same shape returned by `/user-positions` per sub-account). **Output:** For each available mode on the specified lender/chain, returns: - **healthFactor** — the hypothetical health factor if the user switches to that mode (`null` if no debt) - **supportedAssets** — which marketUids are eligible as collateral or for borrowing in that mode - **canSwitch** — whether the switch is safe (health factor > 1 and no incompatible debt) Mode categories are cached server-side (1 hour TTL). Market configs are cached (3 minute TTL). The "mode" terminology is the protocol-agnostic generalization of Aave V3's "e-mode" (efficiency mode); other lenders expose analogous category mechanisms. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `lender` | query | string | yes | Protocol identifier See the `LenderId` schema for the full set of accepted values. | | `chain` | query | string | yes | Chain ID | **Request body** (`application/json`) | Field | Type | Required | Description | | --- | --- | --- | --- | | `accountId` | string | no | | | `health` | number | no | | | `borrowCapacityUSD` | number | no | | | `balanceData` | object | yes | Balance data for the sub-account. `collateral` and `adjustedDebt` are required for health factor calculation. | | `balanceData.collateral` | number | yes | | | `balanceData.adjustedDebt` | number | yes | | | `balanceData.deposits` | number | no | | | `balanceData.debt` | number | no | | | `balanceData.borrowDiscountedCollateral` | number | no | | | `balanceData.nav` | number | no | | | `aprData` | object | no | | | `positions` | object[] | yes | | | `positions[].marketUid` | string | no | Market identifier, formatted `lender:chainId:address`. | | `positions[].depositsUSD` | number | no | | | `positions[].debtUSD` | number | no | | | `positions[].debtStableUSD` | number | no | | | `positions[].collateralEnabled` | boolean | no | | | `userConfig` | object | yes | | | `userConfig.selectedMode` | string | yes | Current mode/config key | | `userConfig.id` | string | no | | | `userConfig.isWhitelisted` | boolean | no | | **Example request body** ```json { "accountId": "string", "health": 1, "borrowCapacityUSD": 1, "balanceData": { "collateral": 1, "adjustedDebt": 1, "deposits": 1, "debt": 1, "borrowDiscountedCollateral": 1, "nav": 1 }, "aprData": {}, "positions": [ { "marketUid": "AAVE_V3:1:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "depositsUSD": 1, "debtUSD": 1, "debtStableUSD": 1, "collateralEnabled": true } ], "userConfig": { "selectedMode": "string", "id": "string", "isWhitelisted": true } } ``` **Response `200`** — Mode analysis results | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Informational payload. `null` when the endpoint only builds calldata. | | `actions` | null | | **Example response** ```json { "success": true, "data": {} } ``` **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. ### GET /v1/data/lending/next-account - operationId: `next-available-sub-account` - docs: https://docs.1delta.io/1delta-api/next-available-sub-account/ - markdown: https://docs.1delta.io/1delta-api/next-available-sub-account.md - tags: Lending (Data) Next available sub-account Discover the next available sub-account or position ID for a given lender and owner. Different protocols handle sub-accounts differently: - **Euler V2** (`accountType: SELECT`): Sub-accounts are derived by XORing the owner's last address byte with an index (0-255). The integrator selects an `accountId` from the range. Any unused value automatically creates a new sub-account. - **Dolomite** (`accountType: SELECT`): Margin sub-accounts are arbitrary `uint256` account numbers (`accountIdRange` is `0` to `2^256-1`). Account `0` is the default cross-margin account; `activeAccountIds` lists funded accounts and `nextAccountId` is the lowest unused integer. Any unused number automatically creates a new sub-account. - **Init Capital** (`accountType: AUTOGEN`): Position IDs are NFT hashes generated on-chain. To create a new position, **omit** the `posId`/`accountId` parameter entirely. The `nextAccountId` field is a preview of the ID that will be generated. - **Other lenders** (Aave, Morpho, Compound, etc.): Do not support sub-accounts — returns a 400 error. ### Integration Guide | `accountType` | To create new account | To use existing account | |---|---|---| | `SELECT` | Pass `accountId=` from `accountIdRange` | Pass `accountId=` | | `AUTOGEN` | **Omit** `accountId` / `posId` parameter | Pass `posId=` | **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chainId` | query | string | yes | Chain ID. See the `ChainId` schema for the full set of supported chains. | | `lender` | query | string | yes | Lender identifier. See the `LenderId` schema for the full set of accepted values. | | `account` | query | string | yes | Owner wallet address. | **Response `200`** — Next account information | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | | | `data.accountType` | "SELECT" \| "AUTOGEN" | SELECT — integrator picks an ID from the range (Euler V2). AUTOGEN — ID is generated on-chain; omit the param to create (Init Capital). | | `data.nextAccountId` | string | For SELECT: lowest unused account ID. For AUTOGEN: preview of the on-chain generated ID. | | `data.activeAccountIds` | string[] | Currently active account IDs for this owner. May be empty for AUTOGEN protocols. | | `data.accountIdRange` | string[] | Inclusive [min, max] range of valid account IDs. | | `data.createHint` | string | Human-readable instructions for integrators on how to create a new sub-account. | | `actions` | null | | **Example response** ```json { "success": true, "data": { "accountType": "SELECT", "nextAccountId": "1", "activeAccountIds": [ "0", "3", "7" ], "accountIdRange": [ "0", "255" ], "createHint": "string" } } ``` **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. ### GET /v1/data/lending/orders - operationId: `lending-orders` - docs: https://docs.1delta.io/1delta-api/lending-orders/ - markdown: https://docs.1delta.io/1delta-api/lending-orders.md - tags: Lending (Data) Your open orders (unified) A user's own cancellable/pending orders on an order-book or auction lender, normalized into ONE shape: - `MORPHO_MIDNIGHT_` → signed maker limit offers (`kind: 'maker-offer'`), cancel via [`/v1/actions/midnight/cancel`](/1delta-api/midnight-cancel). - `TERM_FINANCE_` → secondary repo-token listings (`kind: 'listing'`) + primary sealed-bid auction submissions (`kind: 'auction-offer'|'auction-bid'`), managed via [`/v1/actions/term/*`](/1delta-api/term-offer). Each order carries a self-describing `cancel` action (`{ method, path, query }`) pointing at the exact endpoint, so one Cancel button works for every provider. `aprPct` is `null` while an auction price is still sealed. To TAKE (fill) *other* users' liquidity, use the standard lending actions + the unified ladder at `/v1/data/lending/book`. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `marketUid` | query | string | no | Market uid `lender:chainId:asset` (or pass `lender` + `chainId`). | | `lender` | query | string | no | `MORPHO_MIDNIGHT_` or `TERM_FINANCE_` lender key. See the `LenderId` schema for the full set of accepted values. | | `chainId` | query | string | no | Chain ID (aliases: `chains`, `chain`). See the `ChainId` schema for the full set of supported chains. | | `account` | query | string | yes | The order owner whose orders to return. | **Response `200`** — The account's own orders on the market | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | A user's own orders across order-book / auction lenders. | | `data.orders` | object[] | | | `data.orders[].id` | string | Provider order id — the cancel target (Midnight offer root / Term listingId / auction submission id). | | `data.orders[].lender` | string | Protocol identifier. See the `LenderId` schema. | | `data.orders[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.orders[].kind` | "maker-offer" \| "listing" \| "auction-offer" \| "auction-bid" | `maker-offer` (Midnight signed limit offer), `listing` (Term secondary repo-token listing), `auction-offer`/`auction-bid` (Term primary sealed-bid submission). | | `data.orders[].side` | "lend" \| "borrow" | | | `data.orders[].amount` | string | Order size, loan-token base units. | | `data.orders[].assets` | number | Size decimal-scaled to loan-token assets, or null. | | `data.orders[].aprPct` | number | Annualized rate in percent, or null while sealed. | | `data.orders[].status` | "open" \| "sealed" \| "revealed" \| "filled" \| "closed" | `open` = cancellable now (maker offer / listing); `sealed`/`revealed` = auction lifecycle; `filled` = assigned at clearing; `closed` = complete or cancelled. | | `data.orders[].filledAmount` | string | Amount assigned at clearing (auctions), base units. | | `data.orders[].maturity` | number | Market/repo maturity, unix seconds. | | `data.orders[].expiry` | number | Maker-offer expiry, unix seconds (Midnight). | | `data.orders[].revealTime` | number | Auction reveal window opens, unix seconds (Term). | | `data.orders[].auctionEndTime` | number | Auction closes / clears, unix seconds (Term). | | `data.orders[].cancel` | object | Self-describing cancel/unlock action — omitted when not cancellable. Fetch `path`+`query` to build the cancel transaction. | | `data.orders[].cancel.method` | "GET" \| "POST" | | | `data.orders[].cancel.path` | string | | | `data.orders[].cancel.query` | object | | | `actions` | null | | **Example response** ```json { "success": true, "data": { "orders": [ { "id": "string", "lender": "TERM_FINANCE_0xABC…", "chainId": "1", "kind": "maker-offer", "side": "lend", "amount": "1000000000000000000", "assets": 1, "aprPct": 1, "status": "open", "filledAmount": "1000000000000000000", "maturity": 1, "expiry": 1, "revealTime": 1, "auctionEndTime": 1, "cancel": { "method": "GET", "path": "/v1/actions/term/unlock-offers", "query": {} } } ] } } ``` **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. ### GET /v1/data/lending/pairs - operationId: `get-lending-pairs` - docs: https://docs.1delta.io/1delta-api/get-lending-pairs/ - markdown: https://docs.1delta.io/1delta-api/get-lending-pairs.md - tags: Lending (Data) Get lending pairs Returns paginated leverage pair data with optional filters and sorting. Backed by the same origin route as `/v1/data/lending/pairs/leverage`, so it shares that endpoint's behaviour — including dropping pairs whose collateral leg has no remaining supply capacity (`includeIlliquid=true` keeps them). **Lista DAO fixed-term (brokered) debt side:** when the short (debt) market is brokered, `variableBorrowDisabledShort` is `true` and `termsShort[]` lists the fixed-term loop options (each a `MarketTerm`). The pair has one loop option per term rather than a single variable-rate loop — use the per-term APR from `termsShort[]` in place of `variableBorrowRateShort` (which is `0`/undefined for these pairs). **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chainId` | query | string | no | Filter by chain ID See the `ChainId` schema for the full set of supported chains. | | `lender` | query | string | no | Filter by lender key See the `LenderId` schema for the full set of accepted values. | | `assetGroupLong` | query | string | no | Filter by collateral asset group | | `assetGroupShort` | query | string | no | Filter by debt asset group | | `minApr` | query | number | no | Minimum total APR | | `minLeverage` | query | number | no | Minimum max leverage | | `minLiquidityUsd` | query | number | no | Minimum liquidity in USD | | `includeIlliquid` | query | boolean | no | Keep pairs whose collateral leg has no remaining supply capacity (un-openable at any size). Off by default. | | `sortBy` | query | "aprTotal" \| "maxLeverage" \| "totalDepositsUsdLong" \| "totalDebtUsdShort" | no | Sort field | | `sortDir` | query | "asc" \| "desc" | no | Sort direction | | `start` | query | integer | no | Pagination start index | | `count` | query | integer | no | Page size | **Response `200`** — Pair data | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | | | `data.start` | integer | | | `data.count` | integer | Number of entries in `items`. | | `data.items` | object[] | The result set for this response. | | `data.items[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.items[].lender` | string | Protocol identifier. See the `LenderId` schema. | | `data.items[].marketLongUid` | string | Market UID of the collateral side | | `data.items[].marketShortUid` | string | Market UID of the debt side | | `data.items[].marketNameLong` | string | Display name of the collateral market/vault (e.g. the Euler eVault name). Disambiguates rows that share the collateral/debt token symbols and lender. | | `data.items[].marketNameShort` | string | Display name of the debt market/vault. For Euler this is the controller (debt) eVault — the primary way to tell otherwise-identical WETH→USDC rows apart. | | `data.items[].curatorNameLong` | string | Curator/brand of the collateral market (Euler: resolved from the vault governor). Null for lenders without a curator, or until the curator registry is seeded. Render as "curatorName + symbol", falling back to marketNameLong. | | `data.items[].curatorNameShort` | string | Curator/brand of the debt (controller) market. Same semantics as curatorNameLong. | | `data.items[].assetLong` | string | Collateral asset address | | `data.items[].assetShort` | string | Debt asset address | | `data.items[].assetGroupLong` | string | | | `data.items[].assetGroupShort` | string | | | `data.items[].symbolLong` | string | Collateral token symbol | | `data.items[].nameLong` | string | Collateral token name | | `data.items[].symbolShort` | string | Debt token symbol | | `data.items[].nameShort` | string | Debt token name | | `data.items[].collateralFactorLong` | number | Liquidation collateral factor for the long side | | `data.items[].borrowCollateralFactorLong` | number | Borrow-adjusted collateral factor for the long side | | `data.items[].borrowFactorLong` | number | Borrow factor for the long side | | `data.items[].collateralDisabledLong` | boolean | Whether collateral is disabled for the long asset | | `data.items[].debtDisabledLong` | boolean | Whether debt is disabled for the long asset | | `data.items[].collateralFactorShort` | number | Liquidation collateral factor for the short side | | `data.items[].borrowCollateralFactorShort` | number | Borrow-adjusted collateral factor for the short side | | `data.items[].borrowFactorShort` | number | Borrow factor for the short side | | `data.items[].collateralDisabledShort` | boolean | Whether collateral is disabled for the short asset | | `data.items[].debtDisabledShort` | boolean | Whether debt is disabled for the short asset | | `data.items[].eModeConfigId` | string | E-mode configuration ID | | `data.items[].eMode` | string | E-mode category | | `data.items[].aprBase` | number | Base APR (deposit - borrow + intrinsic, before rewards) | | `data.items[].aprTotal` | number | Total APR (base + rewards) | | `data.items[].maxLeverage` | number | Highest leverage multiple reachable in this market. | | `data.items[].ltv` | number | Loan-to-value ratio (0-1) | | `data.items[].depositRateLong` | number | | | `data.items[].variableBorrowRateShort` | number | | | `data.items[].intrinsicYieldLong` | number | | | `data.items[].intrinsicYieldShort` | number | | | `data.items[].variableBorrowDisabledShort` | boolean | True when the debt (short) market is a Lista DAO brokered market — it cannot be looped at a variable rate, only at one of the fixed terms in `termsShort`. `variableBorrowRateShort` is `0`/undefined for such pairs. | | `data.items[].termsShort` | object[] | Fixed-term rate card for the debt (short) side when it is a Lista DAO brokered market. Each entry is one loop option — see the per-term net-APR recipe. `null`/empty for regular variable-rate pairs. For Term Finance an empty card means "not borrowable right now" rather than "no offers" — read `fixedTerm.auction` for why. | | `data.items[].termsShort[].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[].termsShort[].depositApr` | number | Annualised fixed LEND rate at this maturity, in percent (Exactly only — its fixed pools quote both sides). | | `data.items[].termsShort[].available` | number | Borrowable liquidity at this maturity in loan-token human units (Exactly only). | | `data.items[].termsShort[].durationDays` | number | How long the position is locked at the fixed rate, in days (e.g. 7, 14, 30). | | `data.items[].termsShort[].durationSecs` | number | Term duration in seconds (raw on-chain value). | | `data.items[].termsShort[].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[].termsShort[].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[].termsShort[].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[].termsShort[].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[].termsShort[].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[].termsShort[].ladder[].apr` | number | Annualised borrow rate at this tier (%). | | `data.items[].termsShort[].ladder[].units` | string | Credit/debt units at this tier (raw). | | `data.items[].termsShort[].ladder[].assets` | number | Loan-token size available at this tier. | | `data.items[].fixedTerm` | object | Fixed-term descriptor for this pair's lender, joined by lender key. Absent on variable-rate lenders. **For Term Finance (`model: "term"`), gate the borrow/loop CTA on `fixedTerm.auction.canBorrow`**: origination only happens inside scheduled sealed-bid auction rounds and most repos sit between rounds, so a pair can carry a maturity, an LTV and a rate and still be impossible to borrow. Note also that `aprBase`/`aprTotal` on such a pair are computed against a `variableBorrowRate` of 0 and therefore read as an enormous leveraged yield with a free debt leg — show them as indicative, not obtainable, whenever `canBorrow` is false. | | `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[].rewardAprLong` | number | Total reward APR on the collateral side | | `data.items[].rewardAprShort` | number | Total reward APR on the debt side | | `data.items[].rewardsLong` | object[] | Reward programs for the collateral side | | `data.items[].rewardsShort` | object[] | Reward programs for the debt side | | `data.items[].totalDepositsLong` | number | Total deposits in token units (long side) | | `data.items[].totalDebtLong` | number | Total debt in token units (long side) | | `data.items[].totalLiquidityLong` | number | Total liquidity in token units (long side) | | `data.items[].totalDepositsShort` | number | Total deposits in token units (short side) | | `data.items[].totalDebtShort` | number | Total debt in token units (short side) | | `data.items[].totalLiquidityShort` | number | Total liquidity in token units (short side) | | `data.items[].totalDepositsUsdLong` | number | | | `data.items[].totalDebtUsdLong` | number | | | `data.items[].totalLiquidityUsdLong` | number | | | `data.items[].totalDepositsUsdShort` | number | | | `data.items[].totalDebtUsdShort` | number | | | `data.items[].totalLiquidityUsdShort` | number | | | `data.items[].borrowLiquidityShort` | number | Available borrow liquidity (debt side) in token units | | `data.items[].withdrawLiquidityLong` | number | Available withdraw liquidity (collateral side) in token units | | `data.items[].depositableLong` | number | Remaining deposit capacity (collateral side) in token units | | `data.items[].utilizationLong` | number | | | `data.items[].utilizationShort` | number | | | `data.items[].underlyingInfoLong` | object | Collateral asset metadata including token info, market prices, and oracle prices | | `data.items[].underlyingInfoLong.asset` | object | Token metadata (address, symbol, name, decimals, logoURI, assetGroup) | | `data.items[].underlyingInfoLong.prices` | object | Market prices (priceUsd, priceUsd24h, priceChange24h) | | `data.items[].underlyingInfoLong.oraclePrice` | object | On-chain oracle prices (oraclePrice, oraclePriceUsd) | | `data.items[].underlyingInfoShort` | object | Debt asset metadata including token info, market prices, and oracle prices | | `data.items[].underlyingInfoShort.asset` | object | Token metadata (address, symbol, name, decimals, logoURI, assetGroup) | | `data.items[].underlyingInfoShort.prices` | object | Market prices (priceUsd, priceUsd24h, priceChange24h) | | `data.items[].underlyingInfoShort.oraclePrice` | object | On-chain oracle prices (oraclePrice, oraclePriceUsd) | | `actions` | null | | **Example response** ```json { "success": true, "data": { "start": 1, "count": 1, "items": [ { "chainId": "1", "lender": "AAVE_V3", "marketLongUid": "string", "marketShortUid": "string", "marketNameLong": "string", "marketNameShort": "string", "curatorNameLong": "string", "curatorNameShort": "string", "assetLong": "string", "assetShort": "string", "assetGroupLong": "string", "assetGroupShort": "string", "symbolLong": "string", "nameLong": "string", "symbolShort": "string", "nameShort": "string", "collateralFactorLong": 0.94, "borrowCollateralFactorLong": 0.92, "borrowFactorLong": 1, "collateralDisabledLong": true, "debtDisabledLong": true, "collateralFactorShort": 0.94, "borrowCollateralFactorShort": 0.92, "borrowFactorShort": 1, "collateralDisabledShort": true, "debtDisabledShort": true, "eModeConfigId": "string", "eMode": "string", "aprBase": 1, "aprTotal": 1, "maxLeverage": 1, "ltv": 1, "depositRateLong": 1, "variableBorrowRateShort": 1, "intrinsicYieldLong": 1, "intrinsicYieldShort": 1, "variableBorrowDisabledShort": true, "termsShort": [ { "termId": 2, "depositApr": 1, "available": 1, "durationDays": 7, "durationSecs": 604800, "apr": 3.85, "aprAtAmount": 1, "fillable": 1, "capped": true, "ladder": [ { "apr": 1, "units": "string", "assets": 1 } ] } ], "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" } }, "rewardAprLong": 1, "rewardAprShort": 1, "rewardsLong": [ {} ], "rewardsShort": [ {} ], "totalDepositsLong": 1, "totalDebtLong": 1, "totalLiquidityLong": 1, "totalDepositsShort": 1, "totalDebtShort": 1, "totalLiquidityShort": 1, "totalDepositsUsdLong": 1, "totalDebtUsdLong": 1, "totalLiquidityUsdLong": 1, "totalDepositsUsdShort": 1, "totalDebtUsdShort": 1, "totalLiquidityUsdShort": 1, "borrowLiquidityShort": 1, "withdrawLiquidityLong": 1, "depositableLong": 1, "utilizationLong": 1, "utilizationShort": 1, "underlyingInfoLong": { "asset": {}, "prices": {}, "oraclePrice": {} }, "underlyingInfoShort": { "asset": {}, "prices": {}, "oraclePrice": {} } } ] } } ``` **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. ### GET /v1/data/lending/pairs/leverage - operationId: `browse-all-leverage-pairs` - docs: https://docs.1delta.io/1delta-api/browse-all-leverage-pairs/ - markdown: https://docs.1delta.io/1delta-api/browse-all-leverage-pairs.md - tags: Lending (Data) Browse all leverage pairs Returns raw materialized view rows with all rate and liquidity fields. Supports single-chain address filtering or cross-chain asset-group mode. Pairs whose COLLATERAL leg has no remaining supply capacity (`depositableLong <= 0`) are dropped by default — a market that cannot take the deposit is not an opportunity at any rate, and those rows sort to the top of an APR ranking precisely because nobody can reach them. `depositableLong: null` means uncapped, i.e. unlimited, and always passes. `includeIlliquid=true` keeps them. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chainId` | query | string | no | Single chain ID (address-based filtering). Omit for cross-chain asset-group mode. See the `ChainId` schema for the full set of supported chains. | | `chainIds` | query | string | no | Comma-separated chain IDs for multi-chain (asset-group filtering) See the `ChainId` schema for the full set of supported chains. | | `lender` | query | string | no | Lender filter (UPPER_SNAKE_CASE) See the `LenderId` schema for the full set of accepted values. | | `minApr` | query | number | no | Minimum total APR | | `maxApr` | query | number | no | Maximum total APR | | `minLeverage` | query | number | no | Minimum leverage | | `assetLong` | query | string | no | Long asset address (single-chain mode) | | `assetShort` | query | string | no | Short asset address (single-chain mode) | | `assetGroupLong` | query | string | no | Long asset group (ILIKE partial match) | | `assetGroupShort` | query | string | no | Short asset group (ILIKE partial match) | | `minDepositApr` | query | number | no | Min effective deposit APR (deposit_rate + intrinsic_yield) | | `minLtv` | query | number | no | Minimum LTV ratio (0-1) | | `maxBorrowRate` | query | number | no | Max effective borrow rate (borrow_rate + intrinsic_yield) | | `includeIlliquid` | query | boolean | no | Keep pairs whose collateral leg has no remaining supply capacity (un-openable at any size). Off by default. | | `minLiquidityUsdLong` | query | number | no | Min collateral-side liquidity USD. This is withdrawable CASH in the market, NOT deposit capacity — see `includeIlliquid` for the capacity gate. | | `minDepositsUsdLong` | query | number | no | Min collateral-side deposits USD | | `maxUtilizationLong` | query | number | no | Max collateral-side utilization (0-1) | | `minBorrowLiquidityUsd` | query | number | no | Min debt-side borrow liquidity USD | | `minDebtUsdShort` | query | number | no | Min debt-side total debt USD | | `maxUtilizationShort` | query | number | no | Max debt-side utilization (0-1) | | `start` | query | integer | no | Pagination offset | | `count` | query | integer | no | Page size (max 100) | | `sortBy` | query | "aprTotal" \| "maxLeverage" \| "depositRateLong" \| "variableBorrowRateShort" \| "intrinsicYieldLong" \| "intrinsicYieldShort" \| … (13 values) | no | Sort field | | `sortDir` | query | "ASC" \| "DESC" | no | Sort direction | **Response `200`** — Paginated leverage pairs | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | | | `data.start` | integer | | | `data.count` | integer | Number of entries in `items`. | | `data.items` | object[] | The result set for this response. | | `data.items[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.items[].lender` | string | Protocol identifier. See the `LenderId` schema. | | `data.items[].marketLongUid` | string | Market UID of the collateral side | | `data.items[].marketShortUid` | string | Market UID of the debt side | | `data.items[].marketNameLong` | string | Display name of the collateral market/vault (e.g. the Euler eVault name). Disambiguates rows that share the collateral/debt token symbols and lender. | | `data.items[].marketNameShort` | string | Display name of the debt market/vault. For Euler this is the controller (debt) eVault — the primary way to tell otherwise-identical WETH→USDC rows apart. | | `data.items[].curatorNameLong` | string | Curator/brand of the collateral market (Euler: resolved from the vault governor). Null for lenders without a curator, or until the curator registry is seeded. Render as "curatorName + symbol", falling back to marketNameLong. | | `data.items[].curatorNameShort` | string | Curator/brand of the debt (controller) market. Same semantics as curatorNameLong. | | `data.items[].assetLong` | string | Collateral asset address | | `data.items[].assetShort` | string | Debt asset address | | `data.items[].assetGroupLong` | string | | | `data.items[].assetGroupShort` | string | | | `data.items[].symbolLong` | string | Collateral token symbol | | `data.items[].nameLong` | string | Collateral token name | | `data.items[].symbolShort` | string | Debt token symbol | | `data.items[].nameShort` | string | Debt token name | | `data.items[].collateralFactorLong` | number | Liquidation collateral factor for the long side | | `data.items[].borrowCollateralFactorLong` | number | Borrow-adjusted collateral factor for the long side | | `data.items[].borrowFactorLong` | number | Borrow factor for the long side | | `data.items[].collateralDisabledLong` | boolean | Whether collateral is disabled for the long asset | | `data.items[].debtDisabledLong` | boolean | Whether debt is disabled for the long asset | | `data.items[].collateralFactorShort` | number | Liquidation collateral factor for the short side | | `data.items[].borrowCollateralFactorShort` | number | Borrow-adjusted collateral factor for the short side | | `data.items[].borrowFactorShort` | number | Borrow factor for the short side | | `data.items[].collateralDisabledShort` | boolean | Whether collateral is disabled for the short asset | | `data.items[].debtDisabledShort` | boolean | Whether debt is disabled for the short asset | | `data.items[].eModeConfigId` | string | E-mode configuration ID | | `data.items[].eMode` | string | E-mode category | | `data.items[].aprBase` | number | Base APR (deposit - borrow + intrinsic, before rewards) | | `data.items[].aprTotal` | number | Total APR (base + rewards) | | `data.items[].maxLeverage` | number | Highest leverage multiple reachable in this market. | | `data.items[].ltv` | number | Loan-to-value ratio (0-1) | | `data.items[].depositRateLong` | number | | | `data.items[].variableBorrowRateShort` | number | | | `data.items[].intrinsicYieldLong` | number | | | `data.items[].intrinsicYieldShort` | number | | | `data.items[].variableBorrowDisabledShort` | boolean | True when the debt (short) market is a Lista DAO brokered market — it cannot be looped at a variable rate, only at one of the fixed terms in `termsShort`. `variableBorrowRateShort` is `0`/undefined for such pairs. | | `data.items[].termsShort` | object[] | Fixed-term rate card for the debt (short) side when it is a Lista DAO brokered market. Each entry is one loop option — see the per-term net-APR recipe. `null`/empty for regular variable-rate pairs. For Term Finance an empty card means "not borrowable right now" rather than "no offers" — read `fixedTerm.auction` for why. | | `data.items[].termsShort[].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[].termsShort[].depositApr` | number | Annualised fixed LEND rate at this maturity, in percent (Exactly only — its fixed pools quote both sides). | | `data.items[].termsShort[].available` | number | Borrowable liquidity at this maturity in loan-token human units (Exactly only). | | `data.items[].termsShort[].durationDays` | number | How long the position is locked at the fixed rate, in days (e.g. 7, 14, 30). | | `data.items[].termsShort[].durationSecs` | number | Term duration in seconds (raw on-chain value). | | `data.items[].termsShort[].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[].termsShort[].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[].termsShort[].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[].termsShort[].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[].termsShort[].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[].termsShort[].ladder[].apr` | number | Annualised borrow rate at this tier (%). | | `data.items[].termsShort[].ladder[].units` | string | Credit/debt units at this tier (raw). | | `data.items[].termsShort[].ladder[].assets` | number | Loan-token size available at this tier. | | `data.items[].fixedTerm` | object | Fixed-term descriptor for this pair's lender, joined by lender key. Absent on variable-rate lenders. **For Term Finance (`model: "term"`), gate the borrow/loop CTA on `fixedTerm.auction.canBorrow`**: origination only happens inside scheduled sealed-bid auction rounds and most repos sit between rounds, so a pair can carry a maturity, an LTV and a rate and still be impossible to borrow. Note also that `aprBase`/`aprTotal` on such a pair are computed against a `variableBorrowRate` of 0 and therefore read as an enormous leveraged yield with a free debt leg — show them as indicative, not obtainable, whenever `canBorrow` is false. | | `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[].rewardAprLong` | number | Total reward APR on the collateral side | | `data.items[].rewardAprShort` | number | Total reward APR on the debt side | | `data.items[].rewardsLong` | object[] | Reward programs for the collateral side | | `data.items[].rewardsShort` | object[] | Reward programs for the debt side | | `data.items[].totalDepositsLong` | number | Total deposits in token units (long side) | | `data.items[].totalDebtLong` | number | Total debt in token units (long side) | | `data.items[].totalLiquidityLong` | number | Total liquidity in token units (long side) | | `data.items[].totalDepositsShort` | number | Total deposits in token units (short side) | | `data.items[].totalDebtShort` | number | Total debt in token units (short side) | | `data.items[].totalLiquidityShort` | number | Total liquidity in token units (short side) | | `data.items[].totalDepositsUsdLong` | number | | | `data.items[].totalDebtUsdLong` | number | | | `data.items[].totalLiquidityUsdLong` | number | | | `data.items[].totalDepositsUsdShort` | number | | | `data.items[].totalDebtUsdShort` | number | | | `data.items[].totalLiquidityUsdShort` | number | | | `data.items[].borrowLiquidityShort` | number | Available borrow liquidity (debt side) in token units | | `data.items[].withdrawLiquidityLong` | number | Available withdraw liquidity (collateral side) in token units | | `data.items[].depositableLong` | number | Remaining deposit capacity (collateral side) in token units | | `data.items[].utilizationLong` | number | | | `data.items[].utilizationShort` | number | | | `data.items[].underlyingInfoLong` | object | Collateral asset metadata including token info, market prices, and oracle prices | | `data.items[].underlyingInfoLong.asset` | object | Token metadata (address, symbol, name, decimals, logoURI, assetGroup) | | `data.items[].underlyingInfoLong.prices` | object | Market prices (priceUsd, priceUsd24h, priceChange24h) | | `data.items[].underlyingInfoLong.oraclePrice` | object | On-chain oracle prices (oraclePrice, oraclePriceUsd) | | `data.items[].underlyingInfoShort` | object | Debt asset metadata including token info, market prices, and oracle prices | | `data.items[].underlyingInfoShort.asset` | object | Token metadata (address, symbol, name, decimals, logoURI, assetGroup) | | `data.items[].underlyingInfoShort.prices` | object | Market prices (priceUsd, priceUsd24h, priceChange24h) | | `data.items[].underlyingInfoShort.oraclePrice` | object | On-chain oracle prices (oraclePrice, oraclePriceUsd) | | `actions` | null | | **Example response** ```json { "success": true, "data": { "start": 1, "count": 1, "items": [ { "chainId": "1", "lender": "AAVE_V3", "marketLongUid": "string", "marketShortUid": "string", "marketNameLong": "string", "marketNameShort": "string", "curatorNameLong": "string", "curatorNameShort": "string", "assetLong": "string", "assetShort": "string", "assetGroupLong": "string", "assetGroupShort": "string", "symbolLong": "string", "nameLong": "string", "symbolShort": "string", "nameShort": "string", "collateralFactorLong": 0.94, "borrowCollateralFactorLong": 0.92, "borrowFactorLong": 1, "collateralDisabledLong": true, "debtDisabledLong": true, "collateralFactorShort": 0.94, "borrowCollateralFactorShort": 0.92, "borrowFactorShort": 1, "collateralDisabledShort": true, "debtDisabledShort": true, "eModeConfigId": "string", "eMode": "string", "aprBase": 1, "aprTotal": 1, "maxLeverage": 1, "ltv": 1, "depositRateLong": 1, "variableBorrowRateShort": 1, "intrinsicYieldLong": 1, "intrinsicYieldShort": 1, "variableBorrowDisabledShort": true, "termsShort": [ { "termId": 2, "depositApr": 1, "available": 1, "durationDays": 7, "durationSecs": 604800, "apr": 3.85, "aprAtAmount": 1, "fillable": 1, "capped": true, "ladder": [ { "apr": 1, "units": "string", "assets": 1 } ] } ], "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" } }, "rewardAprLong": 1, "rewardAprShort": 1, "rewardsLong": [ {} ], "rewardsShort": [ {} ], "totalDepositsLong": 1, "totalDebtLong": 1, "totalLiquidityLong": 1, "totalDepositsShort": 1, "totalDebtShort": 1, "totalLiquidityShort": 1, "totalDepositsUsdLong": 1, "totalDebtUsdLong": 1, "totalLiquidityUsdLong": 1, "totalDepositsUsdShort": 1, "totalDebtUsdShort": 1, "totalLiquidityUsdShort": 1, "borrowLiquidityShort": 1, "withdrawLiquidityLong": 1, "depositableLong": 1, "utilizationLong": 1, "utilizationShort": 1, "underlyingInfoLong": { "asset": {}, "prices": {}, "oraclePrice": {} }, "underlyingInfoShort": { "asset": {}, "prices": {}, "oraclePrice": {} } } ] } } ``` **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. ### GET /v1/data/lending/pairs/optimize - operationId: `collateral-to-debt-optimizer` - docs: https://docs.1delta.io/1delta-api/collateral-to-debt-optimizer/ - markdown: https://docs.1delta.io/1delta-api/collateral-to-debt-optimizer.md - tags: Lending (Data) Collateral ⇄ debt optimizer Filter pairs by either or both sides, then optionally compute the opposite-side amount per row. ## Asset selection `collaterals` / `debts` are reinterpreted by chain mode: - **Single chain** (`chainId`): values are token addresses. - **Multi-chain or no chain**: values are asset groups. Use `collateralGroups` / `debtGroups` to force group semantics in any chain mode. Group params and address params on the same side are OR'd. ### The native asset, and why you usually want groups The native asset is spelled as the **zero address** in every 1delta data payload. `0xEeee…EEeE` is an encoding-layer sentinel — it is accepted on *action* inputs and normalised away, but it is never served here and **never matches an address filter**, so a client filtering by it silently gets zero rows. Native and wrapped-native markets are different rows (`0x0` on Fluid’s ETH vaults, `0xc02a…` on Aave WETH) but share one `assetGroup` (`ETH`). Selecting by group therefore returns **both** — which is what you want whenever the two are interchangeable for your purpose (a migrate bridges them by wrapping, a leverage loop can open on either). It also removes any need for a per-chain wrapped-native address table in the client. Each asset also carries `props.isNative` + `props.wrapped` (native rows) and `props.wnative` (wrapped rows) if you need to tell them apart after the fact. ## Amount params The collateral and debt sides are **independent** — supply an amount on either side, both, or neither: - `collateralAmount` (token units; requires exactly one collateral asset) - `collateralAmountUsd` (USD; multi-asset OK) - `debtAmount` (token units; requires exactly one debt asset) - `debtAmountUsd` (USD; multi-asset OK) A collateral input adds `maxDebtAmount` + `maxDebtAmountUsd` to each row; a debt input adds `minCollateralAmount` + `minCollateralAmountUsd`. Supplying both a collateral **and** a debt amount returns **both** column pairs. Within a single side the token-unit and `*Usd` forms are mutually exclusive (400 otherwise). Un-openable pairs are dropped by default on BOTH legs (`includeIlliquid=true` keeps them). Unconditionally: a collateral leg with no remaining supply capacity (`depositableLong <= 0` — a full or deliberately zeroed supply cap, where the market returns 0 for a max-deposit query). Additionally, when an amount is supplied: a debt leg whose borrow liquidity cannot fund the resulting debt, and a collateral leg whose capacity cannot absorb the required collateral. With no amount supplied, a small-but-real capacity is a real (smaller) opportunity and stays listed; `depositableLong: null` means uncapped and always passes. ## Depth-aware APR Whenever an amount is supplied, each row also carries the EFFECTIVE APR at the computed notional: `borrowAprAtAmount`, `depositAprAtAmount`, `netAprAtAmount`. Each is the headline effective rate (`depositAprLong` / `borrowAprShort`, which fold in intrinsic yield + rewards) with only its ORGANIC (IRM) component re-priced at the utilization the position moves the pool to — intrinsic + rewards are size-invariant. So a curve lender that borrows near 0% at 0 notional prices materially higher at a real size, and `netAprAtAmount` is comparable to `aprTotal` but at the position's actual size/leverage. Pass `depth=true` to additionally receive the raw `borrowDepthShort`/`supplyDepthLong` grids. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chainId` | query | string | no | Single chain ID. When set, asset filters operate on token addresses. See the `ChainId` schema for the full set of supported chains. | | `chainIds` | query | string | no | CSV of chain IDs. When two or more, asset filters operate on asset groups. See the `ChainId` schema for the full set of supported chains. | | `lender` | query | string | no | Single lender key See the `LenderId` schema for the full set of accepted values. | | `lenders` | query | string | no | CSV of lender keys (prefix-expanded) See the `LenderId` schema for the full set of accepted values. | | `excludeLenders` | query | string | no | CSV of lender keys to exclude (prefix-expanded) | | `collaterals` | query | string | no | CSV of long-side filters. Token addresses (single chain) or asset groups (multi/no chain). | | `debts` | query | string | no | CSV of short-side filters. Same dual semantics as `collaterals`. | | `collateralGroups` | query | string | no | CSV of long-side asset groups (works in any chain mode). | | `debtGroups` | query | string | no | CSV of short-side asset groups (works in any chain mode). | | `collateralTags` | query | string | no | CSV of property flags the collateral (long) asset must carry, e.g. `eth`, `btc`, `native`, `wnative`, `stablecoin`, `savings`, `lst`, `lrt`, `pendle`, `rwa`. AND-ed with any `collaterals`/`collateralGroups` selection (narrows). Denomination flags (`eth`/`btc`) cover canonical base tokens only, not LST/derivative wrappers. | | `collateralTagsMode` | query | "any" \| "all" | no | How to match multiple `collateralTags`: `any` (has at least one) or `all` (has every one). | | `debtTags` | query | string | no | CSV of property flags the debt (short) asset must carry (e.g. `eth`, `btc`, `native`, `wnative`, `stablecoin`, `savings`, `lst`, `lrt`, `pendle`, `rwa`). Same semantics as `collateralTags`. Example: `collateralTags=lst&debtTags=wnative` for leveraged staking. | | `debtTagsMode` | query | "any" \| "all" | no | How to match multiple `debtTags`: `any` or `all`. | | `includeExpired` | query | boolean | no | Include pairs whose collateral or debt is an expired Pendle PT. Excluded by default (judged live off `props.pendle.expiry`/`expired`). | | `collateralAmount` | query | number | no | Token-unit collateral amount. Requires exactly one collateral asset. | | `collateralAmountUsd` | query | number | no | USD collateral amount. Multi-asset selections OK. | | `debtAmount` | query | number | no | Token-unit debt amount. Requires exactly one debt asset. | | `debtAmountUsd` | query | number | no | USD debt amount. Multi-asset selections OK. | | `depth` | query | boolean | no | When true, also return the raw `borrowDepthShort`/`supplyDepthLong` rate-at-depth grids. The `*AtAmount` depth-aware scalars are returned whenever an amount is supplied, regardless of this flag. | | `includeIlliquid` | query | boolean | no | By default the optimizer drops collateral legs with no remaining supply capacity, and — when an amount is supplied — pairs whose borrow liquidity cannot fund the resulting debt or whose collateral capacity cannot absorb the required collateral. Set true to keep such (un-openable) pairs. | | `minApr` | query | number | no | Minimum total APR | | `maxApr` | query | number | no | Maximum total APR | | `minLeverage` | query | number | no | Minimum leverage | | `minDepositApr` | query | number | no | Min deposit APR including intrinsic yield (long side) | | `maxBorrowRate` | query | number | no | Max borrow rate including intrinsic yield (short side) | | `minLtv` | query | number | no | Minimum LTV (0-1) | | `maxUtilizationLong` | query | number | no | Max collateral-side utilization (0-1) | | `maxUtilizationShort` | query | number | no | Max debt-side utilization (0-1) | | `minLiquidityUsdLong` | query | number | no | Min collateral-side liquidity USD. This is withdrawable CASH in the market, NOT deposit capacity — capacity is gated separately (see `includeIlliquid`). | | `minBorrowLiquidityUsd` | query | number | no | Min debt-side borrow liquidity USD | | `minDepositsUsdLong` | query | number | no | Min collateral-side deposits USD | | `minDebtUsdShort` | query | number | no | Min debt-side total debt USD | | `maxRiskScore` | query | number | no | Backwards-compat alias for `maxConfigRiskScore` | | `maxConfigRiskScore` | query | number | no | Max config risk score | | `maxTokenRiskScore` | query | number | no | Max token risk score | | `maxChainRiskScore` | query | number | no | Max chain risk score | | `maxLenderRiskScore` | query | number | no | Max lender risk score | | `start` | query | integer | no | Pagination offset | | `count` | query | integer | no | Page size (max 100) | | `sortBy` | query | "aprTotal" \| "aprBase" \| "maxLeverage" \| "ltv" \| "depositAprLong" \| "borrowAprShort" \| … (15 values) | no | Sort field | | `sortDir` | query | "ASC" \| "DESC" | no | Sort direction | **Response `200`** — Optimizer pairs | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | | | `data.chainIds` | string[] | EVM chain ids, as decimal strings. See the `ChainId` schema. | | `data.collaterals` | string[] | | | `data.debts` | string[] | | | `data.collateralAmount` | number | | | `data.collateralAmountUsd` | number | | | `data.debtAmount` | number | | | `data.debtAmountUsd` | number | | | `data.start` | integer | | | `data.count` | integer | Number of entries in `items`. | | `data.items` | object[] | The result set for this response. | | `data.items[].chainId` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.items[].lender` | string | Protocol identifier. See the `LenderId` schema. | | `data.items[].fixedTerm` | object | Fixed-term descriptor for this pair's lender, joined by lender key. Absent on variable-rate lenders. **For Term Finance (`model: "term"`), gate the borrow/loop CTA on `fixedTerm.auction.canBorrow`**: origination only happens inside scheduled sealed-bid auction rounds and most repos sit between rounds, so a pair can carry a maturity, an LTV and a rate and still be impossible to borrow. Note also that `aprBase`/`aprTotal` on such a pair are computed against a `variableBorrowRate` of 0 and therefore read as an enormous leveraged yield with a free debt leg — show them as indicative, not obtainable, whenever `canBorrow` is false. | | `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[].marketLongUid` | string | Market UID of the collateral side | | `data.items[].marketShortUid` | string | Market UID of the debt side | | `data.items[].marketNameLong` | string | Display name of the collateral market/vault (e.g. the Euler eVault name). Disambiguates rows that share the collateral/debt token symbols and lender. | | `data.items[].marketNameShort` | string | Display name of the debt market/vault. For Euler this is the controller (debt) eVault — the primary way to tell otherwise-identical WETH→USDC rows apart. | | `data.items[].curatorNameLong` | string | Curator/brand of the collateral market (Euler: resolved from the vault governor). Null for lenders without a curator, or until the curator registry is seeded. Render as "curatorName + symbol", falling back to marketNameLong. | | `data.items[].curatorNameShort` | string | Curator/brand of the debt (controller) market. Same semantics as curatorNameLong. | | `data.items[].assetLong` | string | | | `data.items[].assetShort` | string | | | `data.items[].assetGroupLong` | string | | | `data.items[].assetGroupShort` | string | | | `data.items[].symbolLong` | string | Collateral token symbol | | `data.items[].nameLong` | string | Collateral token name | | `data.items[].symbolShort` | string | Debt token symbol | | `data.items[].nameShort` | string | Debt token name | | `data.items[].aprBase` | number | Leverage-weighted net APR % EXCLUDING rewards — the SUSTAINABLE rate (reward incentives are typically transient). | | `data.items[].aprTotal` | number | Leverage-weighted net APR % INCLUDING rewards. The reward contribution is aprTotal − aprBase. | | `data.items[].maxLeverage` | number | Highest leverage multiple reachable in this market. | | `data.items[].ltv` | number | Loan-to-value ratio, as a fraction between 0 and 1. | | `data.items[].depositAprLong` | number | Effective deposit APR (depositRate + intrinsicYield) | | `data.items[].borrowAprShort` | number | Effective borrow APR % (borrowRate + intrinsicYield − rewards, plus any 1y-amortized origination fee — see originationFeeShort). For Liquity-family CDPs the amortized origination fee is the whole borrow cost (variable rate is 0). | | `data.items[].originationFeeShort` | number | One-time origination / mint fee on the debt side, PERCENT (Liquity-family CDPs: River, Felix, Nerite, Ebisu, Soneta, USDAf, Liquity). NOT an APR — it is already folded (1y-amortized) into borrowAprShort / aprTotal, and surfaced raw so consumers can re-amortize over a different holding horizon. Null/absent for markets without one. | | `data.items[].totalDepositsUsdLong` | number | | | `data.items[].totalDepositsUsdShort` | number | | | `data.items[].totalDebtUsdLong` | number | | | `data.items[].totalDebtUsdShort` | number | | | `data.items[].totalLiquidityUsdLong` | number | | | `data.items[].totalLiquidityUsdShort` | number | | | `data.items[].borrowLiquidityShort` | number | | | `data.items[].utilizationLong` | number | | | `data.items[].utilizationShort` | number | | | `data.items[].maxDebtAmount` | number | Max borrowable amount given collateral (only when collateralAmount/collateralAmountUsd param provided) | | `data.items[].maxDebtAmountUsd` | number | USD value of maxDebtAmount | | `data.items[].minCollateralAmount` | number | Min collateral needed for debt amount (only when debtAmount/debtAmountUsd param provided) | | `data.items[].minCollateralAmountUsd` | number | USD value of minCollateralAmount | | `data.items[].borrowAprAtAmount` | number | Effective borrow APR % at the computed debt notional: the headline borrowAprShort with only its organic (IRM) component re-priced at the post-borrow utilization (intrinsic + rewards are size-invariant). Present when an amount is supplied; null for non-curve lenders and brokered debt markets. | | `data.items[].depositAprAtAmount` | number | Effective supply APR % at the collateral notional: the headline depositAprLong with only its organic (IRM) component re-priced at the post-deposit utilization. Present when an amount is supplied; null for non-curve lenders. | | `data.items[].netAprAtAmount` | number | Leverage-weighted net position APR % on equity at the supplied amount, using the effective legs (INCLUDING rewards). Same components as aprTotal (directly comparable), but at the position's actual size/leverage. Null when equity is non-positive or a leg is unavailable. | | `data.items[].netAprAtAmountBase` | number | Net APR % at the supplied amount EXCLUDING rewards — the sustainable at-size rate (netAprAtAmount with per-leg rewards stripped). The at-size reward contribution is netAprAtAmount − netAprAtAmountBase. Null when netAprAtAmount is. | | `data.items[].borrowDepthShort` | object | Debt-market rate-vs-amount borrow grid. Only when depth=true. | | `data.items[].supplyDepthLong` | object | Collateral-market rate-vs-amount supply grid. Only when depth=true. | | `data.items[].risk` | object | Per-dimension risk for the pair. No composite headline score — take the worst (highest) breakdown entry if you need one. | | `data.items[].risk.maxTokenScore` | integer | Worse of the two sides' token risk scores. | | `data.items[].risk.breakdown` | object[] | One entry per dimension: config (market/e-mode configuration), chain, lender (protocol), tokenLong (collateral asset), tokenShort (debt asset), and curation — the last present ONLY for lenders that have curators (Morpho Blue, Euler). Scores are 1-5, higher = riskier; 0/null means unassessed and is labelled "unknown". | | `data.items[].risk.breakdown[].category` | string | | | `data.items[].risk.breakdown[].score` | integer | Normalized risk score — lower is safer. | | `data.items[].risk.breakdown[].label` | "low" \| "medium" \| "high" \| "unknown" | | | `data.items[].risk.breakdown[].curatorIds` | string[] | curation only: curator slugs of the pair's two markets, unioned. The pair's curation score is the WORSE of its two legs — an Euler position spanning a curated collateral vault and an uncurated controller is only as curated as the controller. | | `actions` | null | | **Example response** ```json { "success": true, "data": { "chainIds": [ "1" ], "collaterals": [ "string" ], "debts": [ "string" ], "collateralAmount": 1, "collateralAmountUsd": 1, "debtAmount": 1, "debtAmountUsd": 1, "start": 1, "count": 1, "items": [ { "chainId": "1", "lender": "AAVE_V3", "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" } }, "marketLongUid": "string", "marketShortUid": "string", "marketNameLong": "string", "marketNameShort": "string", "curatorNameLong": "string", "curatorNameShort": "string", "assetLong": "string", "assetShort": "string", "assetGroupLong": "string", "assetGroupShort": "string", "symbolLong": "string", "nameLong": "string", "symbolShort": "string", "nameShort": "string", "aprBase": 1, "aprTotal": 1, "maxLeverage": 1, "ltv": 1, "depositAprLong": 1, "borrowAprShort": 1, "originationFeeShort": 1, "totalDepositsUsdLong": 1, "totalDepositsUsdShort": 1, "totalDebtUsdLong": 1, "totalDebtUsdShort": 1, "totalLiquidityUsdLong": 1, "totalLiquidityUsdShort": 1, "borrowLiquidityShort": 1, "utilizationLong": 1, "utilizationShort": 1, "maxDebtAmount": 1, "maxDebtAmountUsd": 1, "minCollateralAmount": 1, "minCollateralAmountUsd": 1, "borrowAprAtAmount": 1, "depositAprAtAmount": 1, "netAprAtAmount": 1, "netAprAtAmountBase": 1, "borrowDepthShort": {}, "supplyDepthLong": {}, "risk": { "maxTokenScore": 1, "breakdown": [ { "category": "lender", "score": 1, "label": "low", "curatorIds": [ "string" ] } ] } } ] } } ``` **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. ### GET /v1/data/lending/pools - operationId: `get-lending-pools` - docs: https://docs.1delta.io/1delta-api/get-lending-pools/ - markdown: https://docs.1delta.io/1delta-api/get-lending-pools.md - tags: Lending (Data) Get lending pools Returns paginated lending pool data with optional filters and sorting. **Server-side defaults** (applied when the parameter is omitted; pass an explicit value to override): | Parameter | Default | |-----------|---------| | `minUtil` | `0.1` | | `maxUtil` | `0.9` | | `minTvlUsd` | `100000` (Ethereum, chainId 1) / `25000` (all other chains) | | `maxRiskScore` | `4` (medium) | To disable a default filter, pass `0` (e.g. `minUtil=0`). **Oracle risk:** each pool 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 | | --- | --- | --- | --- | --- | | `chainId` | query | string | no | Filter by chain ID See the `ChainId` schema for the full set of supported chains. | | `lender` | query | string | no | Filter by lender key (e.g. AAVE_V3) See the `LenderId` schema for the full set of accepted values. | | `underlyings` | query | string | no | Comma-separated token addresses (0x-prefixed) | | `assetGroups` | query | string | no | Comma-separated asset group names | | `minYield` | query | number | no | Minimum deposit rate | | `maxYield` | query | number | no | Maximum deposit rate | | `minUtil` | query | number | no | Minimum utilization (0-1). Defaults to 0.1 when omitted. | | `maxUtil` | query | number | no | Maximum utilization (0-1). Defaults to 0.9 when omitted. | | `minTvlUsd` | query | number | no | Minimum total liquidity in USD. Defaults to 100000 on Ethereum (chainId 1), 25000 on other chains. | | `maxTvlUsd` | query | number | no | Maximum total liquidity in USD | | `minDeposits` | query | number | no | Minimum total deposits (native units) | | `maxDeposits` | query | number | no | Maximum total deposits (native units) | | `minDebt` | query | number | no | Minimum total debt (native units) | | `maxDebt` | query | number | no | Maximum total debt (native units) | | `minLiquidity` | query | number | no | Minimum total liquidity (native units) | | `maxLiquidity` | query | number | no | Maximum total liquidity (native units) | | `minDebtUsd` | query | number | no | Minimum total debt in USD | | `maxDebtUsd` | query | number | no | Maximum total debt in USD | | `minLiquidityUsd` | query | number | no | Minimum total liquidity in USD | | `maxLiquidityUsd` | query | number | no | Maximum total liquidity in USD | | `maxRiskScore` | query | integer | no | Maximum risk score (1–5). Defaults to 4 (medium) when omitted. | | `includeExposures` | query | boolean | no | Include config exposure data per pool. Opt-in; omit or false to skip (expensive). | | `sortBy` | query | "depositRate" \| "variableBorrowRate" \| "stableBorrowRate" \| "intrinsicYield" \| "utilization" \| "totalDeposits" \| … (11 values) | no | Sort field | | `sortDir` | query | "ASC" \| "DESC" | no | Sort direction | | `start` | query | integer | no | Pagination offset | | `count` | query | integer | no | Page size (default 100, max 1000) | **Response `200`** — Pool data | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | | | `data.start` | integer | | | `data.count` | integer | Number of entries in `items`. | | `data.pools` | object[] | | | `data.pools[].chain_id` | string | EVM chain id, as a decimal string. See the `ChainId` schema. | | `data.pools[].lender_key` | string | | | `data.pools[].underlying_address` | string | | | `data.pools[].asset_group` | string | | | `data.pools[].deposit_rate` | number | | | `data.pools[].variable_borrow_rate` | number | | | `data.pools[].stable_borrow_rate` | number | | | `data.pools[].intrinsic_yield` | number | | | `data.pools[].utilization` | number | Market utilization, as a fraction between 0 and 1. | | `data.pools[].total_deposits` | number | | | `data.pools[].total_debt` | number | | | `data.pools[].total_liquidity` | number | | | `data.pools[].total_deposits_usd` | number | | | `data.pools[].total_debt_usd` | number | | | `data.pools[].total_liquidity_usd` | number | | | `actions` | null | | **Example response** ```json { "success": true, "data": { "start": 1, "count": 1, "pools": [ { "chain_id": "string", "lender_key": "AAVE_V3", "underlying_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "asset_group": "string", "deposit_rate": 1, "variable_borrow_rate": 1, "stable_borrow_rate": 1, "intrinsic_yield": 1, "utilization": 1, "total_deposits": 1, "total_debt": 1, "total_liquidity": 1, "total_deposits_usd": 1, "total_debt_usd": 1, "total_liquidity_usd": 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. ### GET /v1/data/lending/pools/by-config - operationId: `get-pools-grouped-by-config` - docs: https://docs.1delta.io/1delta-api/get-pools-grouped-by-config/ - markdown: https://docs.1delta.io/1delta-api/get-pools-grouped-by-config.md - tags: Lending (Data) Get pools grouped by config For each (lender, chain, configId) combination, returns which markets are eligible as collateral or borrowable. Each item includes a `collaterals` and `borrowables` array with per-market rate, factor, and TVL data. Either array is `null` when no markets qualify. A market absent from a config entry has both collateral and debt disabled for that config. Useful for building position-builder UIs that need to know which assets can be paired within a given pool configuration (e.g. e-mode categories, isolated pools). **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `chains` | query | string | no | Comma-separated chain IDs | | `lenders` | query | string | no | Comma-separated lender keys See the `LenderId` schema for the full set of accepted values. | **Response `200`** — Config pool breakdown per lender/chain/configId | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | Informational payload. `null` when the endpoint only builds calldata. | | `actions` | null | | **Example response** ```json { "success": true, "data": {} } ``` **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. ### GET /v1/data/snapshots - operationId: `get-lending-snapshots` - docs: https://docs.1delta.io/1delta-api/get-lending-snapshots/ - markdown: https://docs.1delta.io/1delta-api/get-lending-snapshots.md - tags: Lending (Data) Get lending snapshots Returns historical lending data time series for specified markets. **Parameters** | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `marketUids` | query | string[] | yes | Market UIDs (repeatable) | | `fields` | query | "depositRate" \| "variableBorrowRate" \| "stableBorrowRate" \| "totalDeposits" \| "totalDebtStable" \| "totalDebt" \| … (11 values)[] | no | Fields to include in each snapshot point (repeatable) | | `start` | query | string | no | ISO start date | | `end` | query | string | no | ISO end date | **Response `200`** — Lending snapshot data | Field | Type | Description | | --- | --- | --- | | `success` | true | | | `data` | object | | | `data.markets` | integer | Number of distinct markets | | `data.totalPoints` | integer | Total data points across all markets | | `data.series` | object | Map of marketUid → array of {dataTs, ...fields} | | `actions` | null | | **Example response** ```json { "success": true, "data": { "markets": 1, "totalPoints": 1, "series": {} } } ``` **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.