---
title: "Get rebalancer balances"
method: GET
path: "/v1/balances/{walletAddress}"
tags: ["Balances"]
---

# Get rebalancer balances

`GET /v1/balances/{walletAddress}`

Retrieves detailed balance information across all protocols and pools for a wallet address. This endpoint provides comprehensive financial data including token balances, net earnings, aggregate APY, and per-protocol/per-pool breakdowns.<br><br>

**Authentication**: Requires a valid API key. The wallet address must be a valid checksummed EOA address.<br><br>

**Token Filtering**: The optional `tokens` query parameter accepts a comma-separated list of token symbols (e.g., `USDC,MUSD,USDT,RLUSD,USDG,USDE,PYUSD`). If not provided, balances for all supported tokens are returned.<br><br>

**Balance Details**: For each token, the response includes:
- Total balance across all chains (raw units and human-readable format)
- Net earnings in USD (calculated as current balance minus net deposits/withdrawals)
- Aggregate APY (weighted average across all protocols)
- Per-chain breakdown with per-protocol and per-pool details<br><br>

**Spending / Card Balance (USDC only)**: For users with the MetaLend card
  feature active in their configuration, the total rebalancer balance consists
  of **two parts**:

- **Regular rebalancing balance** — funds held across DeFi pools on all chains,
  shown in `perToken[n].perChain[m].perProtocol[p].perPool[q]`.
- **Card balance** — funds reserved on Linea for card spending, shown in
  `perToken[n].spendingInfo`. This is USDC only and has two sub-components:
  - Liquid USDC held in the rebalancer contract on Linea (`lineaUsdcBalance`)
  - USDC deposited in Aave V3 on Linea, earning yield while available for
    card spending (`lineaAaveUsdcBalance`)

`spendingInfo` is `null` when the card feature is not active for the user.
  When displaying total balance to the user, include both the pool balances
  AND `spendingInfo` amounts — they are additive parts of the same rebalancer.

**Withdraw Request**: Each pool balance includes optional `withdrawRequest` containing EIP-712 domain parameters, type definitions, and value structure for creating withdrawal signatures. The `value` field includes `token` and `poolContract` addresses, while `amount` and `deadline` must be supplied by the user when creating a withdrawal via `/v1/withdrawals` endpoint.<br><br>

**Summary**: The response includes an aggregate summary with total balance across all queried tokens, total net earnings, queried tokens, and queried chains.<br><br>

**Error Handling**: If blockchain queries fail or the wallet has no rebalancer configuration, appropriate error responses are returned. The endpoint uses an all-or-nothing approach - if any token query fails, the entire request fails with a 500 or 503 status code.

**Rate limiting**: 1 request per 12 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

- `tokens` string

## Response `200`

Rebalancer balances retrieved successfully

- GetBalancesResponse
  - `walletAddress` string, required — User's Ethereum wallet address
  - `rebalancerAddress` string, required — Rebalancer contract address
  - `perToken` TokenBalance[], required
    - `token` string, required — Token symbol
    - `totalBalanceRaw` string, required — Total balance in raw units
    - `totalBalanceFormatted` string, required — Human-readable balance (formatted to 2 decimals)
    - `netEarning` string, required — Net earnings in USD (formatted to 2 decimals)
    - `aggregateApy` string, required — Weighted average APY across all protocols (formatted to 2 decimals)
    - `perChain` ChainBalance[], required
      - `chain` string, required — Chain name
      - `chainId` integer, required — Chain ID
      - `totalBalanceRaw` string, required — Total balance in raw units
      - `totalBalanceFormatted` string, required — Total balance formatted
      - `perProtocol` ProtocolBalance[], required
        - `protocolName` string, required — Protocol name
        - `protocolIconUrl` string, required — Protocol icon URL
        - `totalBalanceRaw` string, required — Total balance in protocol (raw units)
        - `totalBalanceFormatted` string, required — Human-readable balance in protocol (formatted to 2 decimals)
        - `perPool` PoolBalance[], required
          - `poolAddress` string, required — Pool contract address
          - `poolName` string, required — Pool name
          - `balanceRaw` string, required — Balance in pool (raw units)
          - `balanceFormatted` string, required — Human-readable pool balance (formatted to 2 decimals)
          - `apy` string, required — Current APY for this pool (formatted to 2 decimals)
          - `chain` string, required — Chain name
          - `chainId` integer, required — Chain ID
          - `withdrawRequest` WithdrawalRequestData, required — Always present when this pool has a non-zero balance. Contains the pre-filled EIP-712 domain, types, and partial value needed to sign a withdrawal. The `value.amount` and `value.deadline` are returned as null — you MUST fill them in with your chosen values before signing.
            - `domain` Domain, required
              - …
            - `types` Types, required
              - …
            - `value` Value, required
              - …
    - `spendingInfo` SpendingInfo — Breakdown of USDC funds reserved on Linea for MetaLend card spending. Only returned when the card feature is active in the user's config. The total rebalancer balance = regular pool balances (perChain) + lineaUsdcBalance + lineaAaveUsdcBalance from this object.
      - `lineaUsdcBalanceRaw` string, required — Liquid USDC held directly in the rebalancer contract on Linea (raw units, 6 decimals). This is uninvested and immediately available for card spending.
      - `lineaUsdcBalanceFormatted` string, required — Human-readable liquid USDC balance on Linea (formatted to 2 decimals).
      - `lineaAaveUsdcBalanceRaw` string, required — USDC deposited in Aave V3 on Linea (raw units, 6 decimals). This is earning yield and also counts toward the card spending balance. Add to lineaUsdcBalanceRaw to get the full card balance.
      - `lineaAaveUsdcBalanceFormatted` string, required — Human-readable USDC balance in Aave V3 on Linea (formatted to 2 decimals).
      - `lineaAaveApy` string, required — Current APY of the Aave V3 USDC pool on Linea where card funds earn yield (formatted to 2 decimals, e.g. "2.01").
    - `bridgeBalances` BridgeBalance[], nullable
      - `sourcePool` Pool — **Important: `poolAddress` is NOT globally unique across tokens.** For Aave V3, the same `poolAddress` (the Aave lending pool contract) is shared across all tokens on a given chain. For example, Aave V3 USDC, USDT, RLUSD, MUSD, USDG, USDE, and PYUSD on Ethereum all have the same `poolAddress`. A pool is uniquely identified by the combination of THREE fields together: - `poolAddress` - `chain` - `underlyingToken.symbol` When filtering pools by token (e.g. "show only USDC pools"), ALWAYS filter on `underlyingToken.symbol`. Never filter on `poolAddress` alone for Aave pools.
        - `protocolName` string, required — Protocol name
        - `protocolVersion` string, required — Protocol version
        - `protocolDescription` string, required — Protocol description
        - `protocolUrl` string, uri, required — Protocol website URL
        - `poolAddress` string, required — Pool contract address. The pool contract address. For Aave V3 pools, this is the Aave lending pool contract address, which is the SAME for all tokens (USDC, USDT, RLUSD, MUSD, USDG, USDE, PYUSD) on a given chain. Do NOT use this field alone as a unique pool identifier — it must always be combined with `chain` and `underlyingToken.symbol`. For Morpho and Euler, this address IS unique per pool
        - `poolName` string, required — Pool name
        - `chain` string, required — Chain name
        - `chainId` integer, required — Chain ID
        - `underlyingToken` 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
        - `poolTvl` string, required — Total Value Locked for the pool
        - `poolLiquidity` string, required — Available liquidity for the pool
        - `collateralExposure` object, nullable — Collateral exposure for the pool. Keys are Morpho market identifiers, values are the collateral token symbols for each market. Null for non-Morpho pools (Aave, Euler).
        - `poolApy` PoolApyInfo, required
          - `native` string, required — Native APY percentage (formatted to 2 decimals)
          - `rewards` object, required — Map of reward tokens to their APYs (formatted to 2 decimals)
          - `total` string, required — Total APY percentage (formatted to 2 decimals)
          - `totalNet` string, required — Total net APY percentage (formatted to 2 decimals)
          - `performanceFee` string, required — Performance fee percentage (formatted to 2 decimals)
        - `signData` PoolSignData, required
          - `protocolId` integer, required — Protocol ID (0=Aave, 1=Morpho, 2=Euler)
          - `poolAddress` string, required — Pool contract address
          - `domainId` integer, required — Domain ID for the chain
        - `blacklisted` boolean, required — Indicates whether the pool has been blacklisted (banned) due to a third party critical security issue. Blacklisted pools are deprecated and retained solely for backwards compatibility. New deposits are never routed to blacklisted pools, and all existing balances are automatically rebalanced out of such pools when possible (balance is large enough to pay on-behalf fee and there is enough liquidity to withdraw).
      - `destinationPool` Pool, required — **Important: `poolAddress` is NOT globally unique across tokens.** For Aave V3, the same `poolAddress` (the Aave lending pool contract) is shared across all tokens on a given chain. For example, Aave V3 USDC, USDT, RLUSD, MUSD, USDG, USDE, and PYUSD on Ethereum all have the same `poolAddress`. A pool is uniquely identified by the combination of THREE fields together: - `poolAddress` - `chain` - `underlyingToken.symbol` When filtering pools by token (e.g. "show only USDC pools"), ALWAYS filter on `underlyingToken.symbol`. Never filter on `poolAddress` alone for Aave pools.
        - `protocolName` string, required — Protocol name
        - `protocolVersion` string, required — Protocol version
        - `protocolDescription` string, required — Protocol description
        - `protocolUrl` string, uri, required — Protocol website URL
        - `poolAddress` string, required — Pool contract address. The pool contract address. For Aave V3 pools, this is the Aave lending pool contract address, which is the SAME for all tokens (USDC, USDT, RLUSD, MUSD, USDG, USDE, PYUSD) on a given chain. Do NOT use this field alone as a unique pool identifier — it must always be combined with `chain` and `underlyingToken.symbol`. For Morpho and Euler, this address IS unique per pool
        - `poolName` string, required — Pool name
        - `chain` string, required — Chain name
        - `chainId` integer, required — Chain ID
        - `underlyingToken` 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
        - `poolTvl` string, required — Total Value Locked for the pool
        - `poolLiquidity` string, required — Available liquidity for the pool
        - `collateralExposure` object, nullable — Collateral exposure for the pool. Keys are Morpho market identifiers, values are the collateral token symbols for each market. Null for non-Morpho pools (Aave, Euler).
        - `poolApy` PoolApyInfo, required
          - `native` string, required — Native APY percentage (formatted to 2 decimals)
          - `rewards` object, required — Map of reward tokens to their APYs (formatted to 2 decimals)
          - `total` string, required — Total APY percentage (formatted to 2 decimals)
          - `totalNet` string, required — Total net APY percentage (formatted to 2 decimals)
          - `performanceFee` string, required — Performance fee percentage (formatted to 2 decimals)
        - `signData` PoolSignData, required
          - `protocolId` integer, required — Protocol ID (0=Aave, 1=Morpho, 2=Euler)
          - `poolAddress` string, required — Pool contract address
          - `domainId` integer, required — Domain ID for the chain
        - `blacklisted` boolean, required — Indicates whether the pool has been blacklisted (banned) due to a third party critical security issue. Blacklisted pools are deprecated and retained solely for backwards compatibility. New deposits are never routed to blacklisted pools, and all existing balances are automatically rebalanced out of such pools when possible (balance is large enough to pay on-behalf fee and there is enough liquidity to withdraw).
      - `balanceRaw` string, required — Balance in raw units
      - `balanceFormatted` string, required — Balance formatted
      - `estimatedCompletion` string, required — Estimated completion timestamp or duration
      - `estimatedCompletionTimestamp` integer, required — Estimated completion as Unix timestamp (seconds)
      - `isForSpending` boolean, required — Whether the balance is reserved for spending
  - `summary` Summary, required
    - `totalBalanceFormatted` string, required — Total balance across all tokens (formatted to 2 decimals)
    - `totalNetEarnings` string, required — Total net earnings in USD (formatted to 2 decimals)
    - `queriedTokens` string[], required — List of queried token symbols
    - `queriedChains` string[], required — List of queried chain names

## 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 or query failed
- `503` — Service temporarily unavailable

---

[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)
