The KOL leaderboard assumes every tracked wallet is an independent information source. That's almost never true. Run a copy-trade roster of 5 wallets and you'll quickly find that 2 of them are just copying a 3rd, one is a bot following the whole group, and the "5 diversified alpha sources" is actually 2 sources and 3 echoes.
GET /api/v1/kol/pairs is the endpoint that surfaces this structure. It returns the affinity matrix across all tracked KOLs — every pair, sorted by how often they buy the same tokens within tight timing windows. High-affinity pairs are either copy-trading each other, sharing a group chat, or part of a coordinated bot cluster. Either way, they're not independent.
The call
GET /api/v1/kol/pairs?period=7d&min_shared=3&limit=20
Authorization: Bearer msk_...
Parameters:
period — 7d or 30d. Default 7d. Short windows catch current clusters; 30d reveals durable relationships.
min_shared — minimum number of shared tokens to include a pair. Range 1–20, default 3. Lower values surface casual overlap; higher values only return tight pairs.
limit — 1–50 pairs returned. Default 20.
Responses are cached 5 minutes server-side so rapid polls are cheap.
The response
{
"pairs": [
{
"kol_a": { "name": "Publix", "wallet": "86AE...EdD" },
"kol_b": { "name": "Clown", "wallet": "EDXH...HR8" },
"shared_token_count": 18,
"agreement_rate": 83.33,
"shared_tokens": [
"26s2aY...pump", "9FgEb8X...mint", "4vW54Bm...", ...
]
},
{
"kol_a": { "name": "RaydiumFan", "wallet": "..." },
"kol_b": { "name": "PumpDegen", "wallet": "..." },
"shared_token_count": 11,
"agreement_rate": 45.45
}
],
"period": "7d",
"min_shared": 3
}
Each pair has:
shared_token_count — how many tokens both wallets bought in the period.
agreement_rate (%) — of those shared tokens, what fraction they bought within 2 hours of each other. This is the coordination signal.
shared_tokens[] — list of the actual mint addresses. ULTRA only — PRO and BASIC omit this array.
Reading agreement_rate
shared_token_count alone doesn't tell you much. Two KOLs who both trade heavily on pump.fun will overlap on many tokens just by pure coverage. What matters is how often they enter those shared tokens at the same time.
Calibration:
agreement_rate | Interpretation |
|---|
| 90%+ | Almost certainly coordinated. Either one is copy-trading the other, they're in the same group chat, or they share a bot. |
| 60–90% | Tight cluster. Same information flow, same tooling. Treat as one signal source. |
| 40–60% | Loose overlap. Partially correlated strategies. |
| 20–40% | Coincidental overlap from both fishing the same pool (e.g. pump.fun). |
| < 20% | Independent wallets that happen to share coverage. |
Combine with shared_token_count:
- Low
shared_token_count + high agreement_rate = small number of tokens, but they always trade them together. Could be a specific thesis group.
- High
shared_token_count + high agreement_rate = the strongest coordination signal. You've found a pod.
- High
shared_token_count + low agreement_rate = they trade the same pool but move independently. Two snipers on pump.fun, not coordination.
Use cases
De-duplicating a copy-trade roster
The most concrete use. You've shortlisted 5 wallets to copy-trade. Run /kol/pairs?period=30d&min_shared=5 and look for pairs from your shortlist with high agreement rates. (If you're still assembling that roster, our walkthrough on building a Solana copy-trading signal feed shows how to wire the Wallet Tracker API into a live feed.)
import { MadeOnSol } from "madeonsol";
const client = new MadeOnSol({ apiKey: process.env.MADEONSOL_API_KEY! });
async function deduplicateRoster(candidates: string[]) {
// Pull a big pair list for the period
const { pairs } = await client.kol.pairs({
period: "30d",
min_shared: 5,
limit: 50,
});
// Find cross-roster high-affinity pairs
const roster = new Set(candidates);
const coordinated = pairs.filter(
(p) =>
roster.has(p.kol_a.wallet) &&
roster.has(p.kol_b.wallet) &&
p.agreement_rate >= 70
);
// For each coordinated pair, drop the one with lower historical win rate
// (left as exercise — needs /kol/{wallet} lookups)
return coordinated;
}
If your shortlist has 5 wallets and 2 of them pair at 85% agreement, you're effectively copy-trading 4 wallets, not 5. Drop one, reclaim a slot on your rate limits.
Bot cluster detection
Pure bots frequently show up as pairs with 95%+ agreement_rate over 30-40 shared tokens. They're not information sources — they're algorithmic reactors. If your strategy is "follow where smart humans are buying first," you want to exclude bot clusters from your KOL feed.
Identify a bot-dominated pair once, and both wallets can be tagged as bot-suspect in your downstream pipeline.
Spotting new alpha cohorts
Periodic sweeps at ?period=7d surface which KOLs have recently started co-trading. If two wallets that didn't appear together in 30d data now pair at 70% agreement over 5 shared tokens in the last week, something changed — a new group formed, someone got added to a chat, a new tooling stack went live. Worth watching those pairs for the tokens they collectively signal. To find out which member of a cluster actually fires first on a given mint, cross-reference the KOL entry-order endpoint, which ranks every tracked wallet by buy timestamp.
Independence-check before a paid subscription
Before you subscribe to a KOL's signal service or copy-trade group, check their pair affinity against other KOLs you already follow. If they pair at 80%+ with someone you already track, you're paying for redundant signal.
Worked example: the "coordinated sell" trap
Suppose you've copy-traded a wallet that's been great on buys. You keep getting good entries. Then one day the wallet sells a position and you take a loss. You later discover the sell was triggered by 6 other KOLs dumping the same token within 5 minutes — a coordinated exit you didn't see coming.
A high agreement_rate pair on sells is just as meaningful as on buys. If your copy-trade target pairs at 85% with 4 other KOLs, every sell they make could be group-triggered. That doesn't make the signal bad — but it does mean you should either copy the whole cluster or none of them, never just one.
Missing transitive clusters. If A and B pair at 80%, and B and C pair at 80%, A and C are probably in the same cluster even if their direct pair is lower. Build the full graph from /kol/pairs data, not just the top pair list.