Docs

Fetch Rewards Data

Fetch Vault and market rewards from Morpho and Merkl APIs, including user-specific claims, caching, rate limits, and error handling.

This tutorial shows you how to fetch reward information for Morpho Vaults and Markets from the Merkl API. Vault and market reward rates are not supported in the Morpho REST API yet.

What You'll Learn

  • Understand current REST availability for Vault V2 reward rates
  • How to query user-specific rewards from Merkl API
  • Handle caching and errors for user-specific reward data

Prerequisites

  • Basic understanding of Reward Programs
  • Familiarity with REST APIs
  • A tool for making API requests (curl, fetch, or axios)

API Landscape Overview

Use Merkl for current user rewards; Morpho REST does not yet serve vault or market reward rates:

APIUse CaseRewards TypeData Provided
Morpho REST APIVault/Market reward ratesNot supported yetReward APRs and vault/market-to-reward-token mappings aren't available in the REST API yet; a known token's metadata is available through GET /v0/tokens/{token-selector}
Merkl APIUser claimable rewardsMerkl onlyUser balances, claim data, real-time rewards
Legacy RewardsUser claimable rewardsURD onlyDeprecated. Use rewards-legacy.morpho.org

Recommended Strategy:

  1. Vault/market reward APRs are not supported in the Morpho REST API yet.
  2. Use Merkl API for user-specific Merkl rewards
  3. For legacy URD rewards, direct users to rewards-legacy.morpho.org

Fetching Morpho Vault V2 Rewards

Using Morpho API

Vault V2 reward APRs are not supported in the REST API yet.

Fetching Market Rewards

Market supply and borrow reward APRs are not supported in the REST API yet.

Fetching User-Specific Rewards

Merkl API (Current Programs)

To get a user's claimable Merkl rewards:

Endpoint:

GET https://api.merkl.xyz/v4/users/{address}/rewards?chainId={chainId}

Example:

curl "https://api.merkl.xyz/v4/users/0x1234...5678/rewards?chainId=1"

Response Structure:

[
  {
    "chain": { "id": 1, "name": "Ethereum" },
    "rewards": [
      {
        "token": { "address": "0xREWARD_TOKEN", "symbol": "MORPHO", "decimals": 18 },
        "amount": "2000000000000000000",
        "claimed": "1000000000000000000",
        "pending": "0",
        "proofs": ["0xproof1", "0xproof2"]
      }
    ]
  }
]

The response is an array of per-chain objects, each with a rewards array. A token's currently-claimable balance is amount - claimed (both are cumulative). pending is reward not yet in a live merkle root.

TypeScript Example:

async function fetchMerklRewards(userAddress: string, chainId: number) {
  const response = await fetch(
    `https://api.merkl.xyz/v4/users/${userAddress.toLowerCase()}/rewards?chainId=${chainId}`
  );
  const data = await response.json();

  // The endpoint returns an array of per-chain objects; flatten to a list of rewards.
  const rewards = data.flatMap((entry) => entry.rewards);

  // Aggregate the unclaimed balance per token (amount - claimed)
  const claimableByToken: Record<string, bigint> = {};

  for (const reward of rewards) {
    const unclaimed = BigInt(reward.amount) - BigInt(reward.claimed);
    claimableByToken[reward.token.address] =
      (claimableByToken[reward.token.address] || 0n) + unclaimed;
  }

  return claimableByToken;
}

Legacy Rewards (Pre-Merkl)

Performance Considerations

Caching

Vault and market reward rates are not supported in the Morpho REST API yet.

User Merkl Rewards:

  • Cache for 5-10 minutes
  • Updates every 8 hours, but users expect fresh data

Parallel Fetching

When fetching rewards for multiple users, independent Merkl requests can run in parallel. Vault/market reward-rate fetching is not supported in the Morpho REST API yet.

Error Handling

async function fetchRewardsSafely(userAddress: string) {
  try {
    const merkl = await fetchMerklRewards(userAddress);
    return merkl;
  } catch (error) {
    console.error("Merkl API error:", error);
    return {}; // Fallback to empty
  }
}

API Rate Limits

Be mindful of rate limits:

APIRate LimitNotes
Morpho API5k / 5 minUse responsibly
Merkl API10 request / secondCache responses

Best Practice: Cache aggressively and fetch only when needed.

Next Steps

Resources