Common queries
Copy-pasteable curl recipes for the queries integrators reach for first.
Every recipe below shows the query itself in a graphql block, a one-click link that opens Apollo Sandbox with the query pre-loaded, and the equivalent curl call. Replace the example vault address, chain ID, or user address with your own and the queries will return live data.
Recipes
3
A user's share balance and pending/claimable deposits and redeems.
List vaults on a chain
Top vaults on Ethereum by USD TVL, paginated, only those visible on the Lagoon frontend:
query ListVaults {
vaults(
first: 10
skip: 0
orderBy: totalAssetsUsd
orderDirection: desc
where: { chainId_eq: 1, isVisible_eq: true }
) {
items {
address
name
symbol
state {
totalAssetsUsd
pricePerShareUsd
yearlyApr { linearNetApr twrrNetApr }
}
}
pageInfo { hasNextPage totalCount }
}
}Returns items (the vaults) plus pageInfo.totalCount for total match count and pageInfo.hasNextPage for paging.
Get a single vault by address
Fetch one vault with its current state, underlying asset, and chain:
state carries every live metric (TVL, supply, price-per-share, fees, sync mode, guardrails, roles). Pick only the fields you need.
Get a user's positions across vaults
A user's full position on a given chain — share balance, pending and claimable deposits, pending and claimable redeems — in one round trip:
This is the off-chain equivalent of the three on-chain calls described in Get a user position (balanceOf + maxMint + pendingRedeemRequest), plus the dollar value and the claimable-deposit current-price actualization.
Stream vault events
Most recent settlement events for a vault, with the event payload pulled from the TransactionData union via inline fragments:
TransactionData is a union — request only the variants you care about with ... on EventName fragments. The full list of event types is in the TransactionType enum (browsable in Sandbox). See Key data structures and epoch mechanism for the semantics of each event.
Historical vault state at a timestamp
Reconstruct a vault as it existed at a past Unix timestamp:
stateAt returns null (or a BAD_USER_INPUT error) for timestamps before the vault's first indexed state. For a time series of any of these fields, use stateHistory instead — see Conventions → Historical data.
Global Lagoon TVL
Returns a single Float — the aggregate USD TVL across all Lagoon vaults, sourced from DeFiLlama.
How the Lagoon dApp uses these queries
The production app.lagoon.finance frontend is built on exactly this API. A few patterns from that integration that are worth copying:
Server-side fetch, no client library. The dApp uses plain
fetchwithcache: 'no-store'from Next.js route handlers — no Apollo or urql. Letting the framework handle revalidation (ISR /revalidatedirectives) is simpler than maintaining a normalized cache, and the API returns whole entities anyway.Compose queries from fragments. Vault listing pages and vault detail pages share a
VaultFieldsfragment but pick different sub-fragments (VaultFieldsListLightskips APR data for fast homepage rendering;VaultFieldsDetailadds composition, fees, and roles). Define one fragment per logical view and interpolate into multiple queries.isVisible_eq: truefor frontend listings. Vaults flagged as not visible are still indexed and queryable, but should be filtered out of any list shown to end users.Page with
pageInfo.totalCountandhasNextPage. The dApp's transaction-history view does offset pagination with a smallfirstvalue (e.g. 10) and usestotalCountto render the page count up-front.Health-check on every request batch. Route handlers that fan out to multiple queries include
_meta { lastIndexedBlocks { chainId number } }so the UI can surface "data may be stale" when a chain is more than ~1 hour behind.Lowercased addresses in filters. Always normalize address inputs (e.g. with viem's
getAddress/.toLowerCase()) before passing them to_eq/_infilters.
Last updated