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

# Supply Held by Wallets

> Show how much of a token supply tracked KOL, Smart Money and Whale wallets hold, per wallet and combined, from one REST call. Step by step in TypeScript.

Learn how to show one of the most telling numbers about a token, how much of its supply sits in tracked smart hands. You will read the percent each wallet holds, add them up for a combined total, and split that total by wallet type. It is one REST call and a little math, in TypeScript, with no CSS.

## What you will build

A supply concentration view with three parts, a headline total (the combined percent of supply held by tracked wallets), a breakdown by wallet type (KOL, Smart Money, Whale), and a per wallet list sorted by how much each holds.

## The endpoint

One call returns every tracked holder of a token, each with the percent of supply they hold.

<Card title="GET /v1/tokens/holders" href="/api-reference/tokens-holders">
  Every tracked holder of a token, each with a holdings.supply\_pct field, plus a total\_holders count by type.
</Card>

## Step 1, type the response

You only need a few fields, the per holder supply\_pct inside holdings, the wallet type, and the total\_holders counts.

```typescript src/types.ts theme={null}
export interface Holder {
  wallet: string;
  wallet_type: 'kol' | 'smart' | 'whale';
  profile: { name: string };
  holdings: {
    supply_pct: number;       // current percent of supply held
    supply_pct_peak: number;  // highest they ever held
  };
}

export interface HoldersResponse {
  total_holders: {
    kol_count: number;
    smart_count: number;
    whale_count: number;
    still_holding_count: number;
  };
  holders: Holder[];
}
```

## Step 2, fetch the holders

Give it a chain and a mint. Optionally pass a type to restrict to one wallet class, or leave it off to get all of them. A higher limit returns more holders.

```typescript src/holders.ts theme={null}
const API_BASE = 'https://api.cabalspy.xyz/v1';

export async function fetchHolders(mint: string, limit = 100): Promise<import('./types').HoldersResponse> {
  const params = new URLSearchParams({
    blockchain: 'solana',
    mint,
    limit: String(limit),
    api_key: import.meta.env.VITE_CABALSPY_KEY as string,
  });
  const res = await fetch(`${API_BASE}/tokens/holders?${params}`);
  const body = await res.json();
  if (!body.success) throw new Error(body.error?.message || 'holders failed');
  return body.data;
}
```

## Step 3, do the math

This is the whole idea. Sum supply\_pct for the combined total, and sum it per wallet type for the breakdown. One pass over the holders gives you both.

```typescript src/supply.ts theme={null}
import type { Holder } from './types';

export interface SupplyBreakdown {
  total: number;
  byType: { kol: number; smart: number; whale: number };
  perWallet: { name: string; type: string; supplyPct: number }[];
}

export function computeSupply(holders: Holder[]): SupplyBreakdown {
  const byType = { kol: 0, smart: 0, whale: 0 };
  let total = 0;

  for (const h of holders) {
    const pct = h.holdings.supply_pct || 0;
    total += pct;
    byType[h.wallet_type] += pct;
  }

  const perWallet = holders
    .map((h) => ({ name: h.profile.name, type: h.wallet_type, supplyPct: h.holdings.supply_pct || 0 }))
    .sort((a, b) => b.supplyPct - a.supplyPct);

  return { total, byType, perWallet };
}
```

## Step 4, render it

The headline is the combined total. The breakdown shows how it splits across wallet types. The list shows who holds what. No CSS here, style it later.

```typescript src/render.ts theme={null}
import type { SupplyBreakdown } from './supply';

const pct = (v: number) => v.toFixed(2) + '%';

export function renderSupply(el: HTMLElement, b: SupplyBreakdown): void {
  el.innerHTML = `
    <h2>${pct(b.total)} of supply held by tracked wallets</h2>

    <ul>
      <li>KOL ${pct(b.byType.kol)}</li>
      <li>Smart Money ${pct(b.byType.smart)}</li>
      <li>Whale ${pct(b.byType.whale)}</li>
    </ul>

    <table>
      <thead><tr><th>Wallet</th><th>Type</th><th>Supply held</th></tr></thead>
      <tbody>
        ${b.perWallet.map((w) => `<tr><td>${w.name}</td><td>${w.type}</td><td>${pct(w.supplyPct)}</td></tr>`).join('')}
      </tbody>
    </table>`;
}
```

## Step 5, wire it together

```typescript src/main.ts theme={null}
import { fetchHolders } from './holders';
import { computeSupply } from './supply';
import { renderSupply } from './render';

const MINT = '3Pkrq4MmLvDXyn1fa3sz5MekKRkZkc1iLDcz5AzWpump';

async function main() {
  const { holders } = await fetchHolders(MINT);
  const breakdown = computeSupply(holders);
  renderSupply(document.querySelector('#supply')!, breakdown);
}

main();
```

That is the whole feature. One call, one pass of math, three views.

## Making it live

The holders endpoint is a snapshot. If you want the supply numbers to move in real time, the holder stream carries the same supply\_pct per holder on every update. Subscribe to it, recompute the breakdown when a holder changes, and re render. The math in step 3 does not change, only where the holders come from. See the holder table cookbook for the streaming setup.

## Lessons worth knowing

Two things worth keeping in mind.

supply\_pct is current, supply\_pct\_peak is the high. Show the current percent for how much a wallet holds now. The peak is useful to flag a wallet that has trimmed, if peak is much higher than current, they have been selling.

The total is a sum, not a unique count. Adding supply\_pct across holders gives the share of supply in tracked hands. It is a concentration signal, the higher it is, the more of the token sits with wallets you follow.

## Reference

<Card title="GET /v1/tokens/holders" href="/api-reference/tokens-holders">
  Every tracked holder with supply\_pct, plus total\_holders by wallet type.
</Card>
