Data API

GET /v1/wallets/{wallet}/holdings

A wallet's token holdings (portfolio) across all tracked tokens, priced. The self-hosted getTokenAccountsByOwner equivalent.

Endpoint

GET  https://solindex.infinityblocks.io/v1/wallets/{wallet}/holdings

Authentication

Send your key in the x-api-key header (or ?api-key=). See Authentication.

Path parameters

ParamDescription
walletBase-58 wallet address.

Query parameters

ParamTypeDefaultAllowed / range
limitint501–500 (page size)
offsetint0Rows to skip
pageint1-based page (alternative to offset)
minUsdfloat0Drop holdings worth less than this USD value (0 = all)
sortstringvaluevalue (valueUsd desc — portfolio view) or mint (stable mint order — for exports)
aftermintKeyset cursor: return holdings with mint > this value, in mint order. Implies sort=mint; ignores offset. Use page.nextCursor to continue.

Request

curl -s "https://solindex.infinityblocks.io/v1/wallets/<WALLET>/holdings?minUsd=1" \
  -H "x-api-key: <API_KEY>"
const r = await fetch("https://solindex.infinityblocks.io/v1/wallets/<WALLET>/holdings?minUsd=1", {
  headers: { "x-api-key": "<API_KEY>" },
});
const { data } = await r.json();

Response

{ "data": {
  "count": 5, "totalValueUsd": 101.13,
  "holdings": [
    { "mint": "EPjFW…Dt1v", "symbol": "USDC", "name": "USD Coin",
      "decimals": 6, "balance": 100.724535, "priceUsd": 1, "valueUsd": 100.72 },
    { "mint": "Df6y…pump", "symbol": "CHILLGUY", "name": "Just a chill guy",
      "decimals": 6, "balance": 39.638425, "priceUsd": 0.00962, "valueUsd": 0.38 },
    … ] },
  "page": { "limit": 50, "offset": 0, "total": 5, "returned": 5, "hasMore": false, "nextOffset": null } }
The self-hosted equivalent of getTokenAccountsByOwner for our scope — a wallet's holdings across every tracked token (DegenSafe launches + Raydium-traded tokens), each priced from the latest trade with a computed valueUsd; sorted by value, with a portfolio totalValueUsd. Use ?minUsd= to hide dust.

Freshness & consistency. Balances come from the live geyser token-account change stream and are written in ~1-second batches; prices are maintained per-mint from the latest trade, also within ~1 second. A holding’s priceUsd/valueUsd can therefore trail an actively-trading token by up to a second between repeated calls; balances and the mint set are stable. The endpoint is served from wallet-keyed structures, so response cost is bounded by the wallet’s own holdings — page limit bounds output work, and high-cardinality wallets (thousands of mints) are fully supported.

Completeness semantics. Zero-balance accounts are omitted (only balances > 0 are returned). Ordering is deterministic — valueUsd desc, then balance desc, then mint asc. For complete exports, use cursor pagination: pass ?sort=mint and follow page.nextCursor with ?after=<mint> until it is null — the mint key is immutable, so the sweep is duplicate-free and complete (exactly data.count holdings) even while prices move. Plain offset pagination over the default value ordering is a live view: a price tick between page fetches can re-rank rows across a page boundary (a holding may repeat or be missed) — fine for showing top-of-portfolio pages, wrong for exhaustive enumeration. Scope note: tracked tokens only — a wallet's holdings of tokens we don't index (arbitrary all-SPL) are not included. During a (rare, alerted) indexer outage, balances reflect stream state as of the outage start and catch up automatically on recovery.

Try it

Run GET /v1/wallets/{wallet}/holdingslive · GET

Your key is stored only in this browser (localStorage).