Markets
GET /v1/markets — lending markets (Aave V4 spokes) with supplied, borrowed, and per-reserve detail.
A market is the user-facing lending market a depositor picks:
| Protocol | Market is… | Reserves in it |
|---|---|---|
| Aave v2 / v3 | the Pool deployment | every aToken reserve in that pool |
| Aave v4 | the spoke (not the hub) | every reserve on that spoke |
| SparkLend | the Pool | every spToken reserve |
| Compound v3 | the Comet | one — the Comet's base asset |
| Morpho Blue | the loan/collateral pair | none — see below |
Ethereum alone runs Aave V3 Main, Lido, EtherFi and Horizon side by side over overlapping assets with different collateral policies — which is exactly the distinction this surface exposes.
In Aave V4 the market is the spoke — Main, Bluechip, EtherFi Cash — not the liquidity hub.
Aave V4 separates the two: a hub pools liquidity per asset and owns the rate accounting, while
several spokes draw on it, each with its own collateral set and risk policy. Markets are keyed on
the spoke because that is what a depositor chooses; hub_address records which hub it draws from,
so markets sharing liquidity remain identifiable.
Every reserve inside a market is also served as its own vault row —
reserves[].vault_id links the two — and a market's totals are aggregated from exactly those rows
at request time, so the two surfaces cannot disagree.
Not to be confused with GET /v1/vault/{id}/markets, which returns a single Morpho vault's
allocation across isolated markets. That is a different surface and requires a Data-tier key.
GET /v1/markets
List lending markets with supplied/borrowed rollups.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Page number |
| limit | number | 20 | Results per page (1–100) |
| protocol | string | — | Filter by protocol id, e.g. aave |
| version | string | — | Filter by protocol version, e.g. v4 |
| chain | number or string | — | Chain: integer id (e.g. 10) or slug (e.g. ethereum, solana) |
| sortBy | string | total_supplied_usd | total_supplied_usd, total_borrowed_usd, reserve_count, or name |
| sortOrder | string | desc | Sort order: asc or desc |
Example
curl "https://api.philidor.io/v1/markets?protocol=aave&version=v4"Response
{
"data": [
{
"id": "aave-v4-10-etherfi-cash",
"protocol_id": "aave",
"protocol_version": "v4",
"chain_id": 10,
"market_key": "etherfi-cash",
"name": "Aave V4 EtherFi Cash",
"address": "0xdffcc3536d932eb51df51a7f5fa407c4270d5308",
"hub_address": "0x66753c4e3fc84f1ed0e3c267c927284e9d90c572",
"source": "onchain_rpc",
"reserve_count": 22,
"borrow_observed_count": 2,
"total_supplied_usd": 243900000,
"total_borrowed_usd": 18800000,
"utilization": 0.3542,
"last_synced_at": "2026-08-23T18:00:00Z",
"protocol_name": "Aave",
"chain_name": "Optimism"
}
],
"meta": { "page": 1, "limit": 20, "total": 12, "totalPages": 1 }
}Two market shapes, two totals sources
Pool-shaped markets (Aave, Spark, Compound) are parents: vaults belong to them and their totals are summed from those rows. Morpho Blue markets are one loan asset against one collateral asset — they are not parents, because MetaMorpho vaults allocate across many Blue markets rather than belonging to one.
totals_source always tells you which you are reading:
| Value | Meaning |
|---|---|
members | summed from this market's own /v1/vaults rows |
protocol_api | reported by the protocol (pair-shaped markets) |
Pair-shaped markets also carry loan_asset_symbol, collateral_asset_symbol and
lltv; these are null on pool-shaped markets, whose reserves each carry their own.
Morpho Blue is permissionless — anyone can deploy a market naming any oracle, and the upstream API
reports its nominal state. On Ethereum and Base alone that is ~5,978 markets, led by fabrications
such as a market quoting $5.3B supplied at 2,980% APY. We serve only the ~378 markets Morpho
itself lists; is_protocol_listed records that.
How the totals are computed
| Field | Definition |
|---|---|
total_supplied_usd | Sum of member reserve TVL — the supply side, borrowed amounts included |
total_borrowed_usd | Sum of utilization × TVL over reserves with an observed utilization |
utilization | total_borrowed_usd over the supplied value of those observed reserves only |
A reserve whose utilization is unknown contributes to supplied but not to borrowed.
borrow_observed_count tells you how many of the reserve_count reserves had one, so a partly
observed market is visible as such rather than silently understated. When no reserve in a market
has an observed borrow side, total_borrowed_usd and utilization are null — never 0.
Only active, non-shutdown reserves roll up into these numbers.
source
| Value | Meaning |
|---|---|
protocol_api | Discovered from the protocol's own API |
onchain_rpc | Discovered on-chain |
Some Aave V4 instances are operated by third parties rather than the Aave DAO and are absent from the official Aave API — EtherFi Cash on Optimism is one. Those are indexed directly from chain, from a reviewed allowlist of hub addresses. Their numbers come from the same on-chain reads as every other Aave V4 row.
GET /v1/markets/{id}
Get a market with every reserve it contains.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| id | string | Market ID, e.g. aave-v4-10-etherfi-cash |
The ID is {protocol}-{version}-{chain}-{market_key}. Version is part of it because one protocol
can run several generations whose market names collide — Main exists in both v3 and v4.
IDs are stable. A market's key is assigned the first time we see its contract address and is
never recomputed, so an upstream rename or the appearance of a similarly-named market elsewhere
cannot change an existing /v1/markets/{id} URL or re-point it at a different market.
Example
curl https://api.philidor.io/v1/markets/aave-v4-10-etherfi-cashResponse
{
"data": {
"market": {
"id": "aave-v4-10-etherfi-cash",
"name": "Aave V4 EtherFi Cash",
"chain_id": 10,
"total_supplied_usd": 243900000,
"total_borrowed_usd": 18800000,
"reserve_count": 22
},
"reserves": [
{
"vault_id": "aave-10-0x8f2c...",
"asset_symbol": "USDC",
"asset_address": "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
"chain_id": 10,
"supplied_usd": 49423733,
"supply_apr": 0.0094,
"borrowed_usd": 18596000,
"borrow_apr": 0.03553,
"borrow_apr_net": 0.03553,
"utilization": 0.3763,
"fee_rate": 0.1,
"borrow_status": "unknown",
"is_depositable": true,
"deposit_capacity_usd": null,
"risk_tier": "Core",
"total_score": 7.4,
"is_shutdown": false
}
]
}
}reserves is ordered by supplied value descending and includes shutdown reserves, flagged via
is_shutdown, so a market's history stays readable. Follow vault_id into
GET /v1/vaults/{id} for scores, exposures, and risk vectors.
deposit_capacity_usd is null for on-chain-discovered reserves: supply caps are not read
on-chain, so deposit headroom is unknown rather than unlimited. borrow_status is unknown where
borrow permissioning cannot be observed — on EtherFi Cash, borrowing is restricted to KYC'd
cardholders.
GET /v1/markets/{id}/events
Published risk events scoped to one lending market: incidents, bad debt and liquidation cascades (PHI-244). This is the surface that answers "what has gone wrong on this market" — raw protocol telemetry (routine repays, accruals, cap changes) is deliberately not part of it.
Scoping semantics
Market-scoped events carry scope: "protocol" with the on-chain market id (for Morpho Blue, the bytes32 market id) as their entity key. Vault-scoped BadDebt rows attributed to the same market are included, since bad debt is socialized across the market's lenders but recorded per affected vault. A market with no vault allocation still produces market-scoped events — coverage does not depend on a MetaMorpho vault holding the market.
Path Parameters
| Parameter | Description |
|---|---|
id | Market id, e.g. morpho-v1-1-pt-reusd-10dec2026-usdc-91-5 |
Query Parameters
| Parameter | Description |
|---|---|
limit | Max rows, 1-100 (default 50) |
Example
curl "https://api.philidor.io/v1/markets/morpho-v1-1-pt-reusd-10dec2026-usdc-91-5/events"Response
{
"data": [
{
"id": 7771205,
"market_id": "morpho-v1-1-pt-reusd-10dec2026-usdc-91-5",
"event_type": "Incident",
"severity": "Critical",
"title": "Liquidation cascade detected on Morpho Blue market 0x1e9d6146...a4fc64",
"description": "Cumulative liquidations of approximately $35,188,279 occurred ...",
"scope": "protocol",
"vault_id": null,
"loss_amount_usd": null,
"remediation_status": "unresolved",
"tx_hash": null,
"block_number": null,
"occurred_at": "2026-08-25T04:48:35.000Z",
"detected_at": "2026-08-25T18:20:00.000Z",
"data": {
"cumulative1hUsd": 35188279,
"cascadeTrigger": "$35,188,279 liquidated within 1 hour"
}
}
]
}Events are newest first. Only published, non-retracted rows are served.
Access
/v1/markets is anonymous, like /v1/vaults. An API key raises rate limits.