The Alpha Wallet Intelligence API leaderboard endpoint gives you ranked access to 25,000+ scored wallets — ordered by win rate, ROI, or net PnL, filterable by time period and minimum trade count. This post is for developers who want to understand the data model, query it efficiently, and build something real with it.
The Endpoint
GET /api/v1/alpha/leaderboard
Query parameters:
| Parameter | Type | Values | Default |
|---|
period | string | 7d, 30d, all | 30d |
sort | string | win_rate, roi, pnl | win_rate |
min_tokens | integer | 1–500 | 1 |
exclude_bots | boolean | true, false | false |
offset | integer | 0–n | 0 |
limit | integer | up to tier max | tier max |
Result limits by tier:
- BASIC: 25 results per request
- PRO: 100 results per request
- ULTRA: 500 results per request
Understanding the Response Fields
Each wallet entry in the response contains:
{
"wallet": "7xKXt...",
"rank": 1,
"win_rate": 0.713,
"net_pnl_sol": 284.7,
"avg_roi": 3.41,
"tokens_traded": 87,
"avg_hold_time_minutes": 23,
"bot_confidence": "low",
"is_kol": false,
"period": "all"
}
win_rate
Fraction of trades where the wallet exited at a profit, measured over the requested period. 0.713 = 71.3% win rate.
This is calculated on realized exits — the wallet actually sold. Unrealized positions still held are not counted in either direction, which means win rate can understate performance for wallets currently in profitable open positions and overstate it for wallets holding bags they haven't sold yet.
Key calibration: the average Pump.fun trader is net-negative over time. Any wallet consistently above 55% win rate on 30+ trades is performing well above baseline. Above 65% with 50+ trades is exceptional.
net_pnl_sol
Realized profit minus realized losses in SOL, over the requested period. This is after exit — only trades that have been closed count. Wallets with large unrealized positions may look worse here than their actual economic state.
net_pnl_sol is the most honest profitability metric because it doesn't let winners run forever on paper. A wallet at 200 SOL net PnL has actually extracted that from the market, not just held unrealized gains.
avg_roi
Average return on investment per trade, across all closed positions in the period. This is (exit_value - entry_value) / entry_value, averaged. Note that this is the simple mean — a few massive winners can pull this up significantly. For a more robust sense of typical performance, pair it with win_rate and net_pnl_sol.
avg_roi: 3.41 means the average closed trade returned 3.41x. That could mean most trades are 1.5x with a few 20x outliers, or consistent 3x exits — you need the full wallet profile (GET /api/v1/alpha/{wallet}) to distinguish between them.
tokens_traded
Total trades in the scoring window. This is your sample size denominator — essential context for win rate. Always surface this in any UI you build so users can assess statistical confidence themselves.
avg_hold_time_minutes
Median hold duration from first buy to final sell. This separates scalpers (sub-5 minute holds), day traders (under 60 minutes), and position traders (hours to days). If you're building a copy-trading system, this tells you the latency window within which following an entry makes sense.
bot_confidence
low / medium / high. Derived from behavioral signals: entry timing patterns, transaction structure, cross-token behavior. High-confidence bot wallets are often statistical outliers because their edge is execution speed, not judgment. Set exclude_bots=true when you want human-driven intelligence.
Paging Through Results
The leaderboard is paginated via offset and limit. Here's a clean paging implementation:
import { MadeOnSolClient } from "madeonsol";
const client = new MadeOnSolClient({ apiKey: process.env.MSK_API_KEY });
async function fetchFullLeaderboard(maxResults = 500) {
const PAGE_SIZE = 100; // PRO tier max per request
const results = [];
let offset = 0;
while (results.length < maxResults) {
const page = await client.alpha.getLeaderboard({
period: "all",
sort: "win_rate",
min_tokens: 20,
exclude_bots: true,
limit: PAGE_SIZE,
offset,
});
results.push(...page.wallets);
if (page.wallets.length < PAGE_SIZE) break; // last page
offset += PAGE_SIZE;
}
return results.slice(0, maxResults);
}
On ULTRA, you can pull 500 results in a single request. On PRO, three requests gets you 300 wallets — enough for a comprehensive watchlist.
Building a Top Wallets Dashboard
The leaderboard is the backbone of any smart money dashboard. Here's a minimal but production-ready pattern:
interface WalletRow {
wallet: string;
winRate: string;
netPnlSol: string;
avgRoi: string;
tradeCount: number;
holdTime: string;
}
function formatLeaderboard(wallets: any[]): WalletRow[] {
return wallets.map((w) => ({
wallet: `${w.wallet.slice(0, 4)}...${w.wallet.slice(-4)}`,
winRate: `${(w.win_rate * 100).toFixed(1)}%`,
netPnlSol: `${w.net_pnl_sol > 0 ? "+" : ""}${w.net_pnl_sol.toFixed(1)} SOL`,
avgRoi: `${w.avg_roi.toFixed(2)}x`,
tradeCount: w.tokens_traded,
holdTime:
w.avg_hold_time_minutes < 60
? `${w.avg_hold_time_minutes}m`
: `${(w.avg_hold_time_minutes / 60).toFixed(1)}h`,
}));
}
Pair this with a weekly refresh cron and you have a self-updating smart money directory. Cache the leaderboard response on your side — it doesn't need to be queried more than once per hour for a dashboard use case.
Building a Bot Signal Feed
The more powerful use case is wiring the leaderboard into an automated trading or alerting system. The pattern: maintain a local set of "smart money wallets" derived from the leaderboard, monitor on-chain for those wallets buying new tokens, then trigger your decision logic.
import { MadeOnSolClient } from "madeonsol";
import { Connection, PublicKey } from "@solana/web3.js";
const client = new MadeOnSolClient({ apiKey: process.env.MSK_API_KEY });
// Step 1: Build watchlist from leaderboard
async function buildWatchlist(): Promise<Set<string>> {
const leaderboard = await client.alpha.getLeaderboard({
period: "all",
sort: "win_rate",
min_tokens: 25,
exclude_bots: true,
});
return new Set(leaderboard.wallets.map((w) => w.wallet));
}
// Step 2: When a new token is detected, check if smart money bought it
async function checkSmartMoneyEntry(
mint: string,
watchlist: Set<string>
): Promise<boolean> {
const capTable = await client.alpha.getCapTable(mint);
const smartMoneyBuyers = capTable.buyers.filter((b) =>
watchlist.has(b.wallet)
);
return smartMoneyBuyers.length >= 2; // require 2+ smart money wallets
}
This is the foundation of a signal system that doesn't rely on Twitter calls or Telegram alpha groups. It's purely on-chain, sourced from wallets with verified track records. If the broader landscape of Solana data APIs is new to you, our primer on what a Solana API is and the types that exist frames where this leaderboard fits among RPC, enhanced, and data APIs. The how to build a Solana trading bot guide covers the execution side — how to handle swaps, manage slippage, and submit transactions — which you'd layer on top of this signal layer.
Choosing the Right Time Period
The period parameter changes which trades count toward the scores: