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

# Get wallet balance

> Returns the on-chain balances of a single customer wallet — every token the wallet service tracks on every supported network, with raw and human-readable amounts plus USD valuation.

Read-only and **safe to retry**. There is no request body and no query parameters.

### Behaviour worth knowing

**Chain selection is automatic.** EVM wallets are queried with the aggregated `all` scope, which returns per-network assets in a single call. TRON wallets are queried on their own network (`Tron` / `TronNile`), because the aggregate does not cover TRON. You cannot override this.

**Zero balances are included.** `tokens` is the full supported matrix for the wallet, not just funded holdings. Filter client-side if you only want non-empty assets.

**It is a live read.** `source: "rpc"` means each call hits chain nodes, which is why it takes roughly a second. Cache on your side rather than polling in a tight loop.

**Ownership is enforced on both ids.** A wallet that exists but belongs to another customer is reported as **not found**, never as forbidden — so a partner can never probe for another customer's wallets.

<Note>
Sandbox USD figures are derived from testnet balances and are **not real value**.
</Note>

## Response headers

| Header                  | Description                                                                                    |
| ----------------------- | ---------------------------------------------------------------------------------------------- |
| `api-version`           | The API version that served the request, echoed from your header.                              |
| `x-request-id`          | Correlation id. **Quote it in every support ticket** — it is the key to the server-side trace. |
| `content-type`          | `application/json`.                                                                            |
| `X-RateLimit-Limit`     | Requests allowed per minute for this key. Sent on `429`.                                       |
| `X-RateLimit-Remaining` | Requests left in the current window. Sent on `429`.                                            |

## Operational notes

|                      |                                                                                                                                                                                 |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Rate limiting**    | Per API key, in fixed one-minute windows, defaulting to **60 requests/minute**. A partner or an individual key can be configured higher; changes take effect without a restart. |
| **IP allow-listing** | Optional per key. A key with no list configured accepts any source address. The `403` body echoes the observed IP so you can self-diagnose a mismatch.                          |
| **No API secret**    | `X-API-SECRET` is accepted for backwards compatibility but ignored. Send `Api-Key` only.                                                                                        |
| **Auditing**         | Every call is recorded against the partner as `PARTNER_WALLET_BALANCE_GET`, including calls that fail after authentication.                                                     |

## Reading the numbers

<Warning>
  **Compute from `balance`, never from `formatted`.** `balance` is the raw on-chain
  amount in the smallest unit, sent as a string precisely so it does not lose
  precision. `formatted` is for display only.

  `"balance": "100000000"` with `"decimals": 6` is **100 USDC**.
</Warning>

A missing `contractAddress` means the asset is the network's **native gas token** —
`ETH`, `POL` — rather than an ERC-20. Those are the assets that usually appear in
`unpricedAssets` with `usd: null`, and they contribute nothing to `totalUsd`.


## OpenAPI

````yaml api-reference/endl-partner-api.json GET /api/v0/wallets/{userId}/{walletId}/balance
openapi: 3.1.0
info:
  title: Endl Partner API
  version: '0'
  description: >-
    REST API for Endl partners: wallets, quotes, recipients, accounts and
    transactions.


    All endpoints are authenticated with an `API-KEY` header, are scoped to the
    partner that owns the credential, and return the standard response envelope.
servers:
  - url: https://api-sandbox.endl.io
    description: Sandbox
security:
  - apiKey: []
tags:
  - name: Wallets
    description: Create and manage user wallets.
  - name: Quotes
    description: Price a transfer before submitting it.
  - name: Recipients
    description: Manage the parties a user pays out to.
  - name: Accounts
    description: Open and inspect user accounts.
  - name: Transactions
    description: Fund, submit, and track transfers.
  - name: Reference
    description: 'Static catalogues: currencies, countries, rates, rails, codes.'
paths:
  /api/v0/wallets/{userId}/{walletId}/balance:
    get:
      tags:
        - Wallets
      summary: Get wallet balance
      description: >-
        Returns the on-chain balances of a single customer wallet — every token
        the wallet service tracks on every supported network, with raw and
        human-readable amounts plus USD valuation.


        Read-only and **safe to retry**. There is no request body and no query
        parameters.


        ### Behaviour worth knowing


        **Chain selection is automatic.** EVM wallets are queried with the
        aggregated `all` scope, which returns per-network assets in a single
        call. TRON wallets are queried on their own network (`Tron` /
        `TronNile`), because the aggregate does not cover TRON. You cannot
        override this.


        **Zero balances are included.** `tokens` is the full supported matrix
        for the wallet, not just funded holdings. Filter client-side if you only
        want non-empty assets.


        **It is a live read.** `source: "rpc"` means each call hits chain nodes,
        which is why it takes roughly a second. Cache on your side rather than
        polling in a tight loop.


        **Ownership is enforced on both ids.** A wallet that exists but belongs
        to another customer is reported as **not found**, never as forbidden —
        so a partner can never probe for another customer's wallets.


        <Note>

        Sandbox USD figures are derived from testnet balances and are **not real
        value**.

        </Note>
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: userId
          in: path
          required: true
          schema:
            type: string
          description: >-
            Customer **reference id**, format `cus_<20 chars>` — never an
            internal UUID. Must belong to the authenticated partner.
          example: cus_dgG98G4HjyZaQvPWQmqp
        - name: walletId
          in: path
          required: true
          schema:
            type: string
          description: >-
            Wallet **reference id**, format `wlt_<20 chars>`. Must belong to the
            customer named in the path.
          example: wlt_eoGwAJpq8IWq1ZAbAUqz
      responses:
        '200':
          description: >-
            The balance object. **Unwrapped** — the partner surface returns bare
            payloads, with no `data`/`status` envelope.
          content:
            application/json:
              schema:
                type: object
                properties:
                  walletId:
                    type: string
                    description: The wallet reference id that was requested.
                  address:
                    type: string
                    description: >-
                      The wallet's on-chain address. **The same address is used
                      across all EVM networks.**
                  chain:
                    type: string
                    description: >-
                      Scope of the query — `all` for the aggregated
                      multi-network balance, or a single network name for TRON
                      wallets.
                  tokens:
                    type: array
                    description: >-
                      One entry per tracked asset per network, **including
                      assets with a zero balance**.
                    items:
                      type: object
                      properties:
                        chain:
                          type: string
                          description: >-
                            Network the balance was read on — `Ethereum`,
                            `Base`, `ArbitrumOne`, `Optimism`, `Polygon`,
                            `BaseSepolia`.
                        symbol:
                          type: string
                          description: Asset ticker — `USDC`, `USDT`, `ETH`, `POL`.
                        contractAddress:
                          type: string
                          description: >-
                            ERC-20 contract address. **Absent for native gas
                            tokens** (`ETH`, `POL`) — treat a missing field as
                            *native asset*.
                        decimals:
                          type: integer
                          description: >-
                            Decimal precision — `6` for USDC/USDT, `18` for
                            native EVM assets.
                        balance:
                          type: string
                          description: >-
                            Raw on-chain amount in the token's smallest unit,
                            **as a string to preserve precision**. `"100000000"`
                            with `decimals: 6` is 100 USDC.
                        formatted:
                          type: string
                          description: >-
                            The same amount scaled by `decimals`, for display.
                            **Do not use for arithmetic** — compute from
                            `balance`.
                        usd:
                          type: number
                          nullable: true
                          description: >-
                            USD value of this holding. `null` when no price was
                            available.
                  totalUsd:
                    type: number
                    description: >-
                      Sum of the USD value of all **priced** assets. Anything in
                      `unpricedAssets` contributes nothing.
                  unpricedAssets:
                    type: array
                    items:
                      type: string
                    description: >-
                      `Chain:SYMBOL` identifiers for assets with no USD price at
                      read time, typically native gas tokens. Their `usd` is
                      `null`.
                  source:
                    type: string
                    description: >-
                      Where the figures came from. `rpc` means read live from
                      the chain node at request time.
              example:
                walletId: wlt_eoGwAJpq8IWq1ZAbAUqz
                address: '0x297774861c4985bc3100230fbee9e6865353d467'
                chain: all
                tokens:
                  - chain: Ethereum
                    symbol: ETH
                    decimals: 18
                    balance: '0'
                    formatted: '0.0'
                    usd: null
                  - chain: Ethereum
                    symbol: USDC
                    contractAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
                    decimals: 6
                    balance: '0'
                    formatted: '0.0'
                    usd: 0
                  - chain: BaseSepolia
                    symbol: USDC
                    contractAddress: '0xfdaf25a361132d8fd8D6212D0C68D802a16f3B10'
                    decimals: 6
                    balance: '100000000'
                    formatted: '100.0'
                    usd: 100
                  - chain: BaseSepolia
                    symbol: USDT
                    contractAddress: '0x6e189E7a850f38e1d649715B3EdBa0d132858f11'
                    decimals: 6
                    balance: '100000000'
                    formatted: '100.0'
                    usd: 100
                totalUsd: 200
                unpricedAssets:
                  - Ethereum:ETH
                  - Base:ETH
                  - ArbitrumOne:ETH
                  - Optimism:ETH
                  - Polygon:POL
                  - BaseSepolia:ETH
                source: rpc
        '400':
          description: >-
            `bad_request` — the `Api-Version` header is missing, malformed or
            unsupported. `ERRREF_1000` — a path id is blank, malformed, or a
            reference of the wrong type.
          content:
            application/json:
              example:
                code: ERRREF_1000
                message: '''wallet-123'' is not a valid wallet id'
                name: >-
                  The supplied reference id is blank, malformed, or of the wrong
                  type
        '401':
          description: >-
            The key is unknown, inactive, deleted, or its partner is
            deactivated. **A request with no `Api-Key` header at all** is
            rejected by the security layer before partner error formatting
            applies, and keeps the legacy envelope instead.
          content:
            application/json:
              example:
                code: unauthorized
                message: Invalid API key
        '403':
          description: >-
            The source IP is outside the allow-list configured for the key, or
            the key lacks the `wallets` permission, or the customer belongs to a
            different partner.
          content:
            application/json:
              example:
                code: forbidden
                message: >-
                  Source IP not allowed for this API key (observed:
                  203.0.113.42)
        '404':
          description: >-
            `ERRWLT_1000` — the wallet does not exist, belongs to another
            customer, or has no provider wallet id. `ERRREF_1001` — a
            well-formed reference that resolves to nothing. `404` — the customer
            reference is unknown or deleted.
          content:
            application/json:
              example:
                code: ERRWLT_1000
                message: Wallet 'wlt_eoGwAJpq8IWq1ZAbAUqz' not found
                name: The wallet does not exist or does not belong to this user
        '429':
          description: >-
            Per-API-key rate limit exceeded for the current minute. Carries
            `X-RateLimit-Limit` and `X-RateLimit-Remaining`.
          content:
            application/json:
              example:
                code: too_many_requests
                message: Rate limit exceeded, please retry later
        '500':
          description: >-
            The wallet service was unreachable or an unhandled failure occurred.
            **Safe to retry** — quote `x-request-id` to support.
          content:
            application/json:
              example:
                errors:
                  - code: unexpected
                    message: An unexpected error occurred, you may try again later
components:
  parameters:
    ApiVersion:
      name: Api-Version
      in: header
      required: true
      description: >-
        The API version this request targets. Required on every `/api/v0/*`
        call. Format `YYYY-MM.<release>`; `2026-09.1` is the latest. The version
        that served the request is echoed back on the response. Missing,
        malformed or unsupported values are rejected with `400`.
      schema:
        type: string
        pattern: ^\d{4}-\d{2}\.\d+$
        default: 2026-09.1
      example: 2026-09.1
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: API-KEY
      description: Your partner API key.

````