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

# How to Get Wallet Balances

> Retrieve all token and NFT balances for any Solana wallet with USD values, logos, and metadata. Sorted by value for easy portfolio tracking.

> [!NOTE]
>
> The Wallet API is in Beta. Endpoints and response formats may change.

## Overview

The Wallet Balances endpoint retrieves all token and NFT holdings for a Solana wallet — SOL, SPL tokens, Token-2022, and NFTs — with USD pricing, logos, and metadata. Results are sorted by USD value in descending order: tokens with pricing data appear first, followed by tokens without prices.

The endpoint returns up to 100 tokens per request, so pagination is manual. Use the `page` parameter to fetch additional pages and read `pagination.hasMore` to know when more results are available. Each request is a single API call and costs 100 credits.

> [!NOTE]
>
> USD prices are sourced from DAS and update hourly, covering the top 10,000 tokens by market cap. `pricePerToken` and `usdValue` are `null` for unsupported tokens. Prices are estimates, not real-time market rates.

## When to use this

Use the Wallet Balances API when you need to:

* **Display portfolio holdings**: show users their complete token and NFT holdings.
* **Calculate USD values**: get portfolio valuations with hourly-updated pricing.
* **Build wallet UIs**: power wallet dashboards and asset lists.
* **Track token holdings**: monitor specific token balances across wallets.
* **Portfolio analytics**: analyze holdings distribution and concentration.
* **Tax reporting**: generate holdings snapshots for tax purposes.

## Quickstart

### Basic balance query

Get all token balances for a wallet with USD values:

> [tab] JavaScript
>
> ```javascript theme={"system"}
> const getWalletBalances = async (address) => {
>   const url = `https://api.helius.xyz/v1/wallet/${address}/balances?api-key=YOUR_API_KEY`;
>
>   const response = await fetch(url);
>   if (!response.ok) {
>     throw new Error(`HTTP error! status: ${response.status}`);
>   }
>
>   const data = await response.json();
>
>   const solBalance = data.balances[0]; // SOL is always first when showNative=true
>   console.log(`SOL Balance: ${solBalance.balance} SOL ($${solBalance.usdValue})`);
>   console.log(`Page ${data.pagination.page} Total Value: $${data.totalUsdValue}`);
>   console.log(`Token Count (this page): ${data.balances.length}`);
>
>   // Display top holdings
>   data.balances.slice(0, 5).forEach(token => {
>     console.log(`${token.symbol}: ${token.balance} ($${token.usdValue || 'N/A'})`);
>   });
>
>   return data;
> };
>
> getWalletBalances("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
> ```

> [tab] Python
>
> ```python theme={"system"}
> import requests
>
> def get_wallet_balances(address: str):
>     url = f"https://api.helius.xyz/v1/wallet/{address}/balances"
>     headers = {"X-Api-Key": "YOUR_API_KEY"}
>
>     response = requests.get(url, headers=headers)
>     response.raise_for_status()
>
>     data = response.json()
>
>     sol_balance = data['balances'][0]  # SOL is always first when showNative=true
>     print(f"SOL Balance: {sol_balance['balance']} SOL (${sol_balance['usdValue']})")
>     print(f"Page {data['pagination']['page']} Total Value: ${data['totalUsdValue']}")
>     print(f"Token Count (this page): {len(data['balances'])}")
>
>     # Display top holdings
>     for token in data['balances'][:5]:
>         usd_value = token.get('usdValue', 'N/A')
>         print(f"{token['symbol']}: {token['balance']} (${usd_value})")
>
>     return data
>
> get_wallet_balances("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY")
> ```

> [tab] cURL
>
> ```bash theme={"system"}
> curl "https://api.helius.xyz/v1/wallet/86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY/balances?api-key=YOUR_API_KEY"
> ```

### Include NFTs in results

Get both tokens and NFTs in a single request with `showNfts=true`:

> [tab] JavaScript
>
> ```javascript theme={"system"}
> const getWalletWithNfts = async (address) => {
>   const url = `https://api.helius.xyz/v1/wallet/${address}/balances?api-key=YOUR_API_KEY&showNfts=true`;
>
>   const response = await fetch(url);
>   const data = await response.json();
>
>   console.log(`Tokens: ${data.balances.length}`);
>   console.log(`NFTs: ${data.nfts?.length || 0}`);
>
>   // Display NFTs
>   data.nfts?.forEach(nft => {
>     console.log(`NFT: ${nft.name || 'Unnamed'} (${nft.collectionName || 'Unknown Collection'})`);
>   });
>
>   return data;
> };
>
> getWalletWithNfts("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
> ```

> [tab] Python
>
> ```python theme={"system"}
> def get_wallet_with_nfts(address: str):
>     url = f"https://api.helius.xyz/v1/wallet/{address}/balances"
>     params = {
>         "api-key": "YOUR_API_KEY",
>         "showNfts": "true"
>     }
>
>     response = requests.get(url, params=params)
>     response.raise_for_status()
>
>     data = response.json()
>
>     print(f"Tokens: {len(data['balances'])}")
>     print(f"NFTs: {len(data.get('nfts', []))}")
>
>     # Display NFTs
>     for nft in data.get('nfts', []):
>         name = nft.get('name', 'Unnamed')
>         collection = nft.get('collectionName', 'Unknown Collection')
>         print(f"NFT: {name} ({collection})")
>
>     return data
>
> get_wallet_with_nfts("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY")
> ```

### Filter the results

Use query parameters to narrow what is returned:

```javascript theme={"system"}
// Only show tokens with non-zero balances
const url = `https://api.helius.xyz/v1/wallet/${address}/balances?api-key=YOUR_API_KEY&showZeroBalance=false`;

// Exclude native SOL from results
const url = `https://api.helius.xyz/v1/wallet/${address}/balances?api-key=YOUR_API_KEY&showNative=false`;

// Get only the top 50 tokens by value
const url = `https://api.helius.xyz/v1/wallet/${address}/balances?api-key=YOUR_API_KEY&limit=50`;
```

## Query parameters

| Parameter | Type | Default | Description |
| - | - | - | - |
| `page` | integer | 1 | Page number for pagination (1-indexed) |
| `limit` | integer | 100 | Maximum number of tokens per page (1-100) |
| `showZeroBalance` | boolean | false | Include tokens with zero balance |
| `showNative` | boolean | true | Include native SOL in results |
| `showNfts` | boolean | false | Include NFTs in results (max 100, first page only) |

## Response format

```json theme={"system"}
{
  "balances": [
    {
      "mint": "So11111111111111111111111111111111111111111",
      "symbol": "SOL",
      "name": "Solana",
      "balance": 1.5,
      "decimals": 9,
      "pricePerToken": 145.32,
      "usdValue": 217.98,
      "logoUri": "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png",
      "tokenProgram": "spl-token"
    },
    {
      "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "symbol": "USDC",
      "name": "USD Coin",
      "balance": 1000.5,
      "decimals": 6,
      "pricePerToken": 1.0,
      "usdValue": 1000.5,
      "logoUri": "https://example.com/usdc-logo.png",
      "tokenProgram": "spl-token"
    }
  ],
  "nfts": [
    {
      "mint": "7Xq8wXyXVqfBPPqVJjPDwG9zN5wCVxBYZ6z7vPYBzr6F",
      "name": "Degen Ape #1234",
      "imageUri": "https://example.com/nft.png",
      "collectionName": "Degen Ape Academy",
      "collectionAddress": "DegN1dXmU2uYa4n7U9qTh7YNYpK4u8L9qXx7XqYqJfGH",
      "compressed": false
    }
  ],
  "totalUsdValue": 1218.48,
  "pagination": {
    "page": 1,
    "limit": 100,
    "hasMore": true
  }
}
```

### Field notes

* **`balance`**: human-readable amount, already adjusted for decimals — `1.5` means 1.5 SOL and `1000.5` means 1000.5 USDC. No lamport conversion is needed. This endpoint does not expose a raw `amountRaw` field; if you need the exact integer value, derive it as `Math.round(balance * 10 ** decimals)`.
* **`decimals`**: provided for reference only.
* **`pricePerToken` / `usdValue`**: `null` for tokens without DAS pricing data (see the pricing note above).
* **`totalUsdValue`**: total USD value for the current response page only. For full-portfolio value, paginate through all pages and sum each balance's `usdValue`.
* **`tokenProgram`**: which token standard each token uses — `spl-token` (legacy SPL Token) or `token-2022` (Token Extensions). Both are fully supported.

## Use cases

### Build a portfolio dashboard

Display user holdings with USD values:

```javascript theme={"system"}
const renderPortfolio = async (address) => {
  const { balances, totalUsdValue } = await getWalletBalances(address);

  console.log(`Current Page Value: $${totalUsdValue.toLocaleString()}`);
  console.log(`\nTop Holdings:`);

  // totalUsdValue is page-scoped; paginate before computing full portfolio value.
  balances.slice(0, 10).forEach((token, i) => {
    if (token.usdValue) {
      console.log(`${i + 1}. ${token.symbol}: ${token.balance.toFixed(4)} ($${token.usdValue.toFixed(2)})`);
    }
  });
};
```

### Calculate token concentration

Analyze portfolio diversification:

```javascript theme={"system"}
const analyzeConcentration = async (address) => {
  const { balances, totalUsdValue } = await getWalletBalances(address);

  const tokensWithValue = balances.filter(t => t.usdValue);

  if (tokensWithValue.length === 0) {
    console.log('No tokens with USD pricing data available');
    return null;
  }

  const topToken = tokensWithValue[0];
  const pageConcentration = (topToken.usdValue / totalUsdValue) * 100;

  console.log(`Largest Position on Current Page: ${topToken.symbol} (${pageConcentration.toFixed(1)}%)`);

  if (pageConcentration > 50) {
    console.log(`Warning: Current page is highly concentrated in ${topToken.symbol}`);
  }

  return { topToken, pageConcentration };
};
```

### Track a specific token balance

Monitor a specific token across multiple wallets:

```javascript theme={"system"}
const getTokenBalance = async (address, tokenMint) => {
  const { balances } = await getWalletBalances(address);

  const token = balances.find(t => t.mint === tokenMint);

  if (!token) {
    console.log(`Token not found in wallet`);
    return null;
  }

  console.log(`${token.symbol} Balance: ${token.balance}`);
  console.log(`USD Value: $${token.usdValue || 'N/A'}`);

  return token;
};

// Example: Check USDC balance
getTokenBalance(
  "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
  "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" // USDC mint
);
```

### Export holdings for tax reporting

Generate a holdings snapshot:

```javascript theme={"system"}
const exportHoldingsSnapshot = async (address) => {
  const { balances, totalUsdValue } = await getWalletBalances(address);

  const snapshot = {
    date: new Date().toISOString(),
    address,
    pageValueUSD: totalUsdValue,
    holdings: balances
      .filter(t => t.usdValue)
      .map(t => ({
        symbol: t.symbol,
        mint: t.mint,
        balance: t.balance,
        pricePerToken: t.pricePerToken,
        usdValue: t.usdValue
      }))
  };

  console.log(JSON.stringify(snapshot, null, 2));
  return snapshot;
};
```

## Pagination

For wallets with more than 100 tokens, page through results with the `page` parameter and `pagination.hasMore`:

```javascript theme={"system"}
const getAllBalances = async (address) => {
  let allBalances = [];
  let page = 1;
  let hasMore = true;

  while (hasMore) {
    const url = `https://api.helius.xyz/v1/wallet/${address}/balances?api-key=YOUR_API_KEY&page=${page}&limit=100`;

    const response = await fetch(url);
    const data = await response.json();

    allBalances = allBalances.concat(data.balances);
    hasMore = data.pagination.hasMore;
    page++;

    console.log(`Fetched page ${data.pagination.page}, total tokens so far: ${allBalances.length}`);
  }

  console.log(`Total tokens: ${allBalances.length}`);
  return allBalances;
};
```

NFTs are returned on the first page only (up to 100), regardless of token pagination.

## Best practices

* **Filter zero balances for a cleaner UI.** Use `showZeroBalance=false` to hide tokens the wallet no longer holds.
* **Include NFTs only when needed.** NFTs are excluded by default for performance; set `showNfts=true` only when displaying them.
* **Handle missing price data.** Always check whether `pricePerToken` and `usdValue` are `null` before displaying. These are hourly estimates from DAS, not real-time market rates.
* **Cache responses.** Balance data can be cached for several seconds to reduce API calls.
* **Paginate large wallets.** Some wallets hold thousands of tokens; implement pagination to handle them efficiently.

## Common errors

| Error Code | Description | Solution |
| - | - | - |
| 400 | Invalid wallet address format | Verify the address is a valid base58 Solana address |
| 401 | Missing or invalid API key | Check your API key is included in the request |
| 429 | Rate limit exceeded | Reduce request frequency or upgrade your plan |

## Next steps

> [card] [Historical Balance](https://www.helius.dev/docs/wallet-api/balance-at.md)
>
> Get a token or SOL balance at a past timestamp, datetime, or slot.

> [card] [Wallet API Overview](https://www.helius.dev/docs/wallet-api/overview.md)
>
> All Wallet API endpoints and shared conventions.

> [card] [API Reference](https://www.helius.dev/docs/api-reference/wallet-api/balances.md)
>
> Request and response schemas for wallet balances.


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