Docs

Morpho Blue

How to query Morpho Blue data with the API?

Each example below is available as REST (selected by default) or GraphQL — use the tabs to switch.

  • REST calls use public GET requests against https://api.morpho.org with standard public rate limits. Markets are addressed by a <chainId>:<marketId> selector and tokens by <chainId>:<address>. REST returns single-entity reads — market config, state, APY, positions, oracle quote, and token price; there are no list endpoints, so enumeration/discovery, aggregate overviews, oracle feed composition, USD values, and reward APRs come from GraphQL.
  • GraphQL queries run against the Playground at https://api.morpho.org/graphql. By default the API returns only the first 100 results and reads from the Ethereum network.

Discovery and Listing

Markets List

# Config
curl -sS "https://api.morpho.org/v0/blue/markets/8453:0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836" \
  -H "accept: application/json"

# Live state
curl -sS "https://api.morpho.org/v0/blue/markets/8453:0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836/state" \
  -H "accept: application/json"

REST reads one market at a time by <chainId>:<marketId>. Enumerating markets and filtering by listed are GraphQL-only.

query {
  markets {
    items {
      marketId
      lltv
      oracle {
        address
      }
      irmAddress
      loanAsset {
        address
        symbol
        decimals
      }
      collateralAsset {
        address
        symbol
        decimals
      }
      state {
        borrowAssets
        supplyAssets
        fee
        utilization
      }
    }
  }
}
query {
  markets(where: { listed: true }) {
    items {
      marketId
      listed
      lltv
      oracle {
        address
      }
      irmAddress
      loanAsset {
        address
        symbol
        decimals
      }
      collateralAsset {
        address
        symbol
        decimals
      }
      state {
        borrowAssets
        supplyAssets
        fee
        utilization
      }
    }
  }
}

Market Parameters

curl -sS "https://api.morpho.org/v0/blue/markets/8453:0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836" \
  -H "accept: application/json"

REST reads one market at a time by <chainId>:<marketId>. The response gives the immutable config: loan_token, collateral_token, oracle_address, irm_address, and lltv_wad. Enumerating or filtering across markets is GraphQL-only.

query {
  markets(
    first: 100
    orderBy: SupplyAssetsUsd
    orderDirection: Desc
    where: { chainId_in: [1, 8453] }
  ) {
    items {
      marketId
      loanAsset { address }
      collateralAsset { address }
      lltv
      irmAddress
      oracle {
        address
      }
    }
  }
}
query {
  marketById(
    marketId: "0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836"
    chainId: 8453
  ) {
    marketId
    loanAsset { address }
    collateralAsset { address }
    lltv
    irmAddress
    oracle {
      address
    }
  }
}

Market Metrics

Total Collateral, Borrow & Supply

curl -sS "https://api.morpho.org/v0/blue/markets/8453:0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836/state" \
  -H "accept: application/json"

/state returns total_supply_assets, total_borrow_assets, their share counts (total_supply_shares, total_borrow_shares), and fee_wad. USD-denominated values and aggregate collateral totals are GraphQL-only.

  query {
    markets(
      first: 100
      orderBy: SupplyAssetsUsd
      orderDirection: Desc
      where: { chainId_in: [1, 8453] }
    ) {
      items {
        marketId
        state {
          collateralAssets
          collateralAssetsUsd
          borrowAssets
          borrowAssetsUsd
          supplyAssets
          supplyAssetsUsd
          liquidityAssets
          liquidityAssetsUsd
        }
      }
    }
  }
query {
  marketById(
    marketId: "0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836"
    chainId: 8453
  ) {
    state {
      collateralAssets
      borrowAssets
      supplyAssets
      liquidityAssets
    }
  }
}

Market APY (Native & Rewards)

curl -sS "https://api.morpho.org/v0/blue/markets/8453:0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836/apy-averages" \
  -H "accept: application/json"

/apy-averages returns supply_apy_averages and borrow_apy_averages, each keyed by fixed trailing windows (24h, 7d, 30d, 90d, 1y). Values exclude rewards — reward APRs are GraphQL-only.

query {
  markets(
    first: 100
    orderBy: SupplyAssetsUsd
    orderDirection: Desc
    where: { chainId_in: [1, 8453] }
  ) {
    items {
      marketId
      state {
        borrowApy
        avgBorrowApy
        avgNetBorrowApy
        supplyApy
        avgSupplyApy
        avgNetSupplyApy
        rewards {
          asset {
            address
            chain {
              id
            }
          }
          supplyApr
          borrowApr
        }
      }
    }
  }
}
query {
  marketById(
    marketId: "0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836"
    chainId: 8453
  ) {
    state {
      borrowApy
      avgBorrowApy
      avgNetBorrowApy
      supplyApy
      avgSupplyApy
      avgNetSupplyApy
      rewards {
        supplyApr
        borrowApr
      }
    }
  }
}

Asset Information

Assets (Price & Yield)

# Token identity + metadata
curl -sS "https://api.morpho.org/v0/tokens/1:0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0" \
  -H "accept: application/json"

# Canonical USD spot price
curl -sS "https://api.morpho.org/v0/tokens/1:0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0/price" \
  -H "accept: application/json"

REST reads one token at a time by <chainId>:<address>: /tokens/{selector} for identity/metadata and /tokens/{selector}/price for the USD spot price (price, timestamp, provider). Native yield (yield.apr) and multi-asset symbol filtering are GraphQL-only.

query GetAssetsWithPriceAndYield {
  assets(where: { symbol_in: ["wstETH", "WETH"], chainId_in: [1] }) {
    items {
      symbol
      address
      price(maxLag: 12) {
        usd
        timestamp
      }
      yield {
        apr
        lookback
      }
      chain {
        id
        network
      }
    }
  }
}
  • price.usd is the current price of the asset in USD.
  • price.timestamp is when the returned price was recorded.
  • maxLag is the maximum lookback window in hours, from 0 to 24; default is 12.
  • yield.apr is the asset APR, when available.
  • yield.lookback is the lookback period used to compute the APR, in seconds.
  • yield can be null when no native-yield data is available.
  • USD prices are sourced from DefiLlama today, so availability and freshness can depend on DefiLlama coverage for the asset.

Position Tracking

User Positions

User All Markets Position

curl -sS "https://api.morpho.org/v0/blue/markets/1:0x698fe98247a40c5771537b5786b2f3f9d78eb487b4ce4d75533cd0e94d88a115/users/0xabcdefabcdefabcdefabcdefabcdefabcdefabcd/position" \
  -H "accept: application/json"

REST returns a single user's position in a market — collateral_assets, supply_shares, and borrow_shares — keyed by <chainId>:<marketId> and user address. Listing every position in a market, and USD-denominated values, are GraphQL-only.

query {
  marketPositions(
    first: 10,
    orderBy: BorrowShares,
    orderDirection: Desc
    where: {
      marketUniqueKey_in: ["0x698fe98247a40c5771537b5786b2f3f9d78eb487b4ce4d75533cd0e94d88a115"]
    }
  ) {
    items {
      user { address }
      state {
        collateral
        borrowAssets
        borrowAssetsUsd
      }
    }
  }
}

User Market Position

# Market position
curl -sS "https://api.morpho.org/v0/blue/markets/1:0x698fe98247a40c5771537b5786b2f3f9d78eb487b4ce4d75533cd0e94d88a115/users/0x821880a3E2bac432d67E5155e72BB655Ef65fa5E/position" \
  -H "accept: application/json"

# Vault V2 position (repeat this call per market/vault the user holds)
curl -sS "https://api.morpho.org/v0/vaults-v2/1:0x04422053aDDbc9bB2759b248B574e3FCA76Bc145/users/0x821880a3E2bac432d67E5155e72BB655Ef65fa5E/position" \
  -H "accept: application/json"

REST reads one position at a time (per market or per vault, per user); the combined cross-market/cross-vault overview and transaction history are GraphQL-only.

query {
  userByAddress(
    chainId: 1
    address: "0x821880a3E2bac432d67E5155e72BB655Ef65fa5E"
  ) {
    address
    marketPositions {
      market {
        marketId
      }
      state {
        borrowAssets
        borrowAssetsUsd
        supplyAssets
        supplyAssetsUsd
      }
    }
    vaultPositions {
      vault {
        address
        name
      }
      state {
        assets
        assetsUsd
        shares
      }
    }
    vaultV2Positions {
      vault {
        address
        name
      }
      assets
      assetsUsd
      shares
    }
  }
  vaultV1Transactions(
    first: 10
    orderBy: Time
    orderDirection: Desc
    where: {
      userAddress_in: ["0x821880a3E2bac432d67E5155e72BB655Ef65fa5E"]
      chainId_in: [1]
    }
  ) {
    items {
      txHash
      timestamp
      type
    }
  }
  marketTransactions(
    first: 10
    orderBy: Timestamp
    orderDirection: Desc
    where: {
      userAddress_in: ["0x821880a3E2bac432d67E5155e72BB655Ef65fa5E"]
      chainId_in: [1]
    }
  ) {
    items {
      txHash
      timestamp
      type
    }
  }
  vaultV2transactions(
    first: 10
    orderBy: Time
    orderDirection: Desc
    where: {
      userAddress_in: ["0x821880a3E2bac432d67E5155e72BB655Ef65fa5E"]
      chainId_in: [1]
    }
  ) {
    items {
      txHash
      timestamp
      type
      shares
      assets
      vault {
        address
        name
      }
    }
  }
}

All Market Positions

curl -sS "https://api.morpho.org/v0/blue/markets/1:0x698fe98247a40c5771537b5786b2f3f9d78eb487b4ce4d75533cd0e94d88a115/users/0xabcdefabcdefabcdefabcdefabcdefabcdefabcd/position" \
  -H "accept: application/json"

REST returns one user's position in a market (collateral_assets, supply_shares, borrow_shares). Listing every position in a market, and USD-denominated values, are GraphQL-only.

query {
  marketPositions(
    first: 10
    orderBy: SupplyShares
    orderDirection: Desc
    where: {
      marketUniqueKey_in: [
        "0x698fe98247a40c5771537b5786b2f3f9d78eb487b4ce4d75533cd0e94d88a115"
      ]
    }
  ) {
    items {
      market {
        marketId
        loanAsset {
          address
          symbol
        }
        collateralAsset {
          address
          symbol
        }
      }
      user {
        address
      }
      state {
        supplyShares
        supplyAssets
        supplyAssetsUsd
        borrowShares
        borrowAssets
        borrowAssetsUsd
        collateral
        collateralUsd
      }
    }
  }
}

Risk & Oracle Data

Oracle Data

Oracle data is returned if the oracle's type is ChainlinkOracle or ChainlinkOracleV2. creationEvent field is specific to ChainlinkOracleV2 oracles. More on oracles and ChainlinkOracleV2 oracles in the oracle section here.

All Markets

curl -sS "https://api.morpho.org/v0/oracles/1:0x2a01EB9496094dA03c4E364Def50f5aD1280AD72/state" \
  -H "accept: application/json"

REST exposes the oracle's live quote — price, last_updated_at, last_indexed_block — by <chainId>:<oracleAddress>. The feed composition (baseFeed*, quoteFeed*, scaleFactor, vault conversions) is GraphQL-only.

query Markets($first: Int, $skip: Int, $orderBy: MarketOrderBy, $orderDirection: OrderDirection, $where: MarketFilters) {
  markets(first: $first, skip: $skip, orderBy: $orderBy, orderDirection: $orderDirection, where: $where) {
    items {
      marketId
      oracle {
        address
        type
        data {
          ... on MorphoChainlinkOracleData {
            baseFeedOne {
              address
            }
            baseFeedTwo {
              address
            }
            baseOracleVault {
              address
            }
            quoteFeedOne {
              address
            }
            quoteFeedTwo {
              address
            }
            scaleFactor
            vaultConversionSample
          }
          ... on MorphoChainlinkOracleV2Data {
            baseFeedOne {
              address
            }
            baseFeedTwo {
              address
            }
            baseOracleVault {
              address
            }
            baseVaultConversionSample
            quoteFeedOne {
              address
            }
            quoteFeedTwo {
              address
            }
            quoteOracleVault {
              address
            }
            quoteVaultConversionSample
            scaleFactor
          }
        }
        creationEvent {
          txHash
          timestamp
          blockNumber
        }
      }
    }
  }
}

With the following variables as example:

{
  "first": 100,
  "skip": 0,
  "orderBy": "SupplyAssetsUsd",
  "orderDirection": "Desc",
  "where": {
    "chainId_in": [
      1,
      8453
    ],
    "listed": true
  }
}

Specific Market

curl -sS "https://api.morpho.org/v0/oracles/1:0x2a01EB9496094dA03c4E364Def50f5aD1280AD72/state" \
  -H "accept: application/json"

REST exposes the oracle's live quote (price, last_updated_at, last_indexed_block) by <chainId>:<oracleAddress>; the feed composition is GraphQL-only.

query {
  marketById(
    marketId: "0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836"
    chainId: 8453
  ) {
    marketId
    oracle {
      address
      type
      creationEvent {
        txHash
        timestamp
        blockNumber
      }
      data {
        ... on MorphoChainlinkOracleV2Data {
          baseFeedOne {
            address
          }
          baseFeedTwo {
            address
          }
          baseOracleVault {
            address
          }
          baseVaultConversionSample
          quoteFeedOne {
            address
          }
          quoteFeedTwo {
            address
          }
          quoteOracleVault {
            address
          }
          quoteVaultConversionSample
          scaleFactor
        }
        ... on MorphoChainlinkOracleData {
          baseFeedOne {
            address
          }
          baseFeedTwo {
            address
          }
          baseOracleVault {
            address
          }
          quoteFeedOne {
            address
          }
          quoteFeedTwo {
            address
          }
          scaleFactor
          vaultConversionSample
        }
      }
    } 
  }
}

Historical Data

Historical data is available through both REST and GraphQL, with different parameters for each:

  • REST exposes trailing history via fixed lookback windows (one_day, seven_days, thirty_days, ninety_days, one_year, inception) passed as a query string on the relevant /history endpoint. It is per-market/per-vault; enumeration and USD-denominated series are GraphQL-only.
  • GraphQL exposes historical data through the historicalState field, which takes startTimestamp, endTimestamp, and interval (YEAR, QUARTER, MONTH, WEEK, DAY, HOUR) as query variables — see the GraphQL tab in each example below.

The queries need to be backfilled to return proper data (i.e. the historical data needs to be indexed and stored). Some queries are not backfilled and are flagged as deprecated in the Morpho API sandbox.

How to use the GraphQL historicalState variables

Here are the available variables when using a historicalState query:

  • startTimestamp: beginning of the historical data in UNIX timestamp format,
  • endTimestamp: end of the historical data in UNIX timestamp format,
  • interval: interval of the historical data points (YEAR, QUARTER, MONTH, WEEK, DAY, HOUR). Inputting these variables is not mandatory but it is advised to specify them to control the specific data returned.

If no variables are specified, the default values will be:

  • startTimestamp: 0,
  • endTimestamp: infinity,
  • interval: will adjust according to startTimestamp and endTimestamp to return around 50 data points.

Note that the historicalState field is not accessible through the (multiple) markets(...) and vaults(...) list queries. Historical data is only available through individual market or vault queries like market(id: ""), marketById, vault(id: "") or vaultByAddress.

Historical APYs

curl -sS "https://api.morpho.org/v0/blue/markets/8453:0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836/apy/history?lookback=thirty_days" \
  -H "accept: application/json"

REST returns trailing supply/borrow APY history via fixed lookback windows (one_day, seven_days, thirty_days, ninety_days, one_year, inception) instead of an arbitrary startTimestamp/endTimestamp/interval.

query MarketById($marketId: String!, $chainId: Int!, $options: TimeseriesOptions) {
  marketById(marketId: $marketId, chainId: $chainId) {
    historicalState {
      borrowApy(options: $options) {
        x
        y
      }
      supplyApy(options: $options) {
        x
        y
      }
    }
  }
}

With the following variables:

{
  "marketId": "0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836",
  "chainId": 8453,
  "options": {
    "startTimestamp": 1755420554,
    "endTimestamp": 1755506954,
    "interval": "HOUR"
  }
}

Historical Market States

curl -sS "https://api.morpho.org/v0/blue/markets/1:0x608929d6de2a10bacf1046ff157ae38df5b9f466fb89413211efb8f63c63833a/state/history?lookback=thirty_days" \
  -H "accept: application/json"

/state/history returns trailing total_supply_assets / total_borrow_assets history via fixed lookback windows (one_dayinception). USD-denominated series are GraphQL-only.

query MarketApys($options: TimeseriesOptions) {
  marketById(
    marketId: "0x608929d6de2a10bacf1046ff157ae38df5b9f466fb89413211efb8f63c63833a"
    chainId: 1
  ) {
    marketId
    historicalState {
      supplyAssetsUsd(options: $options) {
        x
        y
      }
      borrowAssetsUsd(options: $options) {
        x
        y
      }
    }
  }
}

With the following variables:

"variables": {
"startTimestamp": 1707749700,
"endTimestamp": 1708354500,
"interval": HOUR,
}

Historical Asset Price

curl -sS "https://api.morpho.org/v0/tokens/1:0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0/price" \
  -H "accept: application/json"

REST returns the current USD spot price (price, timestamp, provider); a historical price series is GraphQL-only.

query {
  wstETHWeeklyPriceUsd: assetByAddress(
    address: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
    chainId: 1
  ) {
    historicalPriceUsd(
      options: {
        startTimestamp: 1707749700
        endTimestamp: 1708354500
        interval: HOUR
      }
    ) {
      x
      y
    }
  }
}

All queries sent for assetByAddress, marketById and vaultByAddress should include the chainId parameter.