# Get vault data across providers

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

---

### GET /v1/data/vaults

- operationId: `vaults`
- docs: https://docs.1delta.io/1delta-api/vaults/
- markdown: https://docs.1delta.io/1delta-api/vaults.md
- tags: Vaults (Data)

Get vault data across providers

Returns public vault data across the supported ERC-4626-style providers on a single chain. By default this is served from the recorder origin — a DB-backed, USD-priced, **paginated** listing — and the response is a flat `{ start, count, items[] }` envelope (one entry per vault, see *Response shape* below).

**Pagination** — `start` is the row offset and `limit` the page size; the origin returns up to one page per call. To walk a chain, request `start=0`, then `start=limit`, `start=2*limit`, … until fewer than `limit` items come back. This is intentional: large chains return hundreds of vaults and are paged rather than returned in one payload.

**Legacy live mode** — pass `source=live` to bypass the origin and compute the data live on-chain via multicall. This returns the older **provider-keyed** `VaultPublicDataAll` shape (one key per provider, *not* `items[]`) and ignores `start`/`limit`. It is also the automatic fallback when no origin is configured (e.g. local dev) or the origin is unreachable.

**Supported providers**

| key | source |
|---|---|
| `fluid` | Fluid `fTokens` (ERC-4626 yield tokens) and vaults (NFT-position margin markets) |
| `gearbox` | Gearbox V3 passive PoolV3 (ERC-4626 Diesel shares) |
| `morpho` | Morpho Blue MetaMorpho vaults |
| `lista` | Lista DAO earn vaults (Moolah-fork of MetaMorpho, BNB chain; fetched on-chain) |
| `silo` | Silo V2 + V3 isolated lending vaults (GraphQL-backed) |
| `euler-earn` | Euler V2 Earn vaults (ERC-4626) |
| `lst` | Protocol-issued liquid-staking share tokens (Lido wstETH, Rocket Pool rETH, EtherFi weETH, Renzo ezETH, Kelp rsETH, Swell rswETH/swETH, Puffer pufETH, YieldNest ynETH, StakeWise osETH, Stader ETHx, Mantle mETH, Coinbase cbETH). Ethereum only in this drop. |
| `savings` | ERC-4626 yield-bearing-stablecoin wrappers (Ethena sUSDe, Sky sUSDS/stUSDS, Maker sDAI, Reservoir wsrUSD, YieldFi yUSD, Resolv wstUSR, Angle stUSD/stEUR, Falcon sUSDf, InfiniFi siUSD, Maple syrupUSDC/syrupUSDT). Plus Avant savUSD on Avalanche and YO yoETH on Base. |
| `yearn` | Yearn V3 vaults (VaultV3 + TokenizedStrategy ERC-4626) on Ethereum, Polygon, Base, Arbitrum, Gnosis, Sonic, Katana. Discovered + priced via the yDaemon API. |
| `pendle` | Pendle V2 Principal Tokens as fixed-rate earn products — one row per **live** market. Not a share token (USD size, no share price); entry and exit are swaps. |
| `spectra` | Spectra V2 Principal Tokens, same instrument as `pendle` over a rate-adjusted Curve StableSwap-NG pool. Live on Ethereum, Base, Flare, Katana, Hemi, HyperEVM and BNB; the API routes on a network NAME, so a new Spectra chain needs a registry entry before it appears. |
| `aave-earn` | Aave Earn ("stable") vaults — curator-run ERC-4626 wrappers over an Aave v3 supply position. Discovered + priced via the Aave public GraphQL API (`api.v3.aave.com`) by tracked curator/vault, enriched on-chain for `totalSupply` + share price. |

**Response shape**

*Default (origin) mode:* `{ start, count, items[] }` where each item is a normalized, USD-priced vault record: `{ chainId, provider, vaultAddress, underlying, symbol, name, displayName, curatorName, decimals, assetDecimals, dataTs, updatedAt, rates: { depositRate, rewardsRate, totalRate, fee }, tvl: { totalAssets, totalSupply, totalAssetsFormatted, totalAssetsUsd }, liquidity: { liquidity, liquidityFormatted, liquidityUsd }, underlyingInfo, vaultInfo, curatorEntity, providerMeta, … }`. `totalAssetsUsd` / `liquidityUsd` are computed by the recorder from its own price store (see margin-fetcher `DATABASE_INTEGRATION.md`).

Three metadata bundles travel with every item (mirroring lending's `underlyingInfo` + `lenderInfo`):

- **`underlyingInfo`** — the underlying token: `{ asset: { chainId, address, symbol, name, decimals, logoURI, assetGroup, currencyId, props }, prices: { priceUsd, priceTs } }`.
- **`vaultInfo`** — the vault's *own* identity: `{ address, symbol, name, logoURI, assetGroup, yieldProfile, denomination }`. `logoURI` is resolved from the **share token's** token-list entry, falling back to the underlying asset's logo. `name` uses the branded share-token name for `lst`/`savings` (e.g. *etherFi weETH*) and the curated label elsewhere (e.g. *Steakhouse USDC*).
- **`curatorEntity`** — the curator's `{ name, logoUri }` from the curator registry, or `null`.

*Legacy live mode (`source=live`):* the top-level object is keyed by provider name. Each provider's value is a free-form payload from `@1delta/margin-fetcher`'s `getVaultPublicDataAll` — schemas diverge per provider (see the package's types for exact field shapes). Common fields across most providers: vault/share token address, underlying asset, supply rate, total assets / supply, and provider-specific metadata (e.g. Fluid `vaultId`, Silo `siloAddress`).

**LST deposit metadata (`providerMeta` on `lst` items)**

`lst` records carry the data needed to build a deposit without reading SDK source:

- `isMintable` — `false` ⇒ no permissionless on-chain mint (e.g. cbETH); skip the action endpoint.
- `mintContract` — the mint target.
- `exchangeRate` / `convertToShares` — to compute expected output and a `minOut`.
- `isRebasing` — output-balance semantics (stETH/eETH rebase; wstETH/weETH don't).
- `mintInputAsset` — the **primary** pay asset (`native` or an ERC-20 address).
- **`acceptedInputs[]`** — the full accept-set, each `{ asset: "native"|"0x…", symbol?, mode: "direct"|"wrap"|"submit-wrap", needs?: string[] }`. `asset` is what to pass as `payAsset`; `needs` lists the option query params that path requires. This is the machine-readable answer to "what can I pay with"; drive the deposit request off it. See `GET /v1/actions/vaults/lst` for the build flow.
- **`delegation`** — present only when the deposit requires/allows picking a validator/group/node/pool: `{ required, kind, optionKey, default, source }`. **Absent ⇒ pooled** (no picker needed). When present and `source: "endpoint"`, fetch the selectable set from [/v1/data/vaults/validators](https://docs.1delta.io/1delta-api/vaults-validators/) and send the chosen `id` back to the deposit as the param named by `delegation.optionKey`. This is the flag that tells the UI whether a validator fetch is needed. Attached by the worker in both origin and `source=live` modes.

**Exit fees (`withdrawFeeBps`)**

Basis points (`10` = 0.10 %), on `gearbox` pools and on `savings` entries whose `withdrawalMode` is `fee-or-queued` (Native Credit Pool `wNLP`). Distinct from `rates.fee`, which is a **performance** fee skimmed from yield — `withdrawFeeBps` is a one-off charge on the way **out**.

For Native `wNLP` specifically, an exit has two legs and only one of them is priced by this field:

- **Instant** (`instantRedeem`) — the fee is deducted from the underlying paid to the receiver, never collected as a separate transfer, so the caller neither funds nor approves it: `received = shares × exchangeRate × (1 − withdrawFeeBps/10_000)`. Capped by `liquidity`, which is a **gross** figure — what actually lands is `liquidity × (1 − withdrawFeeBps/10_000)`.
- **Queued** (`requestWithdrawal` → wait `withdrawalCooldownSeconds` → `claim`) — pays at par, so `withdrawFeeBps` does not apply. Its cost is implicit: the payout is snapshotted at request time and yield accruing over the wait goes to the protocol. At a 3-day window that is worth a few bps against a 100 bps instant fee, which is why the action builders default to the queue and require `instant=true` to take the haircut.

There is no deposit or management fee on these vaults — `exchangeRate` and the reported rates are already net. `instantRedeemEnabled: false` means the pool is queue-only and `withdrawFeeBps` is unreachable.

**Lockup likelihood (`instantLiquidityRatio`, `savings` items)**

`liquidity / totalAssets` clamped to `0…1` — the share of the vault exitable **this block**, so `1 − instantLiquidityRatio` is the share that must queue. `instant` vaults report `1`, cooldown/queued/request-based report `0`, and Native `fee-or-queued` pools report live coverage (observed across the full range: `1.00` on Ethereum `wNLP-USDC`, `0.20` on `wNLP-WBTC`, `0.0005` on BNB `wNLP-T4B`).

Not named `utilization` on purpose: these protocols expose no debt accumulator, so `borrowed / supplied` is not readable per pool — this measures exit **coverage** instead, which is what actually predicts lockup. Two caveats: Native's buffer also custodies market-maker collateral so it can exceed the pool it serves (hence the clamp — `1` means "fully covered", not "zero utilization"), and it is a live spot reading that moves as market makers draw inventory. Nothing is lost below `1`; the remainder redeems at par through the queue.

**Related action endpoints**

- `GET /v1/actions/vaults/deposit` — ERC-4626 deposit via the 1delta Composer, with optional Fluid native-deposit path. Also serves Native `wNLP` (auto-detected; no `underlying` needed).
- `GET /v1/actions/vaults/withdraw` — ERC-4626 withdraw via the 1delta Composer, with native-unwrap support. Also serves Native `wNLP` (`instant=true` for the fee-paying leg).
- `GET /v1/actions/vaults/lst` — LST/LRT mint · withdraw-request · claim · cancel, driven by the `acceptedInputs` above.
- `GET /v1/actions/vaults/savings` — cooldown/queued savings exits, plus Native `wNLP` deposit · request-withdraw · claim · cancel.

For Fluid **margin vaults** (the NFT-position kind, not fTokens), the lending action endpoints (`/v1/actions/lending/{deposit,withdraw,borrow,repay}`) are the right surface — they understand the per-vault `FLUID_<chainId>_<vaultId>` lender keys and Fluid's NFT ownership model (including the pre-flight `ownerOf` validation for deposit-to-existing-NFT with a custom `receiver`).

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `chainId` | query | string | yes | Chain ID to query See the `ChainId` schema for the full set of supported chains. |
| `start` | query | integer | no | Pagination offset (origin mode). Row index of the first item to return. Non-negative integer; defaults to 0. |
| `limit` | query | integer | no | Pagination page size (origin mode). Max items to return per call. Non-negative integer. Ignored in `source=live` mode. |
| `provider` | query | string | no | Origin mode: narrow the listing to a single provider (e.g. `morpho`). |
| `source` | query | "live" | no | Set to `live` to bypass the origin and compute on-chain via multicall (returns the legacy provider-keyed shape; `start`/`limit` ignored). |
| `providers` | query | string | no | Legacy live mode only (`source=live`): CSV of vault providers to include. Defaults to all (`fluid,gearbox,morpho,lista,silo,euler-earn,lst,savings,lagoon,aave-earn,upshift,yearn,hypercore,gmx`). Unknown providers return 400. |
| `includeExpired` | query | "true" \| "false" | no | Legacy live mode only (`source=live`): include MATURED fixed-maturity markets (`pendle`, `spectra`). Off by default and deliberately so — a matured principal token keeps publishing its last pre-expiry implied APY, which on a rate-sorted list is a rate that no longer exists on a product that no longer exists. Set it only for a holder-facing redeem flow. Note Spectra's upstream listing appears to drop matured markets itself, so this may return nothing for that provider. |
| `siloProtocolVersion` | query | "v2" \| "v3" | no | Narrow the Silo query to a single protocol version. Has no effect on other providers. |
| `siloLimit` | query | integer | no | Page-size hint for the Silo GraphQL query (positive integer). |
| `terms` | query | "digest" \| "full" \| "none" | no | Term-sheet depth attached to every vault as `termSheet` — the SAME shape and the same parameter as `/v1/data/lending/latest`, so one renderer handles an Aave reserve and a Pendle PT. A vault carries `termSheet.supply` only; `borrow` is absent, and that absence is the statement that it cannot be borrowed. `digest` (default) is the compact form; `full` inlines `info.description`, `backedBy.items[]` and the `coverage` map; `none` omits the field. **Read `coverage` before trusting a silence** — it separates "does not apply here" (`notApplicable`) from "not wired yet" (`pending`), so an absent `governance` block never reads as "ungoverned". Origin mode only. |

**Response `200`** — Origin mode: `{ start, count, items[] }` paginated, USD-priced vault records. Legacy live mode (`source=live`): provider-keyed vault data, with failed providers omitted (the worker logs a warning but does not propagate per-provider errors).

| 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.
