> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metastreams.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet balances

> Read the latest balance of each wallet and asset, across one or more chains.

The latest balance of each wallet you name, one row per chain, wallet and asset. `wallets` takes 1 to 100 addresses, comma-separated. `chains` narrows the read to some chains. Leave it out to read every chain.

## Response

`balances` lists one row per wallet and asset that has moved, ordered by chain, wallet, then asset. A wallet and asset with no observed balance has no row. A missing row is not a zero.

`balance` is the amount after the transaction that last moved it, in the asset's own units. `trigger` names what moved it, such as `trade` or `deposit`. `trigger` and `asset` are open sets, so keep a value you do not recognize.

`blockNumber` and `txIndex` place the row in its chain. To merge this read with the [`wallet.balances`](/reference/streams/wallet-balances#update) stream, follow the rule on that page.

## Errors

| Code | When |
| - | - |
| `UNSUPPORTED_CHAIN` | A `chains` value is not a supported slug |
| `VALIDATION_ERROR` | No wallet or more than 100, a malformed address, or an unknown parameter |

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.metastreams.dev/v1/wallets/balances?wallets=7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5&chains=solana" \
    -H "Authorization: Bearer $API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const url = new URL("https://api.metastreams.dev/v1/wallets/balances");
  url.searchParams.set("wallets", "7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5");
  url.searchParams.set("chains", "solana");

  const response = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.API_KEY}` },
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const { balances } = await response.json();
  ```
</RequestExample>

<ResponseExample>
  ```json Balances theme={null}
  {
    "balances": [
      {
        "chain": "solana",
        "wallet": "7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5",
        "asset": "SOL",
        "balance": "41.208113",
        "trigger": "trade",
        "blockNumber": 371204118,
        "signature": "4xQmVb8e2kT1nR7pZcW3sLdHfA9jEuY6gVnX1oB5iC0wQ2rT8yU3iO7pA1sD4fG6h",
        "txIndex": 812,
        "updatedAt": 1789632015120
      }
    ]
  }
  ```

  ```json Never moved theme={null}
  {
    "balances": []
  }
  ```
</ResponseExample>


## OpenAPI

````yaml specs/openapi.json GET /v1/wallets/balances
openapi: 3.1.0
info:
  title: Metastreams API
  description: >-
    Click's B2B market-data API. Amounts are decimal strings, timestamps are
    Unix milliseconds, and every field name is camelCase.
  license:
    name: Proprietary
    identifier: Proprietary
  version: 1.0.0
servers:
  - url: https://{host}
    variables:
      host:
        default: api.metastreams.dev
        description: API host.
security:
  - bearerKey: []
paths:
  /v1/wallets/balances:
    get:
      tags:
        - wallets
      summary: The latest balance of each named wallet, per chain and asset.
      operationId: wallet_balances
      parameters:
        - name: wallets
          in: query
          description: Wallet addresses, CSV; one to 100.
          required: true
          schema:
            type: string
          example: 9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin
        - name: chains
          in: query
          description: >-
            Chains to scope to, CSV of the chain slugs. Absent means every spot
            chain.
          required: false
          schema:
            type: string
          example: solana,base
      responses:
        '200':
          description: >-
            The latest balance of each named wallet and asset. A pair with no
            observed balance has no row, which is not a zero.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UiWalletBalances'
        '400':
          description: >-
            Unsupported chain, a malformed wallet address, a wallet count
            outside 1-100, or a malformed parameter.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Missing or invalid API key.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '402':
          description: Credit balance cannot cover the request.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: The key is valid, but its plan excludes this endpoint.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limit exceeded.
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Unexpected server failure.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '503':
          description: Dependency down or maintenance.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: >-
                Requests left in the bucket this request spent from. Not sent
                with a 401.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  schemas:
    UiWalletBalances:
      type: object
      description: The latest balance of each wallet and asset a read named.
      required:
        - balances
      properties:
        balances:
          type: array
          items:
            $ref: '#/components/schemas/UiWalletBalance'
          description: >-
            One row per observed wallet and asset, ordered by chain, wallet,
            then asset.
    ErrorEnvelope:
      type: object
      description: The complete error response body — every error is exactly this.
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
          description: The error.
    UiWalletBalance:
      type: object
      description: >-
        One wallet's balance of one asset, as of the transaction that last moved
        it.
      required:
        - chain
        - wallet
        - asset
        - balance
        - trigger
        - blockNumber
        - signature
        - txIndex
        - updatedAt
      properties:
        asset:
          type: string
          description: >-
            The asset the balance is in. This is an open enumeration: keep a
            value you do not recognize.
          examples:
            - SOL
            - ETH
            - BNB
            - POL
            - USDC
            - TRX
            - USDT
            - USDG
            - PUSD
        balance:
          $ref: '#/components/schemas/Decimal'
          description: Post-transaction balance, human units.
        blockNumber:
          type: integer
          format: int64
          description: Block or Solana slot where the balance was observed.
          minimum: 0
        chain:
          $ref: '#/components/schemas/SpotChain'
          description: Chain the balance lives on.
        signature:
          type: string
          description: Transaction that moved it.
        trigger:
          type: string
          description: >-
            What moved the balance. This is an open enumeration: keep a value
            you do not recognize.
          examples:
            - trade
            - deposit
            - withdrawal
            - failed_tx
        txIndex:
          type: integer
          format: int64
          description: Transaction index within the observed block or slot.
          minimum: 0
        updatedAt:
          $ref: '#/components/schemas/UnixMilliseconds'
          description: Block time of the transaction that moved it.
        wallet:
          type: string
          description: Wallet holding it.
    ErrorDetail:
      type: object
      description: The `error` object inside the envelope.
      required:
        - code
        - message
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
          description: >-
            Stable, machine-readable. Clients switch on this, never on
            `message`.
        details:
          description: Optional; shape is fixed per code.
        message:
          type: string
          description: |-
            Human-readable, written for the integrating developer:
            `[What happened]. [What to do next — if actionable].`
    Decimal:
      type: string
      format: decimal
      description: An exact decimal, as a string.
      example: '123.456789'
    SpotChain:
      type: string
      description: >-
        Chain slug. One spelling per chain, in paths and bodies alike. Only a
        chain with spot data is published.
      enum:
        - solana
        - base
        - bsc
        - robinhood
        - arc
    UnixMilliseconds:
      type: integer
      format: int64
      description: An instant, as milliseconds since the Unix epoch.
    ErrorCode:
      type: string
      description: |-
        Every wire error code the API can return.

        Append-only: a new code is non-breaking, since clients fall back on the
        HTTP status for one they do not recognize, and a published code is never
        renamed or removed.
      enum:
        - UNAUTHORIZED
        - FORBIDDEN
        - VALIDATION_ERROR
        - UNSUPPORTED_CHAIN
        - NOT_FOUND
        - RATE_LIMITED
        - CREDITS_EXHAUSTED
        - INTERNAL_ERROR
        - SERVICE_UNAVAILABLE
        - RANGE_TOO_LARGE
        - INVALID_CREDENTIALS
        - ORIGIN_NOT_ALLOWED
        - NOT_ORG_MEMBER
        - MEMBERSHIP_INACTIVE
        - EMAIL_NOT_VERIFIED
        - EMAIL_TAKEN
        - ALREADY_MEMBER
        - INVITATION_ALREADY_SENT
        - INVITATION_ALREADY_ACCEPTED
        - LAST_ADMIN
        - CANNOT_REMOVE_SELF
        - KEY_LIMIT_REACHED
        - TOKEN_EXPIRED
        - PAYLOAD_TOO_LARGE
        - UNSUPPORTED_MEDIA_TYPE
        - IMAGE_TOO_LARGE
  securitySchemes:
    bearerKey:
      type: http
      scheme: bearer
      description: 'Send the API key as `Authorization: Bearer <key>`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.