---
title: "Get rewards"
method: GET
path: "/v1/rewards/{walletAddress}"
tags: ["Rewards"]
---

# Get rewards

`GET /v1/rewards/{walletAddress}`

Retrieves aggregated rewards data for the specified wallet address across
supported reward sources (currently Merkle-based rewards).

After a successful claim on a specific chain, pass `reloadChain` with the human-readable chain name (e.g. `base`, `arbitrum`) to force a Merkl cache refresh for that chain.

**How to claim rewards — the `claimTransaction` is pre-built, just send it.**

Each `RewardItem` with claimable rewards includes a non-null `claimTransaction`
field. The backend has already constructed the full ABI-encoded calldata for the
`claimRewards(address,address[],uint256[],bytes32[][])` function — including the
distributor address, token addresses, amounts, and merkle proofs.

To execute the claim, send a transaction from the user's wallet with exactly
these values:
- `to`: `claimTransaction.to` — the rewards distributor contract address
- `data`: `claimTransaction.calldata` — fully encoded, ready to submit as-is
- `chainId`: `claimTransaction.chainId` — the chain to send it on

**You do NOT need to encode anything yourself.** Do not use `params`, `abi`, or
`method` to construct the calldata — those are informational only. Use `calldata`
directly as the transaction `data` field.

Example (viem):
await walletClient.sendTransaction({
  to: claimTransaction.to,
  data: claimTransaction.calldata,
  chainId: claimTransaction.chainId,
})

**Rate limiting**: 1 request per 3 seconds per client IP. Excess requests receive HTTP `429` with `Retry-After`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers (see `RateLimitExceeded` response).

## Path parameters

- `walletAddress` string, required

## Query parameters

- `reloadChain` 'ethereum' | 'base' | 'polygon' | 'arbitrum' | 'avalanche' | 'optimism' | 'linea'

## Response `200`

Rewards retrieved successfully

- GetRewardsResponse
  - `walletAddress` string, required — Wallet address
  - `timestamp` string, required — ISO timestamp
  - `totalClaimedUsd` string, required — Total claimed rewards in USD
  - `totalAvailableUsd` string, required — Total available rewards in USD
  - `rewards` RewardSource[], required
    - `source` string, required — Reward source name
    - `rewardItems` RewardItem[], required
      - `token` Token, required
        - `symbol` 'USDC' | 'MUSD' | 'USDT' | 'RLUSD' | 'USDG' | 'USDE' | 'PYUSD', required — Token symbol
        - `name` string, required — Token full name
        - `address` string, required — Token contract address
        - `decimals` integer, required — Token decimals
        - `version` string, nullable — Token contract version
      - `chain` RewardChainInfo, required
        - `id` integer, required
        - `name` string, required
        - `icon` string, required
        - `endOfDisputePeriod` integer, required
        - `explorers` ChainExplorer[], required
          - `chainId` integer, required
          - `id` string, required
          - `type` string, required
          - `url` string, required
      - `claimedRaw` string, required
      - `claimedFormatted` string, required
      - `amount` string, required
      - `claimedUsd` string, required
      - `pendingRaw` string, required
      - `pendingFormatted` string, required
      - `availableRaw` string, required — Available (unclaimed) reward amount in raw token units. When this is "0", claimTransaction will be null and no claim button should be shown. When > "0", claimTransaction is non-null and ready to execute.
      - `availableFormatted` string, required
      - `availableUsd` string, required
      - `distributorAddress` string, required
      - `proof` string[], nullable
      - `vestingInfo` VestingInfo
        - `totalAllocatedRaw` string, required
        - `totalAllocatedFormatted` string, required
        - `unlockedRaw` string, required
        - `unlockedFormatted` string, required
        - `lockedRaw` string, required
        - `lockedFormatted` string, required
        - `vestingStartTime` integer, required
        - `vestingEndTime` integer, required
        - `vestingDuration` integer, required
        - `vestingGranularity` integer, required
        - `initialUnlockBps` integer, required
        - `bpsDenominator` integer, required
        - `progressPercentage` string, required
        - `daysElapsed` integer, required
        - `daysTotal` integer, required
        - `stepsCompleted` integer, required
        - `stepsTotal` integer, required
      - `claimTransaction` ClaimTransaction
        - `to` string, required — The rewards distributor contract address. Use as the `to` field of the transaction.
        - `chainId` integer, required — The EVM chain ID to send the transaction on. Ensure the wallet is on this chain before calling sendTransaction.
        - `chain` string, required — Human-readable chain name (informational, e.g. "ethereum", "linea").
        - `method` string, required — The contract function signature — informational only. The value is "claimRewards(address,address[],uint256[],bytes32[][])". Do NOT use this to build the transaction — use `calldata` directly.
        - `params` ClaimTransactionParams, required
          - `distributor` string, required
          - `tokens` string[], required
          - `amounts` string[], required
          - `proofs` array[], required
            - string[]
        - `abi` string, required — The ABI fragment for the claimRewards function — informational only. Do NOT use this to re-encode the calldata — use `calldata` directly.
        - `calldata` string, required — Fully ABI-encoded transaction data, ready to submit as-is. Use this as the `data` field of sendTransaction. This includes the function selector and all encoded arguments (distributor, token addresses, amounts, merkle proofs). Example: walletClient.sendTransaction({ to, data: calldata, chainId })

## Other responses

- `400` — Validation error
- `401` — No authorization header provided
- `429` — Too many requests for this endpoint. Limits are enforced per client IP for the public API routes backed by `RebalancerResource` (and related resources using the same filter). Response headers (when throttled): - `Retry-After`: seconds to wait before retrying (matches the rate-limit window duration for that endpoint). - `X-RateLimit-Limit`: maximum requests allowed in the window (e.g. `1`). - `X-RateLimit-Remaining`: remaining requests in the window (`0` when throttled). - `X-RateLimit-Reset`: Unix timestamp (seconds) when the limit window resets. `internalCode` in the JSON body is `THROTTLE_PER_IP` for IP-scoped limits (other values may apply for different scopes in the backend).
- `500` — Internal error

---

[API](https://skmtc.net/metalend/apis/metalend-rebalancing-api.md) · [All operations](https://skmtc.net/metalend/apis/metalend-rebalancing-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/metalend/metalend-rebalancing-api/versions/1b9900a9e91e/schema)
