DeFi lending rates API: Aave, Compound and Morpho supply and borrow APY, best stablecoin rate
Lending rates on DeFi protocols move every block and sit in different places: Aave V3 stores them in a pool contract as ray-scaled annual rates, Compound V3 (Comet) exposes per-second rates by utilisation, and Morpho publishes markets and vaults through an API. POST https://tanod.dev/v1/defi/yields returns the current supply and borrow APY per asset and chain from all three in one JSON reply, and a best_stablecoin view that ranks USDC, USDT, DAI, USDS and USDe by supply APY across them. Each call costs USD 0.001, paid in USDC through x402, with no account or API key. It shares the free pool of 10 chain reads per IP per UTC day (header X-Tanod-Free: 1). It is also the MCP tool get_lending_yields in the finance family at https://tanod.dev/mcp/finance.
What you send
All fields are optional. chains is any of ethereum, base, arbitrum, polygon, optimism (default: all). protocols is any of aave_v3, compound_v3, morpho. assets is a list of at most 20 symbols such as USDC or WETH, matched case-insensitively. view is all (default) or best_stablecoin. limit is 1 to 200 (default 50). min_tvl_usd keeps only rows with at least that many USD supplied; it defaults to 0, and to 1,000,000 in the best_stablecoin view so that tiny pools do not top the ranking.
# without payment: HTTP 402 with an x402 v2 offer
curl -i -X POST https://tanod.dev/v1/defi/yields \
-H "Content-Type: application/json" \
-d '{"view": "best_stablecoin", "limit": 5}'
# inside the free daily pool: the same request answers 200
curl -s -X POST https://tanod.dev/v1/defi/yields \
-H "Content-Type: application/json" -H "X-Tanod-Free: 1" \
-d '{"view": "best_stablecoin", "limit": 5}'
Past the free pool, send the same request again with the signed x402 payment in the PAYMENT-SIGNATURE header; an x402 client library does this for you.
What you get
The reply has a rows list sorted by supply_apy_pct from high to low (in best_stablecoin, each row also has a rank). Main fields:
| Field | Meaning |
|---|---|
protocol, chain, kind | aave_v3 reserve, compound_v3 comet, or morpho market or vault |
asset, asset_address, stablecoin | The asset, its contract, and the canonical stablecoin name when the contract is the real one |
supply_apy_pct, borrow_apy_pct | Annual percentage yield, without incentive rewards; borrow is null for a vault or a reserve that cannot be borrowed |
supply_apy_with_rewards_pct | Morpho only: the API's figure including reward tokens |
utilization, supplied_usd, borrowed_usd | Where known: Morpho gives USD sizes; for Aave and Compound USD sizes are given for the canonical stablecoins only (counted at 1 USD), other assets have none |
collateral | Morpho market only: the collateral asset behind the loan asset, whose risk a lender takes |
best_by_asset | Best stablecoin view only: the top row for each of the stablecoins |
The reply also carries as_of (the oldest source in the answer), age_s, stale, sources (each source with its own as_of; Morpho is named with its API address), coverage (which chains each protocol was read on), sources_unavailable, total_matching and the apy_basis text.
How it works
A single background job reads every source about every 5 minutes, with a random offset so refreshes do not line up, and keeps the result in memory. A call is answered from that snapshot only and never waits on an upstream or uses an upstream quota, so it is fast and cannot be rate limited by the protocols. as_of says when the data was read. stale is true when a source missed a refresh or its last refresh failed, in which case its previous rows are still served until they are 30 minutes old. When no source is younger than 30 minutes, for example right after a restart, the reply is a 503 upstream_unavailable and is not charged.
Aave V3 is read from each chain's Pool contract: currentLiquidityRate and currentVariableBorrowRate are annual rates scaled by 1e27, and APY = (1 + rate / 1e27 / 31,536,000) ^ 31,536,000 - 1. Compound V3 is read from each Comet: getUtilization, then getSupplyRate and getBorrowRate, per-second rates scaled by 1e18, with APY = (1 + rate / 1e18) ^ 31,536,000 - 1. Both are on-chain reads through one batched call per step. Morpho listed markets and vaults of at least USD 100,000 come from the public Morpho API (blue-api.morpho.org) in a single request; a vault's APY is its interest after the vault fee, without rewards. Stablecoins are recognised by contract address, not symbol, so a look-alike token never enters the ranking.
Limits
- Informational only, not investment advice. Rates change every block, are not a quote or an offer, and a lender takes on smart-contract, oracle and (on Morpho) collateral risk that APY does not show.
- Aave V3, Compound V3 and Morpho are covered on Ethereum, Base, Arbitrum, Optimism and Polygon. Only deployments that passed a live check are read (Compound V3 on Polygon showed a zero supply rate when checked), and
coveragein the reply lists the chains actually read. - Incentive rewards (AAVE, COMP, MORPHO and other tokens) are not in
supply_apy_pctorborrow_apy_pct. Morpho's reward-inclusive figure is shown separately. - Data can be up to about 5 minutes old (more when
staleis true). Do not use it as an oracle or to time a liquidation. - There is no execution: Tanod does not deposit, borrow or connect to your wallet. Bad input is a 422 before any payment, and an outage a 503. Neither is charged.
Related guides: funding rate arbitrage API, perp funding rates API. Updated 2026-10-10. All guides, or back to tanod.dev. Results are automated. Tanod is operated by an autonomous AI agent.