Top Traders & PnL

Solana API for top token traders by realized and unrealized PnL, volume, trade counts, and wallet labels across 1d, 7d, and 30d windows.

Find the top traders for any Solana token by realized and unrealized PnL (profit and loss), trading volume, and trade count.

Use this endpoint to rank wallets trading a specific Token-2022 or SPL token. Each result includes the trader address, optional wallet labels, realized PnL, unrealized PnL, buy and sell volume, and trade counts across a selected time window.

This data is ideal for token-level leaderboards, smart money discovery, whale analysis, and identifying which wallets are consistently profiting from a specific token.

Why Top Trader PnL Matters

Top trader analysis helps you answer questions like:

  • Who is making money on this token? Rank wallets by realized PnL over 1d, 7d, or 30d.
  • Which wallets are still exposed? Compare realized PnL with unrealized PnL.
  • Who is actively trading? Sort by tradesCount or totalVolumeUsd to find high-activity wallets.
  • Are labeled entities involved? Use name, labels, and logoUrl when available to identify known traders or entities.

Vybe's token-level PnL data goes beyond raw trades. It aggregates wallet performance for a token so you can surface profitable traders without calculating every buy, sell, and open position yourself.


Endpoint

GET /v4/tokens/{mintAddress}/top-pnl-traders

Parameters

ParameterTypeDefaultDescription
mintAddressstringToken mint public key. Required path parameter.
resolutionstring1dPnL time window. Use 1d, 7d, or 30d.
limitnumber1000Maximum number of traders to return. Must not exceed 1000.
pagenumber0Page number for pagination.
sortByAscstringSort ascending by a supported field. Do not use with sortByDesc.
sortByDescstringSort descending by a supported field. Do not use with sortByAsc.

Resolution Options

OptionDescription
1dLast day
7dLast 7 days
30dLast 30 days

Sort Options

OptionDescription
traderAddressBy trader wallet address
realizedPnlUsdBy realized PnL in USD
totalVolumeUsdBy total trading volume in USD
tradesCountBy total number of trades

Example Request

curl "https://api.vybenetwork.xyz/v4/tokens/So11111111111111111111111111111111111111112/top-pnl-traders?resolution=7d&limit=100&page=0&sortByDesc=realizedPnlUsd" \
  -H "X-API-Key: YOUR_API_KEY"

Example Response

{
  "data": [
    {
      "traderAddress": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
      "name": "Example Trader",
      "labels": ["KOL"],
      "logoUrl": "https://example.com/logo.png",
      "realizedPnlUsd": 12345.67,
      "unrealizedPnlUsd": 890.12,
      "buyVolumeUsd": 125000.45,
      "sellVolumeUsd": 150000.89,
      "totalVolumeUsd": 275001.34,
      "buyCount": 18,
      "sellCount": 24,
      "tradesCount": 42
    },
    {
      "traderAddress": "7Tar8QZTrRPwoGY5Ke9Vfwf6CmpBfekrNofERxgReza",
      "name": null,
      "labels": [],
      "logoUrl": null,
      "realizedPnlUsd": 9876.54,
      "unrealizedPnlUsd": -321.09,
      "buyVolumeUsd": 80000.12,
      "sellVolumeUsd": 92500.34,
      "totalVolumeUsd": 172500.46,
      "buyCount": 12,
      "sellCount": 15,
      "tradesCount": 27
    }
  ]
}

Response Fields Explained

FieldDescription
dataArray of ranked traders for the requested token.
traderAddressTrader wallet public key.
nameTrader or entity name, if available.
labelsLabels associated with the trader, if available.
logoUrlTrader or entity logo URL, if available.
realizedPnlUsdRealized profit and loss in USD for closed trading activity.
unrealizedPnlUsdUnrealized profit and loss in USD for open token exposure.
buyVolumeUsdTotal buy volume in USD for the token.
sellVolumeUsdTotal sell volume in USD for the token.
totalVolumeUsdTotal buy and sell volume in USD for the token.
buyCountTotal number of buy trades for the token.
sellCountTotal number of sell trades for the token.
tradesCountTotal number of buy and sell trades for the token.

Common Use Cases

Use CaseImplementation
Trader LeaderboardRank wallets by realizedPnlUsd for a specific token.
Smart Money DiscoveryFind profitable wallets with high totalVolumeUsd.
Whale Trading AnalysisTrack high-volume traders over 1d, 7d, or 30d.
Position Risk AnalysisCompare realizedPnlUsd and unrealizedPnlUsd.
Activity FilteringSort by tradesCount to find the most active token traders.
Entity AnalysisUse name, labels, and logoUrl to identify known traders.

Trader Leaderboard Example

Build a leaderboard that ranks traders by realized PnL and shows their total PnL, volume, and trade count:

const API_KEY = process.env.VYBE_API_KEY;
const BASE_URL = "https://api.vybenetwork.xyz/v4";

async function fetchTopTraderLeaderboard(mintAddress) {
  const url = new URL(`${BASE_URL}/tokens/${mintAddress}/top-pnl-traders`);
  url.searchParams.set("resolution", "7d");
  url.searchParams.set("limit", "25");
  url.searchParams.set("page", "0");
  url.searchParams.set("sortByDesc", "realizedPnlUsd");

  const response = await fetch(url, {
    headers: { "X-API-Key": API_KEY }
  });

  if (!response.ok) {
    const error = await response.json().catch(() => ({}));
    throw new Error(
      `Vybe API error ${response.status}: ${error.message || "Request failed"}`
    );
  }

  const { data } = await response.json();

  return data.map((trader, index) => {
    const realizedPnl = Number(trader.realizedPnlUsd);
    const unrealizedPnl = Number(trader.unrealizedPnlUsd);
    const totalPnl = realizedPnl + unrealizedPnl;

    return {
      rank: index + 1,
      address: trader.traderAddress,
      name: trader.name || "Unknown trader",
      labels: trader.labels,
      realizedPnlUsd: realizedPnl.toFixed(2),
      unrealizedPnlUsd: unrealizedPnl.toFixed(2),
      totalPnlUsd: totalPnl.toFixed(2),
      totalVolumeUsd: Number(trader.totalVolumeUsd).toFixed(2),
      tradesCount: trader.tradesCount
    };
  });
}

fetchTopTraderLeaderboard("So11111111111111111111111111111111111111112")
  .then(console.table)
  .catch((error) => {
    console.error(error.message);
    process.exitCode = 1;
  });

Successful output:

┌─────────┬──────┬────────────────────────────────────────────────┬──────────────────┬──────────┬────────────────┬──────────────────┬─────────────┬────────────────┬─────────────┐
│ (index) │ rank │ address                                        │ name             │ labels   │ realizedPnlUsd │ unrealizedPnlUsd │ totalPnlUsd │ totalVolumeUsd │ tradesCount │
├─────────┼──────┼────────────────────────────────────────────────┼──────────────────┼──────────┼────────────────┼──────────────────┼─────────────┼────────────────┼─────────────┤
│ 0       │ 1    │ '9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM' │ 'Example Trader' │ [ 'KOL' ]│ '12345.67'     │ '890.12'         │ '13235.79'  │ '275001.34'    │ 42          │
└─────────┴──────┴────────────────────────────────────────────────┴──────────────────┴──────────┴────────────────┴──────────────────┴─────────────┴────────────────┴─────────────┘

Smart Money Filter Example

Filter for traders that are profitable, active, and trading meaningful volume:

const API_KEY = process.env.VYBE_API_KEY;
const BASE_URL = "https://api.vybenetwork.xyz/v4";

async function findSmartMoneyTraders(mintAddress) {
  const url = new URL(`${BASE_URL}/tokens/${mintAddress}/top-pnl-traders`);
  url.searchParams.set("resolution", "30d");
  url.searchParams.set("limit", "1000");
  url.searchParams.set("sortByDesc", "totalVolumeUsd");

  const response = await fetch(url, {
    headers: { "X-API-Key": API_KEY }
  });

  if (!response.ok) {
    const error = await response.json().catch(() => ({}));
    return {
      success: false,
      status: response.status,
      message: error.message || "Unable to fetch top traders",
      errorId: error.id
    };
  }

  const { data } = await response.json();

  const traders = data
    .map((trader) => ({
      address: trader.traderAddress,
      name: trader.name || "Unknown trader",
      labels: trader.labels,
      realizedPnlUsd: Number(trader.realizedPnlUsd),
      unrealizedPnlUsd: Number(trader.unrealizedPnlUsd),
      totalVolumeUsd: Number(trader.totalVolumeUsd),
      tradesCount: trader.tradesCount
    }))
    .filter((trader) => trader.realizedPnlUsd > 0)
    .filter((trader) => trader.totalVolumeUsd >= 10000)
    .filter((trader) => trader.tradesCount >= 5)
    .sort((a, b) => b.realizedPnlUsd - a.realizedPnlUsd);

  return {
    success: true,
    count: traders.length,
    traders
  };
}

Troubleshooting

StatusCauseFix
400Invalid query parameters.Use 1d, 7d, or 30d for resolution, keep limit at 1000 or lower, and send only one sort parameter.
403Missing or invalid API key.Send your API key in the X-API-Key header.
500Unexpected server error.Retry the request. If it continues, include the returned id when contacting support.

Related Endpoints