Solana memecoin intelligence · API reference
REST, webhooks, and WebSocket streams over the same KOL, deployer, alpha-wallet, and DEX firehose data. Authenticated with a single msk_ bearer key or — for agents — paid per call via x402. Free tier ships full response shape, all 141 endpoints.
Base URL madeonsol.com/api/v1·Auth header Authorization: Bearer msk_…·JSON in, JSON out
What ships in v1
The surface area, the venues, the SDKs, the push latency.
KOL · deployer · alpha · stream
Pump · Raydium · Jupiter · …
TypeScript · Python · Rust
WS + webhooks (Pro/Ultra)
Try it live
Hit production. No signup.
Public demo key. 20 calls/hour per IP, 3 read-only endpoints. Want 120+ endpoints and 200 calls/day? Free key, one click →
Demo API key
msk_demo_try_the_solana_api_2026Paste into your terminal
curl -H "Authorization: Bearer msk_demo_try_the_solana_api_2026" "https://madeonsol.com/api/v1/kol/feed?limit=3"
Quick start
Free key, one curl call, optional SDK.
Authorization header, REST, JSON in / JSON out.
curl -H "Authorization: Bearer msk_…" \ "https://madeonsol.com/api/v1/kol/feed?limit=5"
TypeScript or Rust — same endpoints, same msk_ auth.
npm install madeonsol # or cargo add madeonsol
Starter kits
Open-source (MIT) example projects — free-key runnable, one dependency or fewer. Fork them into your own thing.
kol-copytrade-bot-starterOpens a virtual position when a tracked KOL buys, closes when they sell. Free tier polls /kol/feed; PRO streams kol:trades over WebSocket (<3s).
rug-check-telegram-botPaste a mint → transparent 0–100 risk score with named factors (PRO) or early-buyer quality (free). Zero dependencies.
deployer-alert-discord-botDiscord embeds when a tracked pump.fun / bonk deployer launches or bonds a token. Free-key-safe polling, one webhook URL.
MIT-licensed. Grab a free key and each runs in five minutes — the free tier is genuinely usable, PRO unlocks real-time streams.
Authentication
API key for humans and apps. x402 for autonomous agents paying per call.
Get a free key at /developer — instant, no payment to start. Free tier: 200 calls/day, 40+ endpoints.
curl -H "Authorization: Bearer msk_your_api_key" \ "https://madeonsol.com/api/v1/kol/feed?limit=5"
Windows PowerShell: use curl.exe (bare curl is an Invoke-WebRequest alias).
No key. The agent's Solana wallet IS the identity. Pay per call for KOL, deployer, and wallet data — plus the trade-decision calls an agent makes at the moment of a buy: token risk score, buyer quality, live token snapshot, and the machine-readable Signal Scorecard. See /x402 for the full protocol.
# Receive 402 → sign USDC → retry with proof → data curl https://madeonsol.com/api/x402/kol/feed?limit=5
$0.005–$0.02 per call · settles in ~1s · failed payments don't charge.
Transports
Same data — four delivery shapes.
Dashboards, batch jobs, anything human-paced. The default.
Autonomous AI agents with a Solana wallet but no account.
Long-running bots, alerts, copy-trade execution.
Sub-second decisions, all-DEX coverage, agent loops.
Tier comparison
Every tier ships the full response shape. Paid gates are per-user infra (webhooks, WS, rules) and ULTRA-only data depth.
| Feature | BasicFree | Pro€43/mo | Ultra€131/mo |
|---|---|---|---|
| Daily requests | 200 | 10,000 | 100,000 |
| Burst rate limit | 60/min | 120/min | 600/min |
| Wallet addresses | Full | Full | Full |
| TX signatures | Included | Included | Included |
| KOL feed · leaderboard · profile · PnL · timing | Full | Full | Full |
| KOL coordination detection | Full | Full | Full |
| KOL hot / trending / pairs | 20 results | 20 results | 100 + wallets |
| KOL compare | 4 wallets | 4 wallets | 5 wallets |
| Deployer leaderboard · profile · tokens · trajectory | Full | Full | Full |
| Deployer alerts depth | Up to 50 | Up to 50 | Full pagination |
| Deployer multiplier stats | Full | Full | Full |
| Alpha leaderboard | 100 results | 100 results | 500 + bot signals |
| Alpha profile · linked wallets | — | — | Full |
| Token cap table | — | Top 10 | Top 20 |
| Token buyer quality | Full | Full | Full |
| Token risk/safety score + per-factor breakdown | — | ✓ | ✓ |
| Wallet tracker watchlist | 10 wallets | 50 wallets | 100 wallets |
| Wallet tracker history | Full | Full | Full |
| Copy-trade rules | — | 3 × 5 wallets | 20 × 50 wallets |
| KOL coordination push alerts | — | 5 rules | 20 rules |
| Price alerts (MC dip/recovery) | — | 5 alerts | 25 alerts |
| Webhooks | — | 3 | 10 |
| WebSocket streaming | — | 1 conn | 3 conn |
| Wallet tracker real-time (WS) | — | — | Included |
| DEX firehose (all-DEX WS) | — | — | 2 conn |
Endpoints
All 141 endpoints, grouped by capability. Each card has parameters, defaults, and a real response example.
Catalog
Click a row to jump to the full reference card below.
Latency
Where the seconds come from — and where they don't.
Kaldera Yellowstone · FRA + NYC
Two-region dual-stream gRPC fans out every confirmed swap. We pick the first-to-arrive per slot.
Decode · price · MC · tier · denorm
Decode the DEX program, attach KOL/deployer/alpha tags, stamp market cap, write to Postgres + pg_notify.
WebSocket · webhook · REST cache
Subscribers get the event via the ws-streaming service. Webhook deliveries kick off in parallel with HMAC signing.
KOL Tracker
Real-time wallet activity from 1,000+ tracked Solana KOLs across 14 DEX programs.
/kol/feedReal-time trade feed from 1,000+ tracked Solana KOL wallets. Every buy and sell detected within seconds across Pump.fun, Raydium, Jupiter, Orca, and more.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 50 | Number of trades (1-100) |
| before | ISO datetime | — | Cursor — return trades strictly older than this timestamp. Pass `next_before` from previous response. |
| action | string | — | Filter: "buy" or "sell" |
| kol | string | — | Filter by KOL wallet address |
| min_sol | number | — | Minimum SOL size per trade |
| token_age_max_min | integer | — | Max token age in minutes at time of trade |
| exclude_sells | boolean | false | Drop sell-side trades |
| min_kol_winrate | number | — | Minimum 7d winrate of the KOL (0-100) |
| strategy | string | — | "scalper", "day_trader", "swing_trader", "hodler", or "mixed" |
{
"trades": [
{
"wallet_address": "CyaE1Vxv...ga54o",
"kol_name": "Cented",
"kol_twitter": "https://x.com/Cented7",
"token_mint": "tca3tbFf...pump",
"token_name": "Hands Off Coin",
"token_symbol": "Hands Off",
"action": "buy",
"sol_amount": 5.27,
"token_amount": 19389235.04,
"market_cap_usd_at_trade": 28430,
"price_usd_at_trade": 0.0000284,
"tx_signature": "4fu8vvsF...v1sb",
"traded_at": "2026-03-25T04:18:43+00:00"
}
],
"count": 1
}/kol/leaderboardRanked leaderboard of KOL wallets by realized PnL in SOL — plus alternative sort axes (winrate, ROI, profit factor, early-entry share, consistency). Ranking windows: today, 7d, 30d, 90d, 180d.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 7d | Time period: "today", "7d", "30d", "90d", or "180d" |
| limit | integer | 20 | Number of KOLs (1-50) |
| sort | string | pnl | "pnl", "winrate", "volume", "avg_roi", "profit_factor", "early_entry_pct", or "consistency" |
| strategy | string | — | Filter by strategy tag |
| min_winrate | number | — | Minimum winrate cutoff (0-100) |
{
"leaderboard": [
{
"name": "Cented",
"wallet": "CyaE1Vxv...ga54o",
"pnl": 1672.8,
"buy_count": 2960,
"sell_count": 1525,
"volume": 8748.72,
"median_hold_minutes_30d": 47,
"percentile_early_entry_30d": 82
},
{
"name": "Marcell",
"wallet": "FixmSpsB...7X",
"pnl": 630.97,
"buy_count": 154,
"sell_count": 51,
"volume": 3457.54,
"median_hold_minutes_30d": 120,
"percentile_early_entry_30d": 61
}
],
"period": "7d"
}/kol/{wallet}Detailed profile for a specific KOL wallet. Includes PnL stats, trade history, buy/sell counts, total volume, full mv_kol_scores peer-rank block, and optional per-token PnL breakdown via ?include=pnl_by_token,recent_winners,recent_losers.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | Solana wallet address of the KOL |
| include | string | — | Comma-separated: "pnl_by_token", "recent_winners", "recent_losers" |
{
"kol": {
"name": "Cented",
"wallet": "CyaE1Vxv...ga54o",
"twitter_url": "https://x.com/Cented7"
},
"stats": {
"pnl": 25.71,
"buy_count": 78,
"sell_count": 22,
"volume": 167.89,
"win_rate": 62.5
},
"recent_trades": [
"..."
],
"pnl_by_token": [
{
"token_mint": "tca3tbFf...pump",
"token_symbol": "HANDS",
"pnl": 12.4,
"result": "win"
}
]
}/kol/coordinationDetect tokens being traded by multiple KOLs within a time window. Surfaces coordination signals — when 3+ KOLs converge on the same token, it's often significant.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 24h | Time window: "1h", "6h", "24h", or "7d" |
| min_kols | integer | 3 | Minimum KOLs trading the same token (2-50) |
| limit | integer | 20 | Max results (1-50) |
| min_avg_winrate | number | — | Require cluster avg winrate_7d >= N (0-100) |
| unique_strategies | integer | — | Require >= N distinct strategies in cluster |
{
"coordination": [
{
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"token_name": "Pepe Reborn",
"kol_count": 5,
"total_buys": 12,
"total_sells": 3,
"net_sol_flow": 47.82,
"signal": "accumulating",
"kols": [
{
"name": "Cented",
"wallet": "CyaE...ga54o"
},
{
"name": "Marcell",
"wallet": "Fixm...7X"
}
]
}
],
"period": "24h",
"min_kols": 3
}/kol/tokens/{mint}Get all KOL trading activity for a specific token. Returns an aggregate summary (total bought/sold, net flow, accumulating/distributing signal) plus a per-KOL breakdown.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Solana token mint address |
{
"token_mint": "9aK2rFy1...pump",
"summary": {
"kol_count": 4,
"total_bought_sol": 82.5,
"total_sold_sol": 34.7,
"net_flow_sol": 47.8,
"signal": "accumulating"
},
"kols": [
{
"name": "Cented",
"wallet": "CyaE1Vxv...ga54o",
"buy_count": 3,
"sell_count": 1,
"total_bought": 25,
"total_sold": 10.2,
"net_sol": -14.8,
"position": "net_buyer",
"first_trade": "2026-03-24T10:00:00Z",
"last_trade": "2026-03-25T04:18:00Z"
}
]
}/kol/pairsDiscover which KOLs frequently co-trade the same tokens. Returns pairs ranked by shared token count with agreement rate (both bought within 2 hours). ULTRA adds the list of shared token mints per pair.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 7d | Time period: "7d" or "30d" |
| min_shared | integer | 3 | Minimum shared tokens to qualify (1-20) |
| limit | integer | 20 | Number of pairs (1-50) |
{
"pairs": [
{
"kol_a": {
"name": "Murad",
"wallet": "7QZG...LPZT"
},
"kol_b": {
"name": "traderpow",
"wallet": "2Dh5...w6"
},
"shared_token_count": 7,
"agreement_rate": 85.71,
"shared_tokens": [
"EPjF...Dt1v",
"7vfC...rXs2"
]
}
],
"period": "7d",
"min_shared": 3
}/kol/{wallet}/timingEntry/exit behavioral analytics for a specific KOL. Hold duration, exit speed distribution (% closed within 1h/6h/24h), average trade sizes, and hour-of-day activity pattern.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string | — | KOL wallet address (base58, path param) |
| period | string | 30d | Time period: "7d" or "30d" |
{
"kol": {
"name": "Murad",
"wallet": "7QZG...LPZT"
},
"timing": {
"tokens_traded": 42,
"positions_closed": 28,
"avg_hold_minutes": 312.5,
"median_hold_minutes": 180,
"pct_closed_1h": 21.4,
"pct_closed_6h": 57.1,
"pct_closed_24h": 85.7,
"avg_buy_size_sol": 2.45,
"avg_sell_size_sol": 3.12,
"most_active_hours": [
14,
15,
20
]
},
"period": "30d"
}/kol/tokens/hotTokens with accelerating KOL buy interest — early signal before full coordination triggers. Compares recent KOL buy rate (last 25% of period) to baseline. Acceleration > 1.0 means buying is speeding up. ULTRA adds full KOL wallet addresses per token.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 6h | Time period: "1h" or "6h" |
| min_kols | integer | 1 | Minimum KOL buyers (1-20) |
| limit | integer | 20 | Number of tokens (1-50) |
| min_avg_winrate | number | — | Require avg winrate_7d of buyers >= N (0-100) |
| unique_strategies | integer | — | Require >= N distinct strategies among buyers |
{
"hot_tokens": [
{
"token_mint": "EPjF...Dt1v",
"token_symbol": "PEPE",
"token_name": "Pepe on Sol",
"kols_total": 5,
"kols_recent": 3,
"acceleration": 2.4,
"total_buy_sol": 45.2,
"total_sell_sol": 12.1,
"net_flow": 33.1,
"first_kol_buy_age_minutes": 42,
"kols": [
{
"name": "Murad"
},
{
"name": "traderpow"
}
]
}
],
"period": "6h",
"min_kols": 1
}/kol/tokens/trendingTokens ranked by raw KOL buy volume — a pure capital-flow signal showing where KOL money is going right now. Supports 7 time windows from 5 minutes to 12 hours. ULTRA adds full KOL wallet addresses per token.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 1h | Time window: "5m", "15m", "30m", "1h", "2h", "4h", or "12h" |
| min_kols | integer | 1 | Minimum KOL buyers (1-20) |
| limit | integer | 20 | Number of tokens (1-50) |
{
"trending": [
{
"token_mint": "EPjF...Dt1v",
"token_symbol": "Wcoin",
"token_name": "chasing that w",
"buy_volume_sol": 133.76,
"sell_volume_sol": 111.79,
"net_flow_sol": 21.98,
"buy_count": 24,
"sell_count": 18,
"kol_count": 10,
"latest_buy_age_minutes": 2,
"kols": [
{
"name": "OGAntD"
},
{
"name": "Silver"
},
{
"name": "West"
}
]
}
],
"period": "1h",
"min_kols": 1
}/kol/{wallet}/pnlDeep per-wallet PnL breakdown. Returns summary stats (realized PnL, win rate, profit factor, max drawdown, avg ROI, hold times), daily PnL equity curve, and per-token closed positions. ULTRA adds open positions (tokens bought but not yet sold).
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | KOL wallet address (base58) |
| period | string | 30d | Time period: "7d", "30d", "90d", or "180d" |
{
"kol": {
"name": "OGAntD",
"wallet": "215n...gQjP",
"strategy_tag": "day_trader"
},
"summary": {
"realized_pnl_sol": -27.39,
"win_count": 92,
"loss_count": 52,
"win_rate": 63.89,
"profit_factor": 0.913,
"max_drawdown_sol": 129.41,
"avg_roi_pct": 4.65,
"avg_hold_minutes": 1149.9
},
"pnl_curve": [
{
"date": "2026-03-19",
"day_pnl": 4.17,
"cumulative_pnl": 4.17,
"trades": 9
},
{
"date": "2026-03-20",
"day_pnl": 24.95,
"cumulative_pnl": 29.12,
"trades": 15
}
],
"closed_positions": [
{
"token_symbol": "BONK",
"pnl_sol": 43.47,
"roi_pct": 180.5,
"hold_minutes": 320,
"result": "win"
}
],
"period": "30d"
}/kol/tokens/{mint}/entry-orderRanked order of KOL first-buyers for a specific token — who entered first and how quickly others followed. Each entry includes seconds_after_first relative to the first KOL entry and percentile ranks (percentile_pnl_7d, percentile_winrate_7d).
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Solana token mint address |
| limit | integer | 50 | Max ranked entries (1-200) |
{
"token_mint": "9aK2rFy1...pump",
"entries": [
{
"rank": 1,
"wallet_address": "CyaE1Vxv...ga54o",
"kol_name": "Cented",
"sol_amount": 8.42,
"token_amount": 24218991.1,
"traded_at": "2026-03-25T04:18:43+00:00",
"seconds_after_first": 0,
"tx_signature": "4fu8vvsF...v1sb",
"strategy_tag": "sniper",
"winrate_7d": 68.2,
"early_entry_pct_30d": 72.1,
"percentile_pnl_7d": 94.3
}
],
"count": 1
}/kol/compareSide-by-side comparison of 2-5 KOL wallets — strategy tag, 7d/30d winrates, ROI, profit factor, early-entry %, PnL percentiles, cold/heating-up flags, and 30d overlap tokens (bought by 2+ of the wallets). Max 4 wallets; ULTRA allows 5.
| Name | Type | Default | Description |
|---|---|---|---|
| wallets | string | required | Comma-separated list of 2-5 wallet addresses |
{
"profiles": [
{
"wallet_address": "CyaE1Vxv...ga54o",
"name": "Cented",
"strategy_tag": "swinger",
"winrate_7d": 61.4,
"winrate_30d": 58.7,
"roi_30d": 18.4,
"profit_factor_30d": 1.82,
"early_entry_pct_30d": 44.1,
"pnl_30d": 412.5,
"percentile_pnl_30d": 96.7,
"is_heating_up": true
}
],
"overlap": [
{
"token_mint": "EPjF...Dt1v",
"token_symbol": "PEPE",
"wallets": [
"CyaE1Vxv...ga54o",
"FixmSpsB...7X"
],
"first_buy_at": "2026-04-14T08:22:00Z",
"last_buy_at": "2026-04-14T09:12:00Z"
}
],
"count": 2
}/kol/alerts/recentUnified live KOL alert stream — consensus clusters (3+ KOLs buying same token), fresh-token KOL buys (token <30 min old, KOL winrate ≥50), and heating-up wallets (percentile jump). Sorted by detected_at DESC then severity.
| Name | Type | Default | Description |
|---|---|---|---|
| window | string | 15m | Lookback window: "5m", "15m", "1h", "6h", or "24h" |
| types | string | — | Comma-separated: "consensus_cluster", "fresh_token_kol_buy", "heating_up" |
| min_severity | string | — | "low", "medium", or "high" |
| limit | integer | 50 | Max alerts (1-200) |
{
"alerts": [
{
"type": "consensus_cluster",
"severity": "high",
"detected_at": "2026-04-18T08:42:11Z",
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"details": {
"kol_count": 5,
"buy_span_seconds": 142,
"net_sol_flow": 47.8
}
},
{
"type": "fresh_token_kol_buy",
"severity": "medium",
"detected_at": "2026-04-18T08:39:44Z",
"token_mint": "4HxQKdTT...pump",
"wallet_address": "CyaE1Vxv...ga54o",
"kol_name": "Cented",
"details": {
"token_age_minutes": 12,
"kol_winrate_7d": 64.1
}
}
],
"count": 2,
"window": "15m"
}/kol/first-touchesEvery "first KOL buy on a token mint" event — the moment a tracked KOL is the first of the cohort to touch a token. Filterable by scout tier (S/A/B/C from mv_kol_scout_score), KOL winrate, token age, mint suffix. 38d backtest: top scouts attract ≥3 follow-on KOLs within 4h ~50% of the time vs ~14% baseline. Median lead time before second KOL is 12s — for trading, use the kol:first_touches WS channel instead of polling.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 50 | Number of events (1-100, BASIC capped at 20) |
| since | ISO datetime | — | Polling cursor — events strictly newer than this |
| before | ISO datetime | — | Pagination cursor — events strictly older than this |
| kol | string | — | Single KOL wallet (32-44 base58 chars) |
| min_kol_winrate_7d | number | — | 0-100 |
| min_scout_tier | string | — | "S", "A", "B", or "C". Requires n_first_touches_30d ≥ 30. |
| min_n_touches | integer | 30 | Lower the minimum sample size for scout scoring |
| strategy | string | — | "scalper", "day_trader", "swing_trader", "hodler", or "mixed" |
| token_age_max_min | integer | — | Only events on tokens younger than N minutes |
| min_first_buy_sol | number | — | Minimum size of the first KOL buy in SOL |
| mint_suffix | string | — | Suffix-filter the token mint (e.g. "pump") |
| preset | string | — | "scout" = min_scout_tier=B + min_n_touches=30 + token_age_max_min=60. "fresh_launch" = token_age_max_min=15. |
| include | string | — | "followers_4h" attaches retrospective follower count for events ≥4h old |
{
"events": [
{
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"token_name": "Pepe Reborn",
"token_image_url": "https://...",
"first_buy_at": "2026-04-26T07:18:42Z",
"sol_amount": 1.234,
"token_amount": 4567890.12,
"tx_signature": "5mmHpg35...",
"token_age_minutes": 7,
"first_kol": {
"name": "Jijo",
"twitter_url": "https://x.com/jijo",
"winrate_7d": 67.5,
"strategy": "scalper",
"scout_tier": "S",
"scout_score": 51.1,
"n_first_touches_30d": 331
}
}
],
"count": 1,
"next_before": "2026-04-26T07:18:42Z",
"data_age_seconds": 4
}/kol/scouts/leaderboardRanked leaderboard of KOLs by scout score — first-touch accuracy, follow-on rate, and lead time. S-tier scouts attract 3+ follow-on KOLs within 4h ~50% of the time. Filterable by scout tier, sortable by score, follow-on rate, or lead time.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 50 | Number of results (1-100) |
| scout_tier | string | — | Filter by tier: "S", "A", "B", or "C" |
| sort | string | scout_score | "scout_score", "follow_on_rate", or "lead_time" |
{
"scouts": [
{
"kol_name": "Jijo",
"wallet": "9xKv...3bPq",
"scout_tier": "S",
"scout_score": 51.1,
"n_first_touches_30d": 331,
"follow_on_rate_4h": 0.52,
"median_lead_time_seconds": 12,
"winrate_7d": 67.5,
"strategy": "scalper"
}
],
"count": 1
}/kol/coordination/historyPast coordination clusters with outcomes — did the token pump after KOLs converged? Returns clusters with entry MC, peak MC after detection, and outcome classification (hit, miss, pending). Useful for backtesting coordination signals and measuring signal quality over time.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 50 | Number of clusters (1-100) |
| since | ISO datetime | — | Only clusters detected after this timestamp |
| min_score | integer | — | Minimum coordination_score (0-100) |
{
"clusters": [
{
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"kol_count": 5,
"coordination_score": 82,
"detected_at": "2026-05-20T08:42:11Z",
"entry_mc_usd": 28430,
"peak_mc_usd_after": 423000,
"mc_multiplier": 14.9,
"outcome": "hit",
"time_to_peak_minutes": 47
}
],
"count": 1
}/kol/first-touches/subscriptionsULTRAULTRA only. Create a webhook subscription that delivers kol:first_touch events matching your filters as HMAC-SHA256-signed POSTs. Up to 10 active subscriptions per ULTRA user. Returns webhook_secret ONCE — store it for signature verification.
| Name | Type | Default | Description |
|---|---|---|---|
| name | string | — | Optional label |
| filters | object | {} | { kol?, mint_suffix?, min_first_buy_sol?, min_scout_tier?, min_n_touches? } |
| delivery_mode | string | websocket | "websocket", "webhook", or "both" |
| webhook_url | string | — | HTTPS URL — required when delivery_mode includes "webhook" |
{
"subscription": {
"id": "a3f17b22-...",
"name": "S-tier scouts on pump tokens",
"filters": {
"min_scout_tier": "S",
"mint_suffix": "pump"
},
"delivery_mode": "webhook",
"webhook_url": "https://my.bot/hooks/scout",
"is_active": true,
"created_at": "2026-04-26T08:00:00Z"
},
"webhook_secret": "<32-byte hex — shown once>",
"note": "Save the webhook_secret — it will not be shown again. ..."
}/kol/coordination/alertsPRO/ULTRAList your KOL-coordination push-alert rules — active and inactive. A rule fires when at least `min_kols` distinct tracked KOLs converge on the same token inside a rolling window. PRO/ULTRA only (PRO: 5 rules, ULTRA: 20 rules).
{
"rules": [
{
"id": "c1a2e0f4-...-e9",
"name": "4+ KOLs, 15m",
"min_kols": 4,
"window_minutes": 15,
"min_score": 0,
"include_majors": false,
"cooldown_min": 30,
"score_jump_break": 20,
"delivery_mode": "websocket",
"webhook_url": null,
"min_mc_usd": null,
"max_mc_usd": null,
"is_active": true,
"created_at": "2026-06-01T09:00:00Z",
"updated_at": "2026-06-01T09:00:00Z"
}
]
}/kol/coordination/alertsPRO/ULTRACreate a KOL-coordination push-alert rule. Fires when ≥ `min_kols` distinct tracked KOLs buy the same token within `window_minutes`. Returns `webhook_secret` once if webhook delivery is configured. PRO/ULTRA only (PRO: 5 rules, ULTRA: 20 rules).
| Name | Type | Default | Description |
|---|---|---|---|
| name | string | — | Optional label (max 64 chars) |
| min_kols | integer | 5 | Distinct KOLs required to converge (2-50) |
| window_minutes | integer | 15 | Rolling convergence window (1-60) |
| min_score | integer | 0 | Minimum coordination score to fire (0-100) |
| include_majors | boolean | false | Include major/blue-chip tokens (excluded by default) |
| cooldown_min | integer | 30 | Per-token cooldown between fires (1-1440 min) |
| score_jump_break | integer | 20 | Re-fire during cooldown if score jumps by this much (0-100) |
| delivery_mode | string | websocket | "websocket", "webhook", or "both" |
| webhook_url | string | — | HTTPS URL — required when delivery_mode includes webhook |
| min_mc_usd | number | — | Only fire if the triggering trade's entry MC ≥ this (USD) |
| max_mc_usd | number | — | Only fire if the triggering trade's entry MC ≤ this (USD) |
{
"rule": {
"id": "c1a2e0f4-...-e9",
"name": "4+ KOLs, 15m",
"min_kols": 4,
"window_minutes": 15,
"delivery_mode": "webhook",
"webhook_url": "https://my.bot/hooks/coord",
"is_active": true,
"created_at": "2026-06-01T09:00:00Z"
},
"webhook_secret": "<32-byte hex — shown once>",
"note": "Save the webhook_secret — it will not be shown again."
}/kol/coordination/alerts/{id}PRO/ULTRAFetch a single coordination alert rule by ID. Returns 404 if not found or not owned by the caller. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| id | string (UUID) | required | Rule ID — path parameter |
{
"rule": {
"id": "c1a2e0f4-...-e9",
"name": "4+ KOLs, 15m",
"min_kols": 4,
"window_minutes": 15,
"min_score": 0,
"delivery_mode": "websocket",
"is_active": true,
"created_at": "2026-06-01T09:00:00Z",
"updated_at": "2026-06-01T09:00:00Z"
}
}/kol/coordination/alerts/{id}PRO/ULTRAUpdate a coordination alert rule — accepts any field from Create (all optional) plus `is_active`. Send only the fields you want to change. Pass `min_mc_usd`/`max_mc_usd` as null to clear a bound. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| id | string (UUID) | required | Rule ID — path parameter |
| is_active | boolean | — | Enable or disable the rule |
| min_kols | integer | — | Distinct KOLs required (2-50) |
| min_score | integer | — | Minimum coordination score (0-100) |
| delivery_mode | string | — | "websocket", "webhook", or "both" |
| webhook_url | string | — | HTTPS URL (or null to clear) |
| min_mc_usd | number | — | MC floor in USD (null clears) |
| max_mc_usd | number | — | MC ceiling in USD (null clears) |
{
"rule": {
"id": "c1a2e0f4-...-e9",
"min_kols": 5,
"min_score": 40,
"is_active": false,
"updated_at": "2026-06-02T10:00:00Z"
}
}/kol/coordination/alerts/{id}PRO/ULTRAPermanently delete a coordination alert rule. Returns 404 if not found or not owned by the caller. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| id | string (UUID) | required | Rule ID — path parameter |
{
"deleted": true
}Deployer Hunter
Tier-graded deployers, real-time launch alerts, bonding history, multiplier stats.
/deployer-hunter/statsGlobal deployer hunter statistics: tracked deployer count, signals today, bond rate, and tier distribution (elite/good/rising). Available to all tiers.
{
"tracked_count": 6717,
"signals_today": 42,
"bonds_detected": 1893,
"bond_rate": 28.2,
"tiers": {
"elite": 20,
"good": 62,
"rising": 119
}
}/deployer-hunter/leaderboardRanked list of deployers by bonding rate, recent performance, or total bonds. Full pagination and complete wallet addresses on all tiers.
| Name | Type | Default | Description |
|---|---|---|---|
| tier | string | — | Filter: "elite", "good", "moderate", "rising", or "cold" |
| sort | string | bonding_rate | Sort: "bonding_rate", "recent_bond_rate", "total_bonded", "last_deploy_at" |
| limit | integer | 20 | Max results (1-50) |
| offset | integer | 0 | Pagination offset |
{
"deployers": [
{
"wallet_address": "7xKv...9mPQ",
"tier": "elite",
"total_tokens_deployed": 18,
"total_bonded": 12,
"bonding_rate": 66.7,
"recent_bond_rate": 80,
"recent_outcomes": "BBBDBBBDBB"
}
],
"total": 20,
"limit": 20,
"offset": 0
}/deployer-hunter/{wallet}Full deployer profile with stats, tier classification, outcome history, and Pump.fun token data.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | Solana wallet address of the deployer |
{
"deployer": {
"wallet_address": "7xKv...9mPQ",
"tier": "elite",
"total_tokens_deployed": 18,
"total_bonded": 12,
"bonding_rate": 66.7,
"recent_outcomes": "BBBDBBBDBB"
},
"pump_tokens": [
{
"mint": "abc1...pump",
"name": "Token A",
"symbol": "TOKA",
"bondingCurvePercentage": 100
}
]
}/deployer-hunter/{wallet}/tokensPaginated token history for a deployer with peak market cap and bond timing.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | Solana wallet address |
| limit | integer | 20 | Max results (1-50) |
| offset | integer | 0 | Pagination offset |
{
"tokens": [
{
"token_mint": "abc1...pump",
"token_name": "Token A",
"token_symbol": "TOKA",
"deployed_at": "2026-03-20T12:00:00Z",
"bonded_at": "2026-03-20T12:45:00Z",
"time_to_bond_minutes": 45,
"peak_market_cap": 285000
}
],
"total": 12,
"limit": 20,
"offset": 0
}/deployer-hunter/alertsReal-time alerts when tracked deployers launch new tokens. Enriched with deployer reputation (tier, best_token_peak_mc), the deployer's SOL balance at alert time (`deployer_sol_balance`, null for alerts before 2026-06-21), and KOL buy cross-reference. Cursor-paginated via `before` (preferred over `offset` at scale). Up to 50 results per call on BASIC/PRO; ULTRA unlocks full pagination.
| Name | Type | Default | Description |
|---|---|---|---|
| since | ISO datetime | — | Only alerts after this timestamp |
| before | ISO datetime | — | Cursor — only alerts strictly older than this timestamp. Pass `next_before` from previous response. |
| limit | integer | 20 | Max results (1-50) |
| offset | integer | 0 | Legacy offset pagination (prefer `before` for polling) |
| tier | string | — | Filter by deployer tier: elite, good, moderate, rising, or cold. |
| alert_type | string | — | Filter by alert_type (e.g. new_deploy, bonded) |
| priority | string | — | "high", "medium", or "low" |
| min_kol_buys | integer | — | Only alerts where at least N KOLs bought (1-100) |
| token_mint | string | — | Scope to one token's alert history — combine with alert_type=bonded to check if/when a specific token bonded |
{
"alerts": [
{
"token_mint": "def2...pump",
"token_name": "New Token",
"deployer_wallet": "7xKv...9mPQ",
"deployer_tier": "elite",
"deployer_sol_balance": 42.5301,
"alert_type": "new_deploy",
"created_at": "2026-03-28T14:30:00Z",
"kol_buys": [
{
"kol_name": "Cented",
"sol_amount": 5.2,
"bought_at": "2026-03-28T14:31:12Z"
}
]
}
],
"limit": 20,
"offset": 0
}/deployer-hunter/alert-statsAlert performance metrics: bond rate, multiplier distribution (% hitting 2x, 5x, 10x, 50x), and per-tier breakdown.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | all | Time period: "7d", "30d", or "all" |
{
"period": "all",
"total_alerts": 1247,
"total_bonded": 352,
"bond_rate": 28.2,
"multiplier_distribution": {
"2x": 65.3,
"5x": 41.2,
"10x": 22.7,
"50x": 4.8
},
"by_tier": {
"elite": {
"alerts": 89,
"bonded": 26,
"bond_rate": 29.2
},
"good": {
"alerts": 412,
"bonded": 98,
"bond_rate": 23.8
}
}
}/deployer-hunter/best-tokensTop tokens by market cap multiplier from deployer alerts. See which alerted tokens performed best. Up to 20 results.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 7d | Time period: "7d", "30d", or "all" |
| limit | integer | 5 | Max results (1-20) |
{
"tokens": [
{
"token_mint": "ghi3...pump",
"token_name": "Moon Token",
"mc_at_alert": 5000,
"peak_market_cap": 750000,
"mc_multiplier": 150,
"deployer_tier": "elite"
}
],
"period": "7d",
"limit": 5
}/deployer-hunter/recent-bondsLatest tokens that graduated the Pump.fun bonding curve with deployer info. Use `since` for incremental polling — response returns `next_since` cursor.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 20 | Max results (1-50) |
| since | ISO datetime | — | Only bonds strictly newer than this timestamp. Pass `next_since` from the previous response to avoid re-fetching the same rows. |
| tier | string | — | Filter by deployer tier: elite, good, moderate, rising, or cold |
| peak_mc_min | integer | — | Only bonds that reached at least this peak market cap (USD) |
{
"tokens": [
{
"token_mint": "jkl4...pump",
"token_name": "Bonded Token",
"token_symbol": "BOND",
"bonded_at": "2026-03-28T13:15:00Z",
"time_to_bond_minutes": 23,
"peak_market_cap": 420000,
"deployers": {
"wallet_address": "7xKv...9mPQ",
"tier": "elite",
"bonding_rate": 66.7
}
}
],
"limit": 20
}/deployer-hunter/{wallet}/trajectoryDeployer skill curve showing performance evolution over time. Current and longest streaks, rolling 10-token bond rate windows, improvement trend, deployment cadence, and recovery speed.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string | — | Deployer wallet address (base58, path param) |
{
"deployer": {
"wallet_address": "7xKv...9mPQ",
"total_tokens_deployed": 45,
"bonding_rate": 0.267,
"recent_bond_rate": 0.4,
"tier": "good"
},
"trajectory": {
"current_streak": {
"type": "bond",
"count": 3
},
"longest_bond_streak": 5,
"longest_fail_streak": 8,
"trend": "improving",
"avg_days_between_deploys": 2.3,
"avg_recovery_tokens": 3.1,
"total_tokens_analyzed": 45
}
}/deployer-hunter/{wallet}/historyPRO/ULTRAA deployer's daily reputation time-series — one snapshot per day of how their stats looked AT THAT POINT, so you can backtest "was this deployer elite at the time it launched token X?" without look-ahead bias. Each snapshot carries the tier, tracking status, cumulative totals, and bond rates the deployer had on that date, letting you reconstruct their reputation as it actually was rather than as it looks today after later launches. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | Deployer wallet address (base58) |
| limit | integer | 90 | Number of daily snapshots to return, most recent first (1-365) |
{
"is_deployer": true,
"wallet": "7xKv...9mPQ",
"snapshots": [
{
"date": "2026-07-05",
"tier": "elite",
"is_tracked": true,
"total_deployed": 18,
"total_bonded": 12,
"bonding_rate": 0.667,
"recent_bond_rate": 0.7,
"avg_peak_mc": 312000,
"best_token_peak_mc": 750000
},
{
"date": "2026-07-04",
"tier": "good",
"is_tracked": true,
"total_deployed": 17,
"total_bonded": 11,
"bonding_rate": 0.647,
"recent_bond_rate": 0.6,
"avg_peak_mc": 298000,
"best_token_peak_mc": 750000
}
]
}Alpha Wallets
Scored from 1.2M+ wallets that bought Pump.fun tokens within the first 20 buyers.
/alpha/leaderboardLeaderboard of statistically profitable wallets scored from 1.2M+ early buyers tracked across Pump.fun tokens. Returns wallets ranked by win rate, realized PnL, or ROI. Bot wallets can be excluded. Up to 100 results on BASIC/PRO; ULTRA unlocks 500 results + behavioral signals (bot_confidence, bundle_rate, buy_size_stddev, active_hours).
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | all | Time period: "7d", "30d", or "all" |
| min_tokens | integer | 5 | Minimum tokens traded to qualify (1–20) |
| sort | string | win_rate | Sort by: "win_rate", "pnl", or "roi" |
| exclude_bots | boolean | true | Exclude medium/high bot-confidence wallets |
{
"leaderboard": [
{
"rank": 1,
"wallet": "7xKv...9mPQ",
"tokens_traded": 12,
"wins": 9,
"losses": 3,
"win_rate": 0.75,
"net_pnl_sol": 42.3,
"total_sol_bought": 95,
"total_sol_sold": 137.3,
"roi": 0.445,
"last_seen": "2026-04-10T14:22:00Z"
}
],
"total": 1,
"period": "all",
"sort": "win_rate",
"min_tokens": 5,
"exclude_bots": true
}/alpha/{wallet}ULTRAFull alpha profile for a single wallet. Returns per-token trade breakdown from early buyer data, aggregate stats, and a bot_signals array explaining the confidence rating (signals that triggered the classification). ULTRA only — BASIC/PRO receive HTTP 403.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | Solana wallet address (base58) |
{
"wallet": "7xKv...9mPQ",
"summary": {
"tokens_traded": 12,
"wins": 9,
"losses": 3,
"win_rate": 0.75,
"net_pnl_sol": 42.3,
"bundle_rate": 0.08,
"buy_size_stddev": 0.12,
"active_hours": 14,
"bot_confidence": "low"
},
"positions": [
{
"token_symbol": "BONK",
"pnl_sol": 18.4,
"roi_pct": 92,
"result": "win",
"first_buy_at": "2026-04-01T08:00:00Z"
}
],
"bot_signals": [
{
"signal": "consistent_buy_size",
"detail": "stddev=0.12 SOL — not fixed-amount"
}
]
}/alpha/{wallet}/linkedULTRAFind wallets behaviorally linked to a target wallet — these are wallets that co-bought 3+ of the same tokens within a 2-second window. Likely the same actor split across wallets, or a coordinated group. Returns similarity scores. ULTRA only — BASIC/PRO receive HTTP 403.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | Solana wallet address (base58) |
{
"wallet": "7xKv...9mPQ",
"linked_wallets": [
{
"wallet_address": "CDiw...XsT9",
"shared_tokens": 9,
"similarity_score": 0.81
},
{
"wallet_address": "65NR...oh7B",
"shared_tokens": 5,
"similarity_score": 0.45
}
],
"total": 2
}/tokens/{mint}/kol-consensusAggregated KOL consensus view for a token mint — how many KOLs are accumulating vs distributing, net SOL flow, conviction score, and per-KOL stance breakdown. Useful for gauging whether smart money is bullish or bearish on a specific token right now.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Solana token mint address (base58) |
{
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"consensus": {
"accumulating_kols": 7,
"distributing_kols": 2,
"net_sol_flow": 47.82,
"conviction_score": 78,
"signal": "accumulating"
},
"kols": [
{
"name": "Cented",
"stance": "accumulating",
"net_sol": 12.4
},
{
"name": "Marcell",
"stance": "accumulating",
"net_sol": 8.7
}
]
}/tokens/{mint}/peak-historyHistorical peak market cap snapshots for a token — ATH market cap, timestamps of each peak, drawdown from ATH, and recovery windows. Useful for gauging whether a token has already peaked or is re-approaching highs. Shows the full MC trajectory from first-seen to present.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Solana token mint address (base58) |
{
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"ath_mc_usd": 750000,
"ath_at": "2026-05-18T14:22:00Z",
"current_mc_usd": 423000,
"drawdown_from_ath_pct": 43.6,
"peaks": [
{
"mc_usd": 285000,
"peaked_at": "2026-05-15T08:00:00Z",
"drawdown_pct": 62
},
{
"mc_usd": 750000,
"peaked_at": "2026-05-18T14:22:00Z",
"drawdown_pct": 43.6
}
],
"first_seen_at": "2026-05-14T10:00:00Z"
}/tokens/{mint}/cap-tableFirst 10–20 non-deployer early buyers for a token mint, enriched with historical win rates, realized PnL, bot confidence, KOL identity, and bundle flags. Each buyer also carries their in-token exit/PnL: realized_pnl_sol (SOL profit taken on this mint), total_sol_bought / total_sol_sold, first_sell_at (null if never sold), and still_holding — so you can see which smart-money buyers have already cashed out vs are still in. Includes a summary block with buyer_quality_score. PRO: top 10 with full wallets. ULTRA: top 20 with full wallets.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
{
"mint": "EPjF...Dt1v",
"buyers": [
{
"rank": 1,
"wallet": "7xKv...9mPQ",
"first_buy_sol": 2.5,
"first_buy_at": "2026-04-01T10:00:00Z",
"is_bundle": false,
"is_kol": true,
"kol_name": "Cented",
"bot_confidence": "low",
"historical_win_rate": 0.72,
"historical_pnl_sol": 38.4,
"historical_tokens": 15,
"realized_pnl_sol": 12.8,
"total_sol_bought": 2.5,
"total_sol_sold": 15.3,
"first_sell_at": "2026-04-01T11:42:00Z",
"still_holding": true
}
],
"summary": {
"known_alpha_wallets": 6,
"known_kols": 2,
"bundle_buyers": 1,
"buyer_quality_score": 74,
"confidence": "medium",
"signal": "positive"
}
}/tokens/{mint}/top-tradersEvery wallet that traded this mint, ranked by realized SOL PnL (or ROI) — the most profitable traders on the token, early or late. Uses the same average-cost-basis method as /wallet/{address}/pnl, so a wallet's realized_pnl_sol matches across endpoints. Each trader is enriched with reputation flags (is_kol, is_alpha_tracked, bot_confidence, historical win rate) so you can tell smart money from a bot round-trip. Distinct from cap-table (first ~20 early buyers by entry order). PRO: top 25. ULTRA: top 100.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
| limit | int | 25 | Max traders (capped at 25 PRO / 100 ULTRA) |
| sort | string | pnl | pnl | roi |
| window_days | int | 90 | Look-back window (1–180) |
| min_bought_sol | number | 0.1 | Drop dust wallets below this bought-SOL |
{
"mint": "EPjF...Dt1v",
"sort": "pnl",
"window_days": 90,
"traders": [
{
"rank": 1,
"wallet": "7xKv...9mPQ",
"trades": 14,
"buys": 6,
"sells": 8,
"bought_sol": 12.5,
"sold_sol": 41.2,
"realized_pnl_sol": 28.7,
"unrealized_pnl_sol": 3.1,
"total_pnl_sol": 31.8,
"held_value_sol": 3.1,
"roi": 2.29,
"still_holding": true,
"first_trade_at": "2026-06-01T10:00:00Z",
"last_trade_at": "2026-06-02T14:20:00Z",
"is_kol": true,
"kol_name": "Cented",
"is_alpha_tracked": true,
"bot_confidence": "low",
"historical_win_rate": 0.72,
"historical_pnl_sol": 38.4,
"historical_tokens": 15
}
],
"summary": {
"returned": 25,
"known_kols": 3,
"known_alpha_wallets": 9,
"net_realized_pnl_sol": 142.6
}
}/tokens/{mint}/bundleResolves a token's same-slot bundle cohort — the wallets that bought within a single slot at/near launch (≥3 wallets in one slot flags is_bundle) — and, critically, how much of supply that cohort still holds. Computed from confirmed token_trades, not a shred/mempool feed. The headline field is held_pct_of_supply: the cohort's net held tokens ÷ token supply, clamped to 0–1. bundle_kind is atomic_tx (all buys in one transaction), same_slot (multiple txs, one slot), or none. Caveats: buy_volume is cumulative buy volume and can exceed supply; tokens_held is a swap-derived net proxy (buys minus sells), not a holder-account census. All tiers, field-gated: BASIC gets the scalar bundle block only; PRO adds the top-10 cohort wallets with flags (held_ratio, has_sold, atomic, is_kol); ULTRA adds the full cohort plus KOL/alpha identity (kol_name, win_rate, bot_confidence, tokens_held).
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
{
"mint": "EPjF...Dt1v",
"bundle": {
"wallet_count": 5,
"bundle_kind": "same_slot",
"held_ratio": 0.32,
"held_pct_of_supply": 0.28,
"fully_exited": false,
"buy_volume": 41800000,
"tokens_held": 280000000
},
"wallets": [
{
"rank": 1,
"wallet": "7xKv...9mPQ",
"held_ratio": 0.71,
"has_sold": false,
"atomic": true,
"is_kol": true,
"kol_name": "Cented",
"win_rate": 0.68,
"bot_confidence": "low",
"tokens_held": 120000000
},
{
"rank": 2,
"wallet": "3nQd...42aa",
"held_ratio": 0,
"has_sold": true,
"atomic": true,
"is_kol": false,
"kol_name": null,
"win_rate": null,
"bot_confidence": "high",
"tokens_held": 0
}
]
}/tokens/{mint}/buyer-quality0–100 buyer quality score for a token's early-buyer cohort. Score formula: average win rate of non-bot early buyers × 100, plus KOL bonus (first KOL = +10, each extra = +5, max +20), minus bundle penalties (−5 per bundled buyer in top 10, −15 if >10/20 are bundles), minus bot domination (−20 if >50% are high-confidence bots). Returns score, confidence, signal, and full breakdown (alpha_wallet_count, kol_count, bundle_buyer_count, avg_historical_win_rate, bot_dominated, dump_cluster_count, recycled_early_buyer_count). dump_cluster_count = first-20 buyers on the rolling dump-cluster list (wallets whose recent first-20 appearances are exclusively on tokens that peaked <15 min after deploy — out-of-sample, 3+ such wallets predicted a sub-15-min peak 94% of the time vs 61% base). recycled_early_buyer_count = first-20 buyers with 5+ recent first-20 appearances of any kind; a heavily recycled cohort with dump_cluster_count 0 historically leans the other way. Informational fields — they do not move the score. List refreshes daily over a trailing 42-day window. Results cached 5 minutes per mint. For bulk scoring use POST /tokens/batch/buyer-quality.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
{
"mint": "EPjF...Dt1v",
"score": 74,
"confidence": "medium",
"signal": "positive",
"cached_at": "2026-04-14T12:00:00Z",
"breakdown": {
"alpha_wallet_count": 6,
"kol_count": 2,
"bundle_buyer_count": 1,
"avg_historical_win_rate": 68.5,
"bot_dominated": false,
"dump_cluster_count": 0,
"recycled_early_buyer_count": 4
}
}/tokens/{mint}/riskPRO/ULTRATransparent 0–100 rug-risk score for a token mint, with a full per-factor breakdown so the score is auditable — not an opaque verdict. Higher = riskier. Returns risk_score, band (safe / caution / danger), factors[] (each with key, label, status, points, and a human-readable detail — including supply_inflation, which flags when on-chain supply has grown above the expected amount, i.e. post-launch minting), the raw inputs the score was computed from, and score_version. inputs.sniper_footprint is the slot-window snipe rollup (slots deploy−1 to deploy+3): buys, buyers, SOL, supply_pct, sniper_wallet_buys, data_available, as_of — informational, it does not move the score, and data_available: false means the mint is outside our capture window, not zero snipes. The top-level dev block is the deployer self-activity read: the dev's exact self-buy in the create transaction (buy_sol / buy_tokens / buy_supply_pct), post-create buys and sells on their own mint (bought_tokens_after, sold_tokens, sold_sol, first_sell_at / last_sell_at), and live on-chain truth — holdings_tokens / holdings_supply_pct, wallet_empty ("has the dev already exited?") and transferred_out (chain balance well below what their trades imply ⇒ tokens moved out via transfer; null when we can't assert it honestly). dev is null for mints that pre-date the deploy pipeline. Unlike a black-box safety check, every point of the score is attributed to a named factor you can inspect and weight yourself. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
{
"mint": "EPjF...Dt1v",
"risk_score": 28,
"band": "caution",
"factors": [
{
"key": "mint_authority",
"label": "Mint authority",
"status": "ok",
"points": 0,
"detail": "Mint authority revoked"
},
{
"key": "freeze_authority",
"label": "Freeze authority",
"status": "warn",
"points": 10,
"detail": "Freeze authority still active"
},
{
"key": "top_holder_concentration",
"label": "Top-holder concentration",
"status": "warn",
"points": 18,
"detail": "Top 10 holders control 41% of supply"
},
{
"key": "lp_burned",
"label": "LP burned",
"status": "ok",
"points": 0,
"detail": "Liquidity pool tokens burned"
},
{
"key": "supply_inflation",
"label": "Supply inflation",
"status": "ok",
"points": 0,
"detail": "On-chain supply matches expected — no post-launch minting"
}
],
"inputs": {
"mint_authority_revoked": true,
"freeze_authority_revoked": false,
"top10_holder_pct": 41.2,
"lp_burned": true,
"supply_inflation_pct": 0,
"sniper_footprint": {
"buys": 14,
"buyers": 9,
"sol": 12.4,
"supply_pct": 3.8,
"sniper_wallet_buys": 4,
"data_available": true,
"as_of": "2026-07-10T12:00:00Z"
}
},
"dev": {
"wallet": "4qTz...8xNb",
"launchpad": "pumpfun",
"deployed_at": "2026-07-11T09:14:02Z",
"buy_sol": 0.85,
"buy_tokens": 24183920.5,
"buy_supply_pct": 2.42,
"bought_tokens_after": 0,
"sold_tokens": 24183920.5,
"sold_sol": 1.12,
"first_sell_at": "2026-07-11T09:14:09Z",
"last_sell_at": "2026-07-11T09:14:09Z",
"holdings_tokens": 0,
"holdings_supply_pct": 0,
"wallet_empty": true,
"transferred_out": false
},
"score_version": "1.0",
"as_of": "2026-07-11T09:20:00Z"
}/tokens/{mint}/candlesPRO/ULTRATime-series OHLCV candles for a token mint, aggregated from the trade firehose into fixed buckets. Each candle carries open/high/low/close price, USD volume, trade count, and market cap at the bucket. PRO: OHLCV fields, last 30 days of history. ULTRA: adds per-candle net-flow (buy/sell volume + counts, MEV volume) and liquidity (open/close liquidity, high/low market cap) fields, plus full retained history. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
| tf | string | 1h | Timeframe: one of 1m, 5m, 15m, 1h, 4h, 1d |
| limit | number | 200 | Number of candles to return (1–1000) |
| from | string | optional | ISO8601 timestamp — only candles at or after this time |
| to | string | optional | ISO8601 timestamp — only candles at or before this time |
{
"mint": "EPjF...Dt1v",
"timeframe": "1h",
"from": "2026-06-17T00:00:00Z",
"to": "2026-06-17T02:00:00Z",
"count": 2,
"net_flow_included": true,
"candles": [
{
"t": "2026-06-17T00:00:00Z",
"open": 0.00042,
"high": 0.00051,
"low": 0.0004,
"close": 0.00048,
"volume_usd": 184200,
"trades": 1320,
"market_cap_usd": 480000,
"buy_volume_usd": 102400,
"sell_volume_usd": 81800,
"net_volume_usd": 20600,
"buy_count": 740,
"sell_count": 580,
"volume_mev_usd": 5200,
"open_liquidity_usd": 92000,
"close_liquidity_usd": 98500,
"high_mc_usd": 510000,
"low_mc_usd": 400000
},
{
"t": "2026-06-17T01:00:00Z",
"open": 0.00048,
"high": 0.00049,
"low": 0.00044,
"close": 0.00045,
"volume_usd": 96100,
"trades": 710,
"market_cap_usd": 450000,
"buy_volume_usd": 41300,
"sell_volume_usd": 54800,
"net_volume_usd": -13500,
"buy_count": 305,
"sell_count": 405,
"volume_mev_usd": 2100,
"open_liquidity_usd": 98500,
"close_liquidity_usd": 95300,
"high_mc_usd": 490000,
"low_mc_usd": 440000
}
]
}/tokens/{mint}/flowPRO/ULTRAPer-token trade-flow aggregate computed straight from the trade firehose — the organic-vs-fake-volume read for a single mint. Returns unique wallets / buyers / sellers, buy & sell counts, total trades, buy / sell / net SOL flow, and trades_per_wallet (a wash-trading proxy: a high trade count spread across very few wallets is the classic synthetic-volume tell). Counts and flows only — no holder or balance data. Read the `coverage` block first: `in_scope: false` means the mint sits outside our launchpad write-gate, so the zeros mean "not covered by our capture", NOT "no activity". PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
| window | string | 24h | Lookback window: 1h or 24h |
{
"mint": "EPjF...Dt1v",
"window": "24h",
"from": "2026-06-20T12:00:00Z",
"coverage": {
"history_start": 1775984757,
"scope": "pump.fun pipeline (pump.fun, LaunchLab/bonk, bags)",
"in_scope": true
},
"unique_wallets": 1840,
"unique_buyers": 1620,
"unique_sellers": 910,
"buy_count": 4210,
"sell_count": 2680,
"total_trades": 6890,
"buy_sol": 1284.42,
"sell_sol": 902.17,
"net_sol": 382.25,
"trades_per_wallet": 3.74
}/tokens/{mint}/tradesPRO/ULTRAEvery captured trade for one token mint, newest first — cursor-paginated raw trades, the backfill complement to the live firehose (seed history, then keep current via the stream). Each trade carries tx_signature, wallet_address, action, sol_amount, token_amount, price_sol/price_usd, early_buyer_rank, slot, and block_time. Default window is full history. The response's coverage block carries the honesty markers: capture starts 2026-04-12 and is pump.fun-pipeline scoped, and `in_scope: false` means the mint is outside our write-gate — read an empty result as "not covered by our capture", NOT "no activity". PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
| limit | integer | 100 | Trades per page (1-500) |
| cursor | string | — | From next_cursor of previous page |
| action | string | — | Filter: "buy" or "sell" |
| wallet | string | — | Filter to one wallet's trades on this token |
| since | integer | full history | Unix epoch seconds lower bound |
| until | integer | now | Unix epoch seconds upper bound |
{
"mint": "EPjF...Dt1v",
"trades": [
{
"tx_signature": "5Hyj...kMnP",
"wallet_address": "7xKv...9mPQ",
"action": "buy",
"sol_amount": 1.42,
"token_amount": 4567890.12,
"price_sol": 3.1e-7,
"price_usd": 0.0000284,
"early_buyer_rank": 7,
"slot": 305418729,
"block_time": 1747746000,
"traded_at": "2026-05-20T12:20:00Z"
}
],
"next_cursor": "MTc0Nzc0NjAwMDoxMjM0NQ==",
"has_more": true,
"filters": {
"action": null,
"wallet": null,
"since": 1775984757,
"until": 1783036800
},
"coverage": {
"history_start": 1775984757,
"scope": "pump.fun pipeline (pump.fun, LaunchLab/bonk, bags)",
"in_scope": true
}
}/tokens/{mint}/poolsPRO/ULTRAPer-venue liquidity map for a token mint — every DEX pool the token trades in (pump.fun bonding curve, PumpSwap, Raydium, Meteora, Orca), which are live vs parked (is_active), and how fragmented liquidity is across them. This is the venue-level breakdown behind the single aggregate liquidity number on /token/{mint}: use it to see whether liquidity is concentrated in one deep pool or scattered across many thin ones, and which venue is primary. Returns pools[] (pool_address, dex, quote_mint, liquidity_usd, last_price_sol, last_swap_at, amm_id, is_active) plus a summary (pool_count, active_pool_count, dex_count, dexes, total_liquidity_usd, primary_pool, primary_dex, top_pool_share_pct — the primary pool's share of total liquidity, a fragmentation read). PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
{
"mint": "EPjF...Dt1v",
"pools": [
{
"pool_address": "9WzD...aB3k",
"dex": "PumpSwap",
"quote_mint": "So11...1112",
"liquidity_usd": 184200,
"last_price_sol": 4.2e-7,
"last_swap_at": "2026-07-05T11:58:00Z",
"amm_id": "pAMM...4xQ",
"is_active": true
},
{
"pool_address": "3nQd...42aa",
"dex": "Raydium",
"quote_mint": "So11...1112",
"liquidity_usd": 41800,
"last_price_sol": 4.1e-7,
"last_swap_at": "2026-07-05T11:41:00Z",
"amm_id": "675k...RB8",
"is_active": true
},
{
"pool_address": "7xKv...9mPQ",
"dex": "pump.fun",
"quote_mint": "So11...1112",
"liquidity_usd": 0,
"last_price_sol": 3.9e-7,
"last_swap_at": "2026-07-01T08:12:00Z",
"amm_id": null,
"is_active": false
}
],
"summary": {
"pool_count": 3,
"active_pool_count": 2,
"dex_count": 3,
"dexes": [
"PumpSwap",
"Raydium",
"pump.fun"
],
"total_liquidity_usd": 226000,
"primary_pool": "9WzD...aB3k",
"primary_dex": "PumpSwap",
"top_pool_share_pct": 81.5
}
}/tokens/{mint}/depthPRO/ULTRAPer-pool price-impact and slippage for a token mint — "how much SOL does it take to move the price N%", and what each buy size actually costs. For every pool: spot_price_sol, quotes[] per requested SOL size (tokens_out, avg_price_sol, price_impact_pct) and to_move_price (SOL required to move price 1% / 5% / 10%). Exact for constant-product AMMs (PumpSwap, Raydium v4/CPMM, Meteora DAMM — computed from our streamed reserves, zero RPC) and correct for pump.fun / bonk bonding curves via one live read of the curve's virtual reserves (source: "live_rpc"). Honesty markers: impact is per-pool, not router-optimal; concentrated-liquidity pools (Raydium CLMM, Orca, Meteora DLMM) and unclassified pools are listed under unsupported_pools with a reason instead of returning a wrong number. A sharper liquidity-quality read than raw liquidity_usd — the data a bot needs to size entries. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | string (path) | required | Token mint address (base58) |
| sizes | string | 0.5,1,5,10 | Comma-separated SOL buy sizes to quote (max 8, each ≤ 10000) |
{
"mint": "EPjF...Dt1v",
"found": true,
"sol_usd": 178.42,
"sizes_sol": [
0.5,
1,
5
],
"primary_pool": "9WzD...aB3k",
"pools": [
{
"pool_address": "9WzD...aB3k",
"dex": "pumpswap",
"quote_mint": "So11...1112",
"pool_model": "constant_product",
"liquidity_usd": 184200,
"is_active": true,
"depth_available": true,
"model": "constant_product",
"fee_pct": 0.25,
"source": "stream",
"reserves_age_ms": 1840,
"spot_price_sol": 4.2e-7,
"quotes": [
{
"size_sol": 0.5,
"tokens_out": 1180212.4,
"avg_price_sol": 4.24e-7,
"price_impact_pct": 0.19
},
{
"size_sol": 1,
"tokens_out": 2352114.8,
"avg_price_sol": 4.25e-7,
"price_impact_pct": 0.39
},
{
"size_sol": 5,
"tokens_out": 11548020.1,
"avg_price_sol": 4.33e-7,
"price_impact_pct": 1.97
}
],
"to_move_price": {
"1pct": 2.55,
"5pct": 12.61,
"10pct": 24.87
}
}
],
"unsupported_pools": [
{
"pool_address": "5rTe...2wQx",
"dex": "raydium_clmm",
"quote_mint": "So11...1112",
"pool_model": "concentrated",
"liquidity_usd": 22100,
"is_active": true,
"reason": "concentrated_liquidity_depth_not_supported"
}
],
"note": "Impact is per-pool (not router-optimal). Constant-product served from stream reserves; pump.fun/bonk from live virtual reserves."
}/tokens/batch/buyer-qualityBulk scoring for up to 50 mints. Shares the same 5-minute LRU cache as the single-mint endpoint — already-warm mints return at near-zero cost. Response includes a `cache_hits` counter so you can see how many were served from cache.
| Name | Type | Default | Description |
|---|---|---|---|
| body | JSON | required | { "mints": ["...", "..."] } — 1 to 50 base58 Solana token mints |
{
"tokens": [
{
"mint": "EPjF...Dt1v",
"score": 74,
"confidence": "medium",
"signal": "positive",
"breakdown": {
"alpha_wallet_count": 6,
"kol_count": 2,
"bundle_buyer_count": 1,
"bot_dominated": false,
"dump_cluster_count": 0,
"recycled_early_buyer_count": 4
}
},
{
"mint": "So11...1112",
"score": 50,
"confidence": "low",
"signal": "neutral",
"breakdown": {
"alpha_wallet_count": 0,
"kol_count": 0,
"bundle_buyer_count": 0,
"bot_dominated": false,
"dump_cluster_count": 0,
"recycled_early_buyer_count": 0
}
}
],
"count": 2,
"cache_hits": 1
}/signals/{name}/performanceLive, out-of-sample backtest for an enrichment signal so bots can weight it programmatically instead of guessing. Returns per-bucket hit rate, base rate, and lift over base. `?history=true` adds the per-day series for drift. Open to any authenticated tier — aggregate, non-sensitive efficacy data.
| Name | Type | Default | Description |
|---|---|---|---|
| name | string | required | Signal name (path): dump_cluster_count, runner_rate, or recycled_early_buyer_count |
| history | boolean | false | Include the per-day snapshot series (up to 90 days) for drift tracking |
{
"signal": "dump_cluster_count",
"metric_type": "count",
"outcome": "dumped",
"window_days": 14,
"base_rate": 0.75,
"test_from": "2026-05-28",
"test_to": "2026-06-11",
"as_of": "2026-06-11T03:50:00Z",
"methodology": "Out-of-sample: rolling train/test split, >=15 early-buyer filter, peak-timing labels (<15min=dump / >=60min=runner), no lookahead.",
"buckets": [
{
"bucket": "0",
"hit_rate": 0.71,
"base_rate": 0.75,
"lift": 0.95,
"sample_n": 4210
},
{
"bucket": ">=8",
"hit_rate": 0.98,
"base_rate": 0.75,
"lift": 1.31,
"sample_n": 190
}
]
}Tools
1,160+ tools indexed across the Solana ecosystem.
/tools/searchSearch across 1,160+ Solana tools by name, tagline, or category. Returns ratings, health scores, pricing, and direct links.
| Name | Type | Default | Description |
|---|---|---|---|
| q | string | — | Search query (2-200 characters) |
| category | string | — | Filter by category slug (e.g. trading-bots, dex, analytics) |
| limit | integer | 20 | Max results (1-50) |
{
"tools": [
{
"name": "Jupiter",
"slug": "jupiter",
"tagline": "The best swap aggregator on Solana",
"average_rating": 4.8,
"review_count": 12,
"pricing_model": "free",
"health_score": 100,
"categories": [
"dex"
],
"url": "https://madeonsol.com/tools/jupiter"
}
],
"count": 1
}/token/{mint}Comprehensive token data in one call: real-time VWAP price from our DEX trade stream, market cap, 24h volume, **velocity deltas** (`mc_change_pct`, `volume_usd`, `mev_volume_pct` across 5m/15m/1h/2h/4h windows), deployer reputation, KOL smart money flow (including top buyers by SOL volume), `first_seen_at` + `age_seconds` (from our indexer), and `is_blacklisted` + `blacklist_category` (stablecoin / wrapped_sol / lst / rug-flagged). The `mev_volume_pct` field — unique to MadeOnSol — surfaces the % of each window's volume tagged as sandwich/Jito-bundle MEV, so traders can flag wash-pump patterns where headline volume is bot-driven rather than organic demand. All data self-hosted — no external API dependencies. ULTRA adds individual KOL wallet addresses in the top-buyer list. For bulk lookups use POST /token/batch.
| Name | Type | Default | Description |
|---|---|---|---|
| mint | path | required | Token mint address (base58) |
{
"token": {
"mint": "CYTUg8qLd45EGbx7MXxSwR5PSMNoUck5SetxxSDHpump",
"price_usd": 0.001024,
"price_sol": 0.0000136,
"market_cap": 1024000,
"volume_24h_usd": 4858,
"volume_24h_sol": 46.17,
"trades_24h": 71,
"last_trade_at": "2026-04-06T14:50:00Z",
"first_seen_at": "2026-04-03T08:12:44Z",
"age_seconds": 276136,
"is_blacklisted": false,
"blacklist_category": null,
"mc_change_pct": {
"5m": 8.2,
"15m": 31.4,
"1h": 62.1,
"2h": 75,
"4h": 87
},
"volume_usd": {
"5m": 42000,
"15m": 118000,
"1h": 340000,
"2h": 500000,
"4h": 920000
},
"mev_volume_pct": {
"5m": 18.4,
"15m": 22.1,
"1h": 27.3,
"2h": 31.8,
"4h": 34.2
},
"history_age_seconds": 14400,
"deployer": {
"wallet": "6vxo...5UhE",
"tier": "rising",
"bonding_rate": 0.5,
"total_deployed": 2,
"total_bonded": 1
},
"kol_activity": {
"buying_kols": 14,
"selling_kols": 18,
"net_flow_sol": -228.52,
"signal": "distributing",
"top_buyers": [
{
"name": "Scharo",
"sol_amount": 65.69
}
]
},
"liquidity_to_mc_ratio": 0.0278,
"launch_cohort_sol": 12.45,
"launch_cohort_size": 18
}
}/token/batchBulk lookup of up to 50 mints in a single request. Returns the same per-mint shape as `GET /token/{mint}` — including the full velocity / volume / MEV-share deltas across 5m/15m/1h/2h/4h windows. DB queries batched with `IN (...)`; dex-stream + RPC supply fan-outs run in parallel — ~10-20× cheaper than N sequential single-mint calls. Ideal for sniper pipelines and dashboards scoring many tokens at once.
| Name | Type | Default | Description |
|---|---|---|---|
| body | JSON | required | { "mints": ["...", "..."] } — 1 to 50 base58 Solana token mints |
{
"tokens": [
{
"mint": "CYTUg8qLd45EGbx7MXxSwR5PSMNoUck5SetxxSDHpump",
"price_usd": 0.001024,
"market_cap": 1024000,
"age_seconds": 276136,
"is_blacklisted": false,
"mc_change_pct": {
"5m": 8.2,
"1h": 62.1,
"4h": 87
},
"volume_usd": {
"5m": 42000,
"1h": 340000,
"4h": 920000
},
"mev_volume_pct": {
"5m": 18.4,
"1h": 27.3,
"4h": 34.2
},
"deployer": {
"tier": "rising",
"bonding_rate": 0.5
},
"kol_activity": {
"buying_kols": 14,
"signal": "distributing"
},
"liquidity_to_mc_ratio": 0.0278,
"launch_cohort_sol": 12.45,
"launch_cohort_size": 18
}
],
"count": 2
}/statusPublic system health endpoint. Seven core services are monitored: kol_tracker, deployer_listener, nextjs_app, supabase_db, websocket, rhc_node_sync and rhc_trades_freshness (the last two cover Robinhood Chain). Returns per-service status, uptime percentages and stream lag. `slo_target_pct` is our published availability TARGET, not a measurement of the current period — compare it against the `uptime` block, which is the measured figure. No authentication required. Checks run every 5 minutes.
{
"status": "operational",
"services": {
"kol_tracker": {
"status": "healthy",
"last_trade_age_s": 5
},
"deployer_listener": {
"status": "healthy"
},
"nextjs_app": {
"status": "healthy",
"response_ms": 41
},
"supabase_db": {
"status": "healthy",
"response_ms": 3
},
"websocket": {
"status": "healthy"
},
"rhc_node_sync": {
"status": "healthy",
"block_lag": 2
},
"rhc_trades_freshness": {
"status": "healthy",
"last_trade_age_s": 11
}
},
"uptime": {
"last_24h": 99.5,
"last_7d": 99.8
},
"slo_target_pct": 99.5,
"slo_note": "slo_target_pct is a target, not a measurement — the measured figures are in `uptime`.",
"checked_at": "2026-04-06T15:00:00Z"
}/meInspect your tier, daily/burst quota state, subscription expiry, and per-feature usage. `features` carries all 11 keys: webhooks, ws_connections, dex_connections, copytrade_wallets, copytrade_rules, coordination_rules, first_touch_subscriptions, price_alerts, rhc_copytrade_rules, wallet_tracker_watchlist, rhc_wallet_tracker_watchlist. Robinhood Chain quotas are PER CHAIN — the rhc_* keys are separate budgets that never eat into their Solana counterparts. Reads from the same in-memory counters that drive rate-limit enforcement, so `quota.daily.remaining` is authoritative — no header parsing. Available to every authenticated tier; useful for self-throttling and quota-aware retry logic.
{
"subscriber": "9189666b-0b8f-4606-b39d-a6a52918c587",
"tier": "PRO",
"tier_label": "Pro",
"subscription": {
"status": "active",
"billing_cycle": "monthly",
"current_period_end": "2026-06-12T10:00:00Z",
"started_at": "2026-04-12T10:00:00Z"
},
"quota": {
"daily": {
"limit": 10000,
"used": 3427,
"remaining": 6573,
"resets_at": "2026-05-13T00:00:00Z"
},
"burst": {
"limit": 120,
"used": 14,
"remaining": 106,
"window_seconds": 60
}
},
"features": {
"webhooks": {
"limit": 3,
"used": 1
},
"ws_connections": {
"limit": 1
},
"dex_connections": {
"limit": 0
},
"copytrade_wallets": {
"limit": 5,
"used": 2
},
"copytrade_rules": {
"limit": 3,
"used": 1
},
"coordination_rules": {
"limit": 5,
"used": 1
},
"first_touch_subscriptions": {
"limit": 0,
"used": 0
},
"price_alerts": {
"limit": 5,
"used": 2
},
"rhc_copytrade_rules": {
"limit": 3,
"used": 0
},
"wallet_tracker_watchlist": {
"used": 12
},
"rhc_wallet_tracker_watchlist": {
"used": 4
}
}
}/tokensPRO+Filtered, sortable token directory. Complements `/token/{mint}` (single lookup) and the KOL-scoped `/kol/tokens/{hot,trending}`. Server-side filters: `min_mc`, `max_mc`, `min_liq` (**default 2000** — set 0 to disable phantom-MC dust floor), `active_h`, `primary_dex` (pumpfun/pumpswap/raydium/meteora/orca/raydium_clmm), `authority_revoked`, `exclude_token2022`, `lp_burned`. Computed post-filters (over-fetches 3×): `min_volume_1h_usd`, `max_mev_share_pct`, `mc_change_1h_min_pct`, `mc_change_1h_max_pct`. **Trending / momentum sorts** (PRO/ULTRA): `mc_change_5m_desc`, `mc_change_1h_desc`, `volume_1h_desc`, and `trending` (recent volume × momentum) turn the directory into a reputation-aware momentum board — combine with `deployer_tier` and `max_mev_share_pct` for clean-volume movers from trusted deployers. Full sort set: `mc_desc` | `mc_asc` | `last_trade_desc` | `liquidity_desc` | `cumulative_volume_desc` | `mc_change_5m_desc` | `mc_change_1h_desc` | `volume_1h_desc` | `trending`. Pagination includes `post_filtered: true` so clients can detect when computed filters trim a page below `limit`.
| Name | Type | Default | Description |
|---|---|---|---|
| min_mc | query | — | Minimum market_cap_usd |
| max_mc | query | — | Maximum market_cap_usd |
| min_liq | query | 2000 | Minimum liquidity_usd. Set 0 to disable the default dust floor. |
| active_h | query | — | Only tokens traded within the last N hours (0.1–168) |
| primary_dex | query | — | pumpfun | pumpswap | raydium | meteora | orca | raydium_clmm |
| authority_revoked | query | — | true = both mint + freeze revoked; false = at least one not revoked |
| exclude_token2022 | query | false | Drop Token-2022 mints (common transfer-fee scam vector) |
| lp_burned | query | — | true = LP burn detected (rug-protection signal) |
| min_volume_1h_usd | query | — | Computed organic-volume floor (post-filter) |
| max_mev_share_pct | query | — | Computed MEV/bot volume ceiling % (post-filter) |
| mc_change_1h_min_pct | query | — | Computed minimum 1h MC change % (post-filter; momentum scans) |
| mc_change_1h_max_pct | query | — | Computed maximum 1h MC change % (post-filter; dip scans) |
| min_liq_mc_ratio | query | — | Minimum liquidity-to-MC ratio (liquidity_usd / market_cap_usd) |
| max_liq_mc_ratio | query | — | Maximum liquidity-to-MC ratio (liquidity_usd / market_cap_usd) |
| deployer_tier | query | — | Filter by deployer tier: elite | good | moderate | rising | cold | unranked |
| sort | query | mc_desc | mc_desc | mc_asc | last_trade_desc | liquidity_desc | cumulative_volume_desc | mc_change_5m_desc | mc_change_1h_desc | volume_1h_desc | trending (last four are momentum sorts, PRO/ULTRA) |
| limit | query | 50 | 1–100 |
| offset | query | 0 | 0–10000 |
{
"tokens": [
{
"mint": "CYTUg8qLd45EGbx7MXxSwR5PSMNoUck5SetxxSDHpump",
"symbol": "ALPHA",
"name": "Alpha Coin",
"price_usd": 0.001024,
"market_cap_usd": 1024000,
"fdv_usd": 1024000,
"liquidity_usd": 28430,
"primary_dex": "raydium",
"authorities_revoked": true,
"lp_burned": true,
"is_token_2022": false,
"last_trade_time": "2026-05-12T17:15:05Z",
"mc_change_5m_pct": 4.2,
"mc_change_1h_pct": 31.8,
"organic_volume_1h_usd": 12480,
"mev_share_pct": 18.4,
"liquidity_to_mc_ratio": 0.0278,
"deployer_tier": "elite"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"returned": 50,
"has_more": true,
"post_filtered": false
},
"filters": {
"min_liq": 2000,
"min_liq_default_applied": true,
"sort": "mc_desc"
}
}/tokens/almost-bondedPRO+Pre-bond pump.fun tokens approaching graduation — catch them *before* they bond. Each token carries its live bonding-curve `progress_pct` (from on-chain `real_token_reserves` depletion) and, uniquely, its **velocity** (`velocity_pct_per_min` = Δprogress/min) plus a linear `eta_minutes` projection — so "95% and accelerating" ranks above "92% stalled". Enriched with deployer reputation (`deployer_tier`) from our deployer-hunter graph, so you can filter to elite/good deployers only. Defaults to the 80–99.99% band, already-bonded tokens excluded. Self-hosted from our firehose — no external API.
| Name | Type | Default | Description |
|---|---|---|---|
| min_progress | query | 80 | Minimum bonding-curve progress % (0–100) |
| max_progress | query | 99.99 | Maximum bonding-curve progress % (< 100; bonded tokens always excluded) |
| min_velocity_pct_per_min | query | — | Minimum Δprogress/min — drops tokens without a 5m snapshot when set |
| max_age_minutes | query | — | Only tokens deployed within the last N minutes (≥1) |
| deployer_tier | query | — | elite | good | moderate | rising | cold | unranked |
| authority_revoked | query | — | true = both mint + freeze revoked |
| min_liq | query | — | Minimum liquidity_usd |
| sort | query | velocity_desc | velocity_desc | progress_desc | eta_asc |
| limit | query | 50 | 1–100 |
{
"tokens": [
{
"mint": "8xKv9aK2rFy1mPQ...pump",
"symbol": "MOON",
"name": "Moon Soon",
"progress_pct": 96.4,
"velocity_pct_per_min": 1.82,
"eta_minutes": 2,
"stalled": false,
"real_sol_reserves": 78.3,
"market_cap_usd": 61200,
"liquidity_usd": 24100,
"authorities_revoked": true,
"deployer_tier": "elite",
"age_minutes": 14
}
],
"filters": {
"min_progress": 80,
"max_progress": 99.99,
"deployer_tier": null,
"sort": "velocity_desc"
},
"returned": 1,
"note": "Pre-bond pump.fun tokens. velocity = Δprogress/min (null until a 5m snapshot exists). eta_minutes is a linear projection from current velocity."
}Wallet Tracker
Up to 10 / 50 / 100 wallets by tier. Events stored 120 days. ULTRA gets the WS push channel. Robinhood Chain has its own watchlist at /rhc/wallet-tracker/* with a separate per-chain quota.
/wallet-tracker/watchlistList all tracked wallets with labels, added_at timestamps, and remaining capacity. BASIC: 10 wallets. PRO: 50. ULTRA: 100.
{
"wallets": [
{
"wallet_address": "7xKX...3bPq",
"label": "whale #1",
"added_at": "2026-04-15T10:00:00Z"
}
],
"count": 1,
"limit": 10,
"remaining": 9
}/wallet-tracker/watchlistAdd a Solana wallet to your watchlist. Returns HTTP 409 if the wallet is already tracked or the tier limit is reached. BASIC: 10, PRO: 50, ULTRA: 100.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet_address | string | required | Solana wallet address (base58) |
| label | string | null | Optional human-readable label |
{
"wallet_address": "7xKX...3bPq",
"label": "whale #1",
"added_at": "2026-04-15T10:00:00Z",
"remaining": 9
}/wallet-tracker/watchlist/{address}Remove a wallet from your watchlist. Returns 404 if not found.
| Name | Type | Default | Description |
|---|---|---|---|
| address | path | required | Solana wallet address (base58) |
{
"success": true
}/wallet-tracker/watchlist/{address}Update the label for a tracked wallet. Pass null to clear the label.
| Name | Type | Default | Description |
|---|---|---|---|
| address | path | required | Solana wallet address (base58) |
| label | string | null | required | New label or null to clear |
{
"wallet_address": "7xKX...3bPq",
"label": "renamed whale",
"added_at": "2026-04-15T10:00:00Z"
}/wallet-tracker/tradesHistorical swap and transfer events across all your watched wallets. Swaps = token trades (buy/sell). Transfers = SOL moved without a token change. Full wallets, counterparties, and tx_signatures on all tiers. Retention: 120 days.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string | — | Filter to a specific wallet address |
| action | string | — | Filter by action: buy, sell, transfer_in, transfer_out |
| event_type | string | — | Filter by event type: swap or transfer |
| limit | integer | 50 | Max results (1–200) |
| before | integer | — | Pagination cursor: block_time of the last event from the previous page |
{
"events": [
{
"id": "abc123",
"wallet_address": "7xKX...3bPq",
"label": "whale #1",
"event_type": "swap",
"action": "buy",
"block_time": 1744720800,
"block_time_iso": "2026-04-15T10:00:00Z",
"token_mint": "EPjF...fEgN",
"token_symbol": "EXAMPLE",
"sol_amount": 2.5,
"token_amount": 1000000,
"price_per_token_sol": 0.0000025,
"counterparty": "675k...TSZ",
"tx_signature": "5Hyj...kMnP",
"program": "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
}
],
"count": 1
}/wallet-tracker/summaryPer-wallet stats over a time window: swap counts, buys, sells, SOL bought/sold, last activity time.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 7d | Time window: 24h, 7d, or 30d |
| wallet | string | — | Filter to a specific wallet address |
{
"wallets": [
{
"wallet_address": "7xKX...3bPq",
"label": "whale #1",
"swap_count": 24,
"buys": 18,
"sells": 6,
"sol_bought": 45.2,
"sol_sold": 38.7,
"last_event_at": "2026-04-15T09:45:00Z"
}
],
"period": "7d"
}Wallet
Stats, FIFO PnL with daily curve, open positions with live unrealized, and paginated raw trades — for any Solana wallet, not just curated KOLs.
/wallet/{address}Aggregate counters for any Solana wallet over the last 90 days (trade count, buys/sells split, SOL in/out, unique tokens) plus cross-product flags from kol_wallets, mv_alpha_wallets, and deployers. The flags block carries reputation classification: is_sniper (≥5 tokens early-bought with ≥80% flipped <5min, behavior-updated hourly), is_bundler (bought >1 token in the same block, lifetime flag), is_dumper (≥5 dump cohorts + 0 runners in a rolling 42d window) with the raw dump_cluster cohort counts, and bot_confidence (string enum: none/low/medium/high). Reputation flags are pump.fun-pipeline scoped — false means not observed, not verified clean. v1.8.1 adds four enrichment fields: top traded tokens with realized PnL + peak MC, trading-style signals (sniper rate, round-trip rate, median hold), deployer-tier distribution, and a recent-trades timeline. Sub-100ms even on heavy wallets. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| address | path | required | Base58 wallet address |
{
"address": "ASVz...ybJk",
"stats": {
"first_seen": "2026-04-12T14:18:33Z",
"last_seen": "2026-05-20T18:27:34Z",
"total_trades": 1123,
"buys": 564,
"sells": 559,
"bought_sol": 1494.39,
"sold_sol": 1562.55,
"unique_tokens": 324,
"window_days": 90
},
"flags": {
"is_kol": true,
"kol_name": "Reljoo",
"is_alpha_tracked": true,
"bot_confidence": "low",
"alpha_win_rate": 0.43,
"alpha_net_pnl_sol": 68.2,
"alpha_tokens_traded": 324,
"is_deployer": false,
"deployer_tokens_deployed": null,
"deployer_bonding_rate": null,
"is_sniper": false,
"is_bundler": false,
"is_dumper": false,
"dump_cluster": {
"dump_cohorts": 2,
"runner_cohorts": 3,
"total_cohorts": 5,
"as_of": "2026-07-10T04:00:00Z"
}
},
"top_tokens": [
{
"token_mint": "C7Py...pump",
"token_symbol": "ALVEUS",
"buys": 12,
"sells": 9,
"sol_in": 18.47,
"sol_out": 22.13,
"realized_pnl_sol": 3.66,
"current_mc_usd": 124000,
"peak_mc_usd": 380000,
"last_traded_at": "2026-05-19T08:42:11Z"
}
],
"trading_style": {
"total_trades": 1123,
"avg_trade_size_sol": 2.72,
"sniper_rate": 0.18,
"early_entries": 202,
"round_trip_rate": 0.84,
"tokens_with_round_trips": 272,
"median_hold_minutes": 47,
"dominant_action": "balanced"
},
"deployer_breakdown": {
"total_tokens": 89,
"tracked_deployers": 4,
"by_tier": [
{
"tier": "elite",
"count": 38
},
{
"tier": "good",
"count": 27
},
{
"tier": "rising",
"count": 14
},
{
"tier": "cold",
"count": 10
}
]
},
"recent_trades": [
{
"token_mint": "ASVz...pump",
"token_symbol": "PEPE2",
"action": "buy",
"sol_amount": 1.42,
"block_time": 1747900800,
"traded_at": "2026-05-22T12:00:00Z",
"tx_signature": "5Tx...abc"
}
]
}/wallet/batch/classifyBulk reputation flags for up to 100 wallet addresses in one call — the batch counterpart to the flags block on GET /wallet/{address} (values are identical). Per wallet: is_sniper, is_bundler, is_dumper, is_kol + kol_name, bot_confidence (string enum: none/low/medium/high), and the raw dump_cluster cohort counts (null unless the wallet has recent cohort appearances). Flags are pump.fun-pipeline scoped — false means not observed, not verified clean. Pure index lookups: ~10ms per 100-address batch. Counts as 1 request against quota. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| wallets | string[] | string | required | 1-100 base58 wallet addresses — JSON array or comma-separated string |
{
"wallets": [
{
"address": "7xKv...9mPQ",
"is_sniper": true,
"is_bundler": false,
"is_dumper": false,
"is_kol": true,
"kol_name": "Cented",
"bot_confidence": "low",
"dump_cluster": {
"dump_cohorts": 2,
"runner_cohorts": 3,
"total_cohorts": 5,
"as_of": "2026-07-10T04:00:00Z"
}
},
{
"address": "3nQd...42aa",
"is_sniper": false,
"is_bundler": true,
"is_dumper": true,
"is_kol": false,
"kol_name": null,
"bot_confidence": "high",
"dump_cluster": {
"dump_cohorts": 6,
"runner_cohorts": 0,
"total_cohorts": 6,
"as_of": "2026-07-10T04:00:00Z"
}
}
],
"count": 2,
"as_of": "2026-07-10T12:00:00Z"
}/wallet/{address}/pnlFull per-wallet PnL: realized + unrealized SOL, profit factor, max drawdown, avg + median hold minutes, daily UTC PnL curve, closed positions sorted by pnl desc (with ROI %, hold minutes, win/loss), and open positions hydrated with current prices from market-cap tracker. Cached in wallet_analyses with dynamic TTL (5min / 1h / 24h based on activity). Cache hits don't count against your daily quota. Check `coverage.in_scope` before trusting a flat PnL: `false` means this wallet trades outside our launchpad write-gate, so the numbers mean "not covered by our capture", NOT "no activity". PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| address | path | required | Base58 wallet address |
{
"address": "ASVz...ybJk",
"window_days": 90,
"coverage": {
"history_start": 1775984757,
"scope": "pump.fun pipeline (pump.fun, LaunchLab/bonk, bags)",
"in_scope": true
},
"summary": {
"realized_sol": 211.68,
"unrealized_sol": -197.22,
"total_pnl_sol": 14.46,
"wins": 12,
"losses": 8,
"win_rate": 0.6,
"profit_factor": 2.35,
"avg_hold_minutes": 47,
"median_hold_minutes": 22,
"max_drawdown_sol": 4.81,
"open_positions_count": 27,
"closed_positions_count": 268,
"total_tokens_traded": 324
},
"pnl_curve": [
{
"date": "2026-04-12",
"day_pnl": 1.5,
"cumulative_pnl": 1.5,
"trades": 3
},
{
"date": "2026-04-13",
"day_pnl": -0.3,
"cumulative_pnl": 1.2,
"trades": 2
}
],
"closed_positions": [
{
"token_mint": "81QY...pump",
"buy_count": 3,
"sell_count": 2,
"bought_sol": 2.5,
"sold_sol": 7.7,
"pnl_sol": 5.2,
"roi_pct": 208,
"hold_minutes": 47,
"result": "win"
}
],
"open_positions": [
{
"token_mint": "5KSo...bonk",
"token_amount": 1000,
"cost_basis_sol": 1.5,
"avg_entry_price_sol": 0.0015,
"current_price_sol": 0.002,
"current_value_sol": 2,
"unrealized_sol": 0.5,
"unrealized_pct": 33.3
}
],
"notes": {
"cost_basis_observable_from": "2026-04-12T00:00:00Z"
},
"cache_hit": false,
"ttl_seconds": 300
}/wallet/{address}/positionsOpen lots only — same data as /pnl's open_positions[] but without summary or curve. Shares the wallet_analyses cache: if you recently called /pnl for this wallet, this is an immediate cache hit. Mints without a current price in market-cap tracker return unrealized_sol: null rather than fabricated zero. An empty positions[] with `coverage.in_scope: false` means the wallet is outside our launchpad write-gate — "not covered by our capture", NOT "no activity". PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| address | path | required | Base58 wallet address |
{
"address": "ASVz...ybJk",
"coverage": {
"history_start": 1775984757,
"scope": "pump.fun pipeline (pump.fun, LaunchLab/bonk, bags)",
"in_scope": true
},
"positions": [
{
"token_mint": "5KSo...bonk",
"token_amount": 1000,
"cost_basis_sol": 1.5,
"avg_entry_price_sol": 0.0015,
"current_price_sol": 0.002,
"current_value_sol": 2,
"unrealized_sol": 0.5,
"unrealized_pct": 33.3,
"first_buy_at": "2026-05-01T10:00:00Z",
"buys_in_position": 2
}
],
"cache_hit": true,
"computed_at": "2026-05-20T18:25:42Z"
}/wallet/{address}/holdingsCurrent on-chain token balances, read live from the wallet's SPL + Token-2022 accounts (getTokenAccountsByOwner) plus native SOL — not trade-derived like /positions, so transfers, airdrops and CEX withdrawals are all reflected. Each holding is enriched from our data with price/market-cap, name/symbol, and transfer_delta: the on-chain amount minus the 90-day trade-derived net, which surfaces tokens that arrived or left WITHOUT a swap (airdrops, insider funding, wallet-hopping). Sorted by USD value (unpriced last). 90s cache; 6 uncached lookups/min (cache hits don't count). ULTRA.
| Name | Type | Default | Description |
|---|---|---|---|
| address | path | required | Base58 wallet address |
| limit | integer | 200 | 1-500 holdings returned |
| min_value_usd | number | 0 | Hide holdings below this USD value |
{
"address": "ASVz...ybJk",
"sol_balance": 12.45,
"holdings": [
{
"mint": "5KSo...bonk",
"symbol": "BONK",
"name": "Bonk",
"amount": 1500000,
"amount_raw": "1500000000000",
"decimals": 5,
"token_program": "spl",
"price_usd": 0.0000132,
"value_usd": 19.8,
"market_cap_usd": 890000000,
"is_bonded": true,
"trade_derived_amount": 1200000,
"transfer_delta": 300000
}
],
"summary": {
"token_accounts": 42,
"non_zero": 14,
"returned": 14,
"priced": 13,
"total_value_usd": 1082.89,
"truncated": false
},
"verified_at": "2026-07-05T18:25:42Z",
"trade_window_days": 90,
"cache_hit": false,
"ttl_seconds": 90
}/wallet/{address}/tradesCursor-paginated raw trades from token_trades. Cursor encodes (block_time, id) for stable DESC ordering across pages. Filters: action (buy/sell), token_mint, since/until Unix timestamps (default 90-day window), limit 1-500 (default 100). The `coverage` block disambiguates an empty page: `in_scope: false` means the wallet is outside our launchpad write-gate, so no rows means "not covered by our capture", NOT "no activity". PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| address | path | required | Base58 wallet address |
| limit | integer | 100 | 1-500 |
| cursor | string | — | From next_cursor of previous page |
| action | string | — | buy or sell |
| token_mint | string | — | Filter to one token |
| since | integer | now-90d | Unix epoch seconds |
| until | integer | now | Unix epoch seconds |
{
"address": "ASVz...ybJk",
"trades": [
{
"tx_signature": "5Hyj...kMnP",
"token_mint": "81QY...pump",
"action": "buy",
"sol_amount": 1.002,
"token_amount": 278537,
"block_time": 1747746000,
"traded_at": "2026-05-20T12:20:00Z"
}
],
"next_cursor": "MTc0Nzc0NjAwMDoxMjM0NQ==",
"has_more": true,
"filters": {
"action": null,
"token_mint": null,
"since": 1739970000,
"until": 1747746000
},
"coverage": {
"history_start": 1775984757,
"scope": "pump.fun pipeline (pump.fun, LaunchLab/bonk, bags)",
"in_scope": true
}
}Copy-Trade
PRO: 3 rules × 5 wallets. ULTRA: 20 × 50. Signals fire to webhook / WS in ~1–1.5 s. Robinhood Chain has its own rules at /rhc/copytrade/* with a separate per-chain quota.
/copytrade/subscriptionsRegister a copy-trade rule targeting one or more source wallets (KOLs or any Solana wallet). When a matching trade hits our gRPC pipeline, a signal fires to your webhook and/or WebSocket in ~1–1.5s. Returns the HMAC secret once — save it for signature verification. PRO: 3 rules × 5 source wallets each. ULTRA: 20 rules × 50 wallets each.
| Name | Type | Default | Description |
|---|---|---|---|
| source_wallets | string[] | required | Solana wallets to copy (1–50 base58 addresses) |
| sizing_amount | number | required | Size of the suggested copy trade (fixed SOL or multiplier, depending on sizing_mode) |
| delivery_mode | string | webhook | "webhook", "websocket", or "both" |
| webhook_url | string | — | HTTPS URL — required when delivery_mode includes webhook |
| name | string | — | Human-readable label (≤64 chars) |
| min_trade_sol | number | 0 | Only fire on source trades ≥ this SOL size |
| only_action | string | buy | "buy", "sell", or "both" |
| sizing_mode | string | fixed | "fixed" (SOL amount), "proportional" (multiplier × source size), or "percent_source" |
{
"subscription": {
"id": 12,
"name": "Cented buys only",
"source_wallets": [
"CyaE1Vxv...ga54o"
],
"min_trade_sol": 0.5,
"only_action": "buy",
"sizing_mode": "fixed",
"sizing_amount": 0.25,
"delivery_mode": "both",
"webhook_url": "https://your-app.com/copytrade/hook",
"is_active": true,
"created_at": "2026-04-18T14:00:00Z"
},
"webhook_secret": "a1b2c3...save-me",
"note": "Save the webhook_secret — it will not be shown again. Use it to verify HMAC-SHA256 signatures on incoming webhook payloads."
}/copytrade/subscriptionsList all your active and inactive copy-trade rules. Webhook secret is never returned here — only at creation time.
{
"subscriptions": [
{
"id": 12,
"name": "Cented buys only",
"source_wallets": [
"CyaE1Vxv...ga54o"
],
"min_trade_sol": 0.5,
"only_action": "buy",
"sizing_mode": "fixed",
"sizing_amount": 0.25,
"delivery_mode": "both",
"webhook_url": "https://your-app.com/copytrade/hook",
"is_active": true,
"created_at": "2026-04-18T14:00:00Z"
}
]
}/copytrade/subscriptions/{id}Fetch a single rule by ID. Returns 404 if the rule doesn't belong to your account.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Subscription ID |
{
"subscription": {
"id": 12,
"name": "Cented buys only",
"source_wallets": [
"CyaE1Vxv...ga54o"
],
"only_action": "buy",
"sizing_mode": "fixed",
"sizing_amount": 0.25,
"delivery_mode": "both",
"webhook_url": "https://your-app.com/copytrade/hook",
"is_active": true
}
}/copytrade/subscriptions/{id}Update any rule field. Pass only the fields you want to change. Tier limits on source_wallets still apply.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Subscription ID |
| source_wallets | string[] | — | Replace tracked wallets |
| min_trade_sol | number | — | New SOL threshold |
| only_action | string | — | buy / sell / both |
| sizing_mode | string | — | fixed / proportional / percent_source |
| sizing_amount | number | — | New size or multiplier |
| delivery_mode | string | — | webhook / websocket / both |
| webhook_url | string | null | — | New HTTPS URL or null to clear |
| is_active | boolean | — | Pause (false) or resume (true) |
{
"subscription": {
"id": 12,
"min_trade_sol": 1,
"is_active": true,
"updated_at": "2026-04-18T15:00:00Z"
}
}/copytrade/subscriptions/{id}Permanently delete a rule and its signal history. Returns 404 if not found.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Subscription ID |
{
"deleted": true
}/copytrade/signalsLast 7 days of signals fired by your rules. Each signal carries the source token's MC at trade time AND the current velocity context (`mc_change_pct`, `volume_usd`, `mev_volume_pct`) so you can see at a glance whether the signal token is still pumping or already faded — the difference between 'good entry' and 'chasing the top'. Useful for backfilling missed webhook deliveries or for audit. Always scoped to your account.
| Name | Type | Default | Description |
|---|---|---|---|
| subscription_id | integer | — | Filter to a single rule |
| since | ISO 8601 | — | Return signals fired at or after this time |
| limit | integer | 50 | Max signals (1–500) |
{
"signals": [
{
"id": 4521,
"subscription_id": 12,
"fired_at": "2026-04-18T14:12:03.142Z",
"source_wallet": "CyaE1Vxv...ga54o",
"action": "buy",
"token_mint": "tca3tbFf...pump",
"token_symbol": "Hands Off",
"source_sol_amount": 5.27,
"suggested_sol_amount": 0.25,
"tx_signature": "4fu8vvsF...v1sb",
"market_cap_usd_at_trade": 28430,
"market_cap_usd": 423000,
"mc_change_pct": {
"5m": 8.2,
"15m": 31.4,
"1h": 62.1,
"2h": 75,
"4h": 87
},
"volume_usd": {
"5m": 42000,
"15m": 118000,
"1h": 340000,
"2h": 500000,
"4h": 920000
},
"mev_volume_pct": {
"5m": 18.4,
"1h": 27.3,
"4h": 34.2
},
"delivered": true,
"delivered_at": "2026-04-18T14:12:04.019Z"
}
]
}Price Alerts
Sub-second detection via the in-memory mc-tracker price feed. PRO: 5 alerts. ULTRA: 25. Robinhood Chain has its own alerts at /rhc/price-alerts/* with a separate per-chain quota.
/price-alertsList all your token MC dip/recovery alert rules — active and inactive. PRO: 5 alerts max. ULTRA: 25 alerts max. Sub-second detection powered by the in-memory mc-tracker price feed.
{
"alerts": [
{
"id": "a3f17b22-...",
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"name": "PEPE2 dip watch",
"drop_pct": 20,
"recovery_pct": 15,
"delivery_mode": "webhook",
"webhook_url": "https://my.bot/hooks/dip",
"is_active": true,
"created_at": "2026-05-25T08:00:00Z",
"last_fired_at": "2026-05-25T12:42:11Z"
}
],
"count": 1
}/price-alertsPRO/ULTRACreate a token MC dip/recovery alert. When the token's market cap drops by `drop_pct` from its recent high, the alert fires via your chosen delivery mode. Optional `recovery_pct` triggers a follow-up when MC recovers from the dip low. Returns `webhook_secret` once if webhook delivery is configured. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| token_mint | string | required | Solana token mint address (base58) |
| drop_pct | number | required | MC drop threshold (0.01-99.99). E.g. 20 = fire when MC drops 20% from recent high |
| recovery_pct | number | — | Optional recovery threshold — fires when MC recovers this % from the dip low |
| name | string | — | Optional human-readable label (max 64 chars) |
| delivery_mode | string | websocket | "websocket", "webhook", or "both" |
| webhook_url | string | — | HTTPS URL — required when delivery_mode includes webhook |
{
"alert": {
"id": "a3f17b22-...",
"token_mint": "9aK2rFy1...pump",
"name": "PEPE2 dip watch",
"drop_pct": 20,
"recovery_pct": 15,
"delivery_mode": "webhook",
"webhook_url": "https://my.bot/hooks/dip",
"is_active": true,
"created_at": "2026-05-25T08:00:00Z"
},
"webhook_secret": "<32-byte hex -- shown once>",
"note": "Save the webhook_secret -- it will not be shown again."
}/price-alerts/{id}PRO/ULTRAFetch a single price alert rule by ID. Returns 404 if not found or not owned by the caller. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Alert rule ID |
{
"alert": {
"id": "a3f17b22-...",
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"name": "PEPE2 dip watch",
"drop_pct": 20,
"recovery_pct": 15,
"delivery_mode": "webhook",
"is_active": true,
"created_at": "2026-05-25T08:00:00Z",
"last_fired_at": null
}
}/price-alerts/{id}PRO/ULTRAUpdate fields on a price alert rule. Patchable: name, delivery_mode, webhook_url, is_active. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Alert rule ID |
| name | string | — | New label |
| delivery_mode | string | — | websocket / webhook / both |
| webhook_url | string | null | — | New HTTPS URL or null to clear |
| is_active | boolean | — | Pause (false) or resume (true) |
{
"alert": {
"id": "a3f17b22-...",
"name": "Updated dip alert",
"is_active": true,
"updated_at": "2026-05-25T15:00:00Z"
}
}/price-alerts/{id}PRO/ULTRAPermanently delete a price alert and its event history. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Alert rule ID |
{
"deleted": true
}/price-alerts/eventsPRO/ULTRAHistorical dip/recovery events fired by your price alerts. Each event carries the token's MC at fire time, the drop/recovery percentage, and delivery status. Useful for backtesting alert quality and auditing missed deliveries. PRO/ULTRA only.
| Name | Type | Default | Description |
|---|---|---|---|
| alert_id | uuid | — | Filter to events from a specific alert rule |
| event_type | string | — | "dip" or "recovery" |
| since | ISO datetime | — | Only events after this timestamp |
| limit | integer | 50 | Max results (1-100) |
{
"events": [
{
"id": "e7c12f88-...",
"alert_id": "a3f17b22-...",
"event_type": "dip",
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"mc_at_fire_usd": 340000,
"recent_high_mc_usd": 750000,
"drop_pct_actual": 54.7,
"fired_at": "2026-05-25T12:42:11Z",
"delivered": true
},
{
"id": "f8d23a99-...",
"alert_id": "a3f17b22-...",
"event_type": "recovery",
"token_mint": "9aK2rFy1...pump",
"token_symbol": "PEPE2",
"mc_at_fire_usd": 480000,
"dip_low_mc_usd": 340000,
"recovery_pct_actual": 41.2,
"fired_at": "2026-05-25T14:18:33Z",
"delivered": true
}
],
"count": 2
}Sniper Alerts (Pro + Ultra)
New token launches surface ~500-800ms before they confirm on-chain. Webhook + WS delivery. PRO covers elite + good deployers; ULTRA adds every tier, custom watchlists, and the by-deployer feed.
/sniper/recentPRO+Newest-first list of pump.fun deploys detected before chain settlement. ~500-800ms head start in production vs CONFIRMED-stream alerts. Payload carries mint + deployer + signature + slot + a snapshot of the deployer's reputation (tier, lifetime bond rate, last-10 outcome bitmap). Each deploy also carries a `footprint` block — the slot-window snipe rollup (slots deploy−1 to deploy+3): buys, buyers, sol, supply_pct, sniper_wallet_buys, data_available, as_of; null for deploys younger than the rollup's 10-minute settle window. For live alerts use the `sniper:deploy` webhook event or the `sniper:deploys` WebSocket channel; this endpoint is for backtesting / catch-up after a gap. PRO is curated to elite/good-tier deployers; ULTRA sees every tier.
| Name | Type | Default | Description |
|---|---|---|---|
| since | ISO datetime | — | Only deploys detected after this timestamp |
| deployer_tier | string | — | elite / good / moderate / rising / cold / unranked |
| min_bond_rate | number | — | Minimum lifetime bond rate (0-1, e.g. 0.5 = 50%) |
| limit | integer | 50 | Max results (1-200) |
{
"deploys": [
{
"mint": "9kQu...3xY7pump",
"name": "Waffle Inu",
"symbol": "WAFFLE",
"deployer_wallet": "7dEx...4pQ8",
"signature": "5xT...8jK",
"slot": 305418729,
"detected_at": "2026-05-28T19:32:29.068Z",
"detection_region": "Frankfurt",
"detection_confirmed": false,
"deployer_tier": "elite",
"deployer_bond_rate": 0.734,
"deployer_total_bonded": 11,
"deployer_recent": "BBBBBFBBB",
"confirmed_on_chain": null,
"confirmed_at": null,
"footprint": {
"buys": 14,
"buyers": 9,
"sol": 12.4,
"supply_pct": 3.8,
"sniper_wallet_buys": 4,
"data_available": true,
"as_of": "2026-05-28T19:42:30Z"
}
}
],
"count": 1,
"data_age_seconds": 4
}/sniper/by-deployer/{wallet}ULTRARecent pre-confirm deploys filtered to a single deployer wallet. Useful for auditing a deployer's recent track record before adding them to a custom watchlist.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string (path) | required | Deployer wallet address (base58, 32-44 chars) |
| limit | integer | 50 | Max results (1-200) |
{
"deployer": "7dEx...4pQ8",
"deploys": [
{
"mint": "9kQu...3xY7pump",
"symbol": "WAFFLE",
"signature": "5xT...8jK",
"slot": 305418729,
"detected_at": "2026-05-28T19:32:29.068Z",
"detection_region": "Frankfurt",
"deployer_tier": "elite",
"deployer_bond_rate": 0.734,
"deployer_total_bonded": 11,
"confirmed_on_chain": null
}
],
"count": 1
}/sniper/watchlistULTRAYour custom sniper watchlist — specific deployer wallets you want alerts for regardless of tier. Enable it as a scope on any channel: `?watchlist=true` here, `sniper_scope: "watchlist"` in a webhook/WS subscription. Ultra only, up to 50 deployers.
{
"deployers": [
{
"deployer_wallet": "7dEx...4pQ8",
"label": "alpha dev",
"created_at": "2026-05-29T18:00:00Z"
}
],
"count": 1,
"limit": 50,
"remaining": 49
}/sniper/watchlistULTRAAdd one deployer (`wallet`) or many (`wallets[]`, the paste-50-addresses case), with an optional `label`. Idempotent — already-watchlisted deployers are skipped. DELETE /sniper/watchlist/{wallet} removes one.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string | — | Single deployer wallet (base58) |
| wallets | string[] | — | Bulk add (max 50) |
| label | string | — | Optional note for the added deployer(s) |
{
"added": 2,
"deployers": [
"7dEx...4pQ8",
"9aBc...2zZ1"
]
}Robinhood Chain
Every plan covers Robinhood Chain (chain id 4663) at no extra cost — one key, one shared quota pool, EVM-native field names.
Robinhood Chain (chain id 4663)
Same KOL wallets (bridge-traced to their EVM addresses), plus any-wallet PnL and positions, chain-wide token discovery, the DEX trade tape, candles and deployer reputation — from our self-hosted node. Copy-trade rules, price alerts, coordination alerts and first-touch subscriptions all have RHC equivalents here, each on its own PER-CHAIN quota that never touches your Solana budget. Six WebSocket channels ride the standard stream: rhc:kol_trades, rhc:dex_trades, rhc:copytrade:signals, rhc:price_alert:events, rhc:kol:coordination and rhc:kol:first_touches.
/rhc/kol/feedLive buys and sells on Robinhood Chain from the same verified KOL wallets we track on Solana — EVM addresses traced through their bridge deposits. Free tier.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 50 | Number of trades (1-100) |
| action | string | — | Filter: "buy" or "sell" |
| wallet | string | — | Filter by KOL 0x address |
| min_kol_winrate | number | — | Minimum 7d winrate of the KOL, 0–1 (a FRACTION, not the 0–100 percent the Solana /kol/feed takes). Resolved from the RHC KOL score matview, which scores CLOSED positions only — a KOL who never sells has a null winrate and is DROPPED, not treated as zero. So ?min_kol_winrate=0 is not a no-op: it means "scored, and non-negative". |
| strategy | string | — | Hold-time bucket from the RHC score matview: "scalper", "day_trader", "swing", "inactive" or "unscored". These values DIFFER from the Solana /kol/feed strategy set (swing_trader / hodler / mixed) — it is a separate classifier, not a port. Like min_kol_winrate, KOLs absent from the matview are dropped. |
{
"chain": "robinhood",
"trades": [
{
"kol_name": "danny",
"evm_address": "0x4a9f…c21e",
"token_address": "0x8c3b…9f04",
"token_symbol": "CASHCAT",
"action": "buy",
"eth_amount": 0.215,
"market_cap_usd_at_trade": 3300000,
"dex": "uniswap-v4",
"tx_hash": "0x7d1a…8e3f",
"traded_at": "2026-07-15T17:04:12+00:00"
}
],
"count": 1
}/rhc/kol/leaderboardNet-flow leaderboard of KOLs on Robinhood Chain over 24h/7d/30d windows. Free tier.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 24h | "24h", "7d" or "30d" |
{
"chain": "robinhood",
"leaderboard": [
{
"kol_name": "danny",
"trades": 42,
"buy_eth": 12.4,
"sell_eth": 3.1
}
]
}/rhc/kol/hot-tokensConsensus signal — tokens bought by 2+ distinct tracked KOLs on Robinhood Chain inside the window, ranked by KOL-buyer count then volume, enriched with launchpad, deployer tier, graduation and current MC. Free tier.
| Name | Type | Default | Description |
|---|---|---|---|
| window | string | 1h | Rolling consensus window ("5m"–"24h") |
{
"chain": "robinhood",
"window": "1h",
"tokens": [
{
"token_address": "0x8c3b…9f04",
"token_symbol": "CASHCAT",
"kol_buyer_count": 4,
"buy_volume_eth": 6.2,
"market_cap_usd": 3300000,
"deployer_tier": "good"
}
],
"count": 1
}/rhc/kol/{wallet}A single KOL's Robinhood Chain profile — identity (name, Twitter), aggregate stats, and their 50 most recent RHC trades with MC-at-trade and tx hash. Free tier.
| Name | Type | Default | Description |
|---|---|---|---|
| wallet | string | — | KOL EVM wallet address (0x, 40 hex) — path param |
{
"chain": "robinhood",
"evm_address": "0x4a9f…c21e",
"kol_name": "danny",
"kol_twitter": "danny",
"stats": {
"trades": 128,
"buy_eth": 42.1,
"sell_eth": 18.7
},
"trades": [
{
"token_symbol": "CASHCAT",
"action": "buy",
"eth_amount": 0.215,
"tx_hash": "0x7d1a…8e3f"
}
]
}/rhc/tradesEvery v2/v3/v4 + launchpad-curve swap on the chain with real trader EOA, gas, MC-at-trade and pool liquidity. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| token | string | — | Filter by token 0x address |
| limit | integer | 100 | Number of trades (1-500) |
{
"chain": "robinhood",
"trades": [
{
"token_address": "0x8c3b…9f04",
"action": "sell",
"eth_amount": 1.2,
"trader_eoa": "0x4a9f…c21e",
"dex": "uniswap-v3",
"block_number": 11133411
}
]
}/rhc/tokensScreener over every token on the chain: sort by market cap, liquidity, peak MC or drawdown; launchpad + graduation filters. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| sort | string | market_cap | "market_cap", "liquidity", "peak_mc", "drawdown" |
| min_liquidity | number | — | Minimum pool liquidity in USD |
{
"chain": "robinhood",
"tokens": [
{
"address": "0x8c3b…9f04",
"symbol": "CASHCAT",
"market_cap_usd": 101000000,
"liquidity_usd": 3360000,
"deployer_tier": "good"
}
]
}/rhc/tokens/{address}Full token bundle: price, MC, peak + drawdown, pools with reserves, deployer reputation block and KOL activity. Free tier.
{
"chain": "robinhood",
"token": {
"address": "0x8c3b…9f04",
"symbol": "CASHCAT",
"market_cap_usd": 101000000,
"peak_mc_usd": 206000000,
"deployer": {
"address": "0x91ab…77c2",
"tier": "good",
"graduation_rate": 0.31,
"runner_rate": 0.28
}
}
}/rhc/tokens/{address}/candlesPer-minute OHLC + volume + close liquidity for any RHC token, built from the raw trade stream. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 240 | Number of candles (1-1440) |
{
"chain": "robinhood",
"candles": [
{
"t": "2026-07-15T17:04:00Z",
"o": 0.0021,
"h": 0.0024,
"l": 0.002,
"c": 0.0023,
"v_usd": 18240
}
]
}/rhc/tokens/{address}/kol-consensusHow the tracked-KOL cohort is positioned on an RHC token: distinct buyers vs sellers, exit rate, net ETH flow, and median entry market cap. PRO+ (ULTRA adds the buyer/exited wallet lists).
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"consensus": {
"total_kol_buyers": 83,
"total_kol_sellers": 72,
"kol_exit_rate": 0.735,
"net_flow_eth": -407.5,
"median_entry_mc_usd": 63279213,
"entry_mc_samples": 256
}
}/rhc/tokens/{address}/buyer-qualityA 0-100 quality score on an RHC token's earliest buyer cohort — full parity with the Solana scorer: win-rate + KOL + bot + bundle-buyer + dump-cluster legs. `coverage` reports both bundle_detection and dump_cluster_signal available (dump-cluster is informational and out-of-sample validated). Free tier.
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"quality": {
"score": 28,
"confidence": "high",
"signal": "negative",
"breakdown": {
"early_buyers_analyzed": 20,
"alpha_wallet_count": 8,
"kol_count": 0,
"bundle_buyer_count": 6,
"dump_cluster_count": 6,
"recycled_early_buyer_count": 15,
"avg_historical_win_rate": 48.41,
"bot_dominated": true
}
},
"coverage": {
"bundle_detection": "available",
"dump_cluster_signal": "available"
}
}/rhc/tokens/{address}/bundleDetects a coordinated launch bundle in an RHC token's earliest buyers: ranks the first 20 by on-chain order, flags a bundle when 3+ buy in the same block, then reports how much of what they bought they still hold — or if they fully exited (bought the launch, then dumped). BASIC gets the scalar signal; PRO the top-10 wallets; ULTRA the full cohort with alpha-wallet identity.
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"bundle": {
"wallet_count": 9,
"bundle_kind": "same_block",
"held_ratio": 0,
"held_pct_of_supply": 0,
"fully_exited": true,
"buy_volume": 261900000,
"tokens_held": 0
},
"wallets": []
}/rhc/tokens/{address}/top-tradersWho actually made money on a token. Lifetime per-trader performance ranked by realized ETH, enriched with win-rate, bot heuristic, KOL identity, dump-cluster membership and early-buyer rank. net_eth is REALIZED flow (sell − buy), not PnL — it doesn't value a trader's remaining bag, so a wallet that bought and still holds ranks last. PRO returns 50 rows; ULTRA/BUSINESS 200.
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
| limit | number | 50 | 1–200 (capped at 50 on PRO) |
| offset | number | 0 | Page offset |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"traders": [
{
"trader_eoa": "0x3387…9694",
"buy_eth": 412.3,
"sell_eth": 759.5,
"net_eth": 347.18,
"trades": 992,
"win_rate": 0.61,
"likely_bot": true,
"is_known_kol": false,
"kol_name": null,
"dump_cohorts": 0,
"early_buyer_rank": null
}
],
"count": 1,
"limit": 50,
"offset": 0,
"has_more": true,
"metric": "net_eth = realized ETH flow (sell - buy); excludes unrealized bag value"
}/rhc/tokens/{address}/flowWho is accumulating and who is distributing. Splits a token's flow into mutually-exclusive trader cohorts — KOL, bot, dump-cluster, early-buyer, unprofiled, smart-money, retail. Sign convention: net_eth = sell − buy, so a positive value means that cohort DISTRIBUTED. smart_money is derived (win-rate ≥ 0.5 and net positive); unprofiled is a real answer, not missing data.
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
| window | string | 24h | "1h", "6h", "24h", "7d" |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"window": "24h",
"cohorts": [
{
"cohort": "bot",
"traders": 1142,
"trades": 10404,
"buy_eth": 485.64,
"sell_eth": 827.37,
"net_eth": 341.73
},
{
"cohort": "smart_money",
"traders": 385,
"trades": 1144,
"buy_eth": 86.62,
"sell_eth": 176.09,
"net_eth": 89.46
},
{
"cohort": "retail",
"traders": 1365,
"trades": 4054,
"buy_eth": 465.83,
"sell_eth": 325.97,
"net_eth": -139.86
}
],
"sign_convention": "net_eth = sell - buy; positive = cohort distributed, negative = accumulated"
}/rhc/tokens/{address}/peak-historyPeak market cap, drawdown from peak, and a running high-water curve. Returns TWO peaks because they disagree: peak_mc_usd_recorded is the stored high-water mark other surfaces key off (sampled from write batches, so it can undercount an intra-batch spike), while peak_mc_usd_observed is the max of 1-minute candle highs — trade-level truth, always ≥ recorded. Candle history starts 2026-07-15.
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
| window | string | 7d | "24h", "7d", "30d", "all" |
| curve | string | true | "false" for the summary only |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"symbol": "NVDA",
"current": {
"market_cap_usd": 1412003,
"liquidity_usd": 88120
},
"peak": {
"peak_mc_usd_recorded": 1814857,
"peak_mc_usd_observed": 2694095,
"observed_covers_full_history": false,
"pct_of_peak": 0.524,
"drawdown_from_peak": 0.476
},
"curve": {
"window": "7d",
"bucket": "5m",
"count": 1338
}
}/rhc/tokens/{address}/riskRisk computed LIVE against our own Robinhood Chain node. Not the Solana model — EVM has no mint or freeze authority, and only 2.3% of RHC tokens even expose an owner function, so an absent flag is the norm rather than a safety signal. What discriminates here: proxy upgradeability, LP custody, and above all sellability — a sell is simulated at the chain head to catch a token you can buy but not sell. Never cached.
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"checked_at": "2026-07-29T20:12:46.369Z",
"code_size": 4830,
"is_contract": true,
"proxy": {
"kind": "eip1967_beacon",
"implementation": "0xb354…5ae2",
"upgradeable": true
},
"owner": {
"model": "none",
"address": null
},
"capabilities": {
"can_mint": true,
"can_pause": true,
"has_access_control": true,
"selectors_found": [
"mint(address,uint256)",
"pause()",
"hasRole(bytes32,address)"
]
},
"liquidity": {
"dex": "uniswap-v3",
"lp_custody": "burned",
"lp_burned_pct": 99.27
},
"sellability": {
"sellable": "yes",
"reason": null
},
"flags": [
"mintable",
"pausable",
"upgradeable"
],
"score": 55
}/rhc/tokens/{address}/holdersExact holder set and concentration — folded from ERC-20 Transfer logs, not derived from trades, and reconciled against on-chain totalSupply(). Check verified first: false means the reconstruction is incomplete for that token and the response says why. Concentration excludes liquidity pools and burn addresses from the circulating denominator (the top holder is otherwise the token's own pool) and reports them separately. Balances are raw uint256 strings.
| Name | Type | Default | Description |
|---|---|---|---|
| address | string | — | RHC token 0x address |
| limit | number | 50 | 1–200 (capped at 50 on PRO) |
| offset | number | 0 | Page offset |
{
"chain": "robinhood",
"token_address": "0x8c3b…9f04",
"verified": true,
"unverified_reason": null,
"holders": [
{
"holder": "0xb98b…ded7",
"balance": "72595847095530512318459056",
"share": 0.080699,
"is_pool": true,
"is_burn": false,
"is_deployer": false
}
],
"concentration": {
"holder_count": 214314,
"top1_share": 0.04663,
"top10_share": 0.245752,
"top50_share": 0.62173,
"hhi": 0.011576,
"pool_held_pct": 0.072596,
"burned_pct": 0.069595
},
"source": {
"method": "erc20_transfer_log_replay",
"backfill_complete": true
}
}/rhc/deployer-hunter/leaderboard99,000+ deployers ranked by graduation rate, runner rate, tokens deployed or best peak MC — spam factories tiered out. Reputation tiers are scored on runner rate ($100K+ peak MC), not the $40K graduation bar. Free tier.
| Name | Type | Default | Description |
|---|---|---|---|
| sort | string | graduation_rate | "graduation_rate", "runner_rate", "tokens_deployed", "best_peak_mc_usd", "last_deploy_at" |
| tier | string | — | "elite", "good", "neutral" or "spammer" |
| min_tokens | integer | 3 | Minimum tokens deployed |
{
"chain": "robinhood",
"deployers": [
{
"deployer_address": "0x91ab…77c2",
"tokens_deployed": 28,
"graduated": 9,
"graduation_rate": 0.321,
"runners": 8,
"runner_rate": 0.286,
"tier": "good"
}
],
"total": 99237
}/rhc/deployer-hunter/{address}One deployer's full reputation row plus their recent tokens with current + peak market caps. Free tier.
{
"chain": "robinhood",
"deployer": {
"deployer_address": "0x91ab…77c2",
"tier": "good",
"graduation_rate": 0.321,
"runner_rate": 0.286
},
"recent_tokens": [
{
"address": "0x8c3b…9f04",
"symbol": "CASHCAT",
"is_graduated": true,
"peak_mc_usd": 206000000
}
]
}/rhc/alpha-walletsSmart-money ranking on Robinhood Chain — the highest-performing non-bot wallets, filterable by net ETH, win-rate, memecoin share, size and identity (known-KOL vs net-new smart money). PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| classification | string | all | "human", "smart_money" or "all" |
| identity | string | all | "known_kol", "unknown" or "all" |
| sort | string | net_eth | Sort key (net_eth, win_rate, …) |
| limit | integer | 25 | Rows returned (offset paging) |
{
"chain": "robinhood",
"wallets": [
{
"address": "0x4a9f…c21e",
"net_eth": 18.4,
"win_rate": 0.63,
"trades": 84,
"likely_bot": false
}
],
"total": 320,
"has_more": true
}/rhc/wallet/{address}Any Robinhood Chain wallet's 90-day profile: FIFO cost-basis PnL in ETH, per-token breakdown, recent trades, and reputation flags (tracked KOL, known deployer + tier, alpha-ranked, dump-cluster, early-buyer count). Keyed on trader_eoa — the effective trading account, never the router or an ERC-4337 bundler. PRO+.
{
"chain": "robinhood",
"address": "0xada5…f7cb",
"stats": {
"total_trades": 1420,
"analyzed_trades": 1180,
"unattributed_trades": 240,
"realized_pnl_eth": 1.46,
"unrealized_pnl_eth": -0.32,
"total_pnl_eth": 1.14,
"unique_tokens": 96
},
"flags": {
"is_kol": false,
"is_deployer": true,
"deployer_tier": "neutral",
"likely_bot": false,
"is_dumper": false
}
}/rhc/wallet/{address}/pnlFull FIFO cost-basis PnL: realized/unrealized split, daily realized curve, every closed position with ROI and token-weighted hold time, open positions marked to live price. Same FIFO engine as the Solana /wallet/{address}/pnl, ETH-denominated. Shares one loader with the profile endpoint, so the two cannot disagree. PRO+.
{
"chain": "robinhood",
"summary": {
"realized_eth": 1.46,
"unrealized_eth": -0.32,
"win_rate": 0.36,
"profit_factor": 1.8,
"max_drawdown_eth": 1.44,
"open_positions_count": 12,
"closed_positions_count": 84
},
"pnl_curve": [
{
"date": "2026-07-24",
"day_pnl": 0.42,
"cumulative_pnl": 1.46,
"trades": 9
}
]
}/rhc/wallet/{address}/positionsOnly what the wallet still holds, marked to the current price. "Open" means FIFO-unmatched buys — a trading position, not an on-chain balance, so tokens acquired by transfer or bridge don't appear. PRO+.
{
"chain": "robinhood",
"summary": {
"open_positions": 12,
"total_cost_basis_eth": 3.9,
"total_current_value_eth": 3.1,
"total_unrealized_eth": -0.8,
"unpriced_positions": 0
},
"positions": [
{
"token_address": "0x8c3b…9f04",
"token_symbol": "CASHCAT",
"cost_basis_eth": 0.42,
"current_value_eth": 1.31,
"unrealized_pct": 211.9
}
]
}/rhc/wallet/{address}/tradesOne wallet's swaps, newest first, cursor-paginated on block_time. Distinct from /rhc/trades?token= — that filters by token, this by wallet. token_amount is reconstructed from raw uint256 leg amounts and is null when it can't be, never a guess. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 50 | Rows returned (max 200) |
| before | string | — | Cursor: trades older than this block_time |
| action | string | — | "buy" or "sell" |
| token | string | — | Restrict to one token address |
{
"chain": "robinhood",
"trades": [
{
"token_symbol": "GME",
"action": "buy",
"eth_amount": 0.0026,
"token_amount": 46070.24,
"dex": "uniswap-v3",
"block_time": "2026-07-25T18:23:32Z"
}
],
"count": 1,
"next_before": "2026-07-25T18:23:32Z"
}/rhc/wallet-tracker/summaryWatchlist CRUD (/rhc/wallet-tracker/watchlist) plus a per-wallet activity rollup and a merged trade feed across everything you track. Quotas are PER CHAIN — 50/100/500 RHC wallets — so this never eats into your Solana watchlist. Read straight from the chain rather than a capture log, so a wallet added today reports its full history. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| period | string | 7d | "24h", "7d" or "30d" |
| wallet | string | — | Restrict to one watched wallet |
{
"chain": "robinhood",
"period": "7d",
"wallets": [
{
"wallet_address": "0xada5…f7cb",
"label": "whale-1",
"stats": {
"trades": 447,
"buys": 222,
"sells": 147,
"net_eth": -14.1,
"tokens_traded": 56
}
}
]
}/rhc/copytrade/subscriptionsEvery copy-trade rule you have on Robinhood Chain, active or not, newest first. The webhook secret is never returned here — only once, at creation. Quotas are PER CHAIN: PRO 3 rules × 5 source wallets, ULTRA 20 × 50, BUSINESS 100 × 250 — none of it consumes your Solana copy-trade budget. PRO+.
{
"chain": "robinhood",
"subscriptions": [
{
"id": 7,
"name": "danny buys",
"source_wallets": [
"0x4a9f…c21e"
],
"min_trade_eth": 0.05,
"only_action": "buy",
"sizing_mode": "fixed",
"sizing_amount": 0.01,
"delivery_mode": "both",
"webhook_url": "https://your-app.com/rhc/hook",
"is_active": true,
"created_at": "2026-07-28T09:00:00Z",
"updated_at": "2026-07-28T09:00:00Z"
}
]
}/rhc/copytrade/subscriptionsRegister a rule against one or more Robinhood Chain EVM wallets. Sizing is ETH-denominated (min_trade_eth / sizing_amount), not SOL. There is NO market-cap band on RHC copy-trade — the producer's event carries no MC, so min_mc_usd / max_mc_usd simply do not exist here; filter on MC after the fact via /rhc/tokens/{address}. Source addresses are lowercased on write, so a checksummed address still matches. Returns webhook_secret once. PRO+ (rules 3/20/100, wallets 5/50/250 per rule — per-chain quota).
| Name | Type | Default | Description |
|---|---|---|---|
| source_wallets | string[] | required | 1–250 EVM addresses (0x + 40 hex) to copy; tier-capped at 5 / 50 / 250 |
| sizing_amount | number | required | Suggested copy size in ETH (or the multiplier, depending on sizing_mode). Must be > 0 |
| name | string | — | Human-readable label (1–64 chars) |
| min_trade_eth | number | 0 | Only fire on source trades ≥ this ETH size |
| only_action | string | buy | "buy", "sell" or "both" |
| sizing_mode | string | fixed | "fixed" (ETH amount), "proportional" (multiplier × source size) or "percent_source" |
| delivery_mode | string | webhook | "webhook", "websocket" or "both" — websocket delivers on the rhc:copytrade:signals channel |
| webhook_url | string | — | HTTPS URL — required unless delivery_mode is "websocket" |
{
"chain": "robinhood",
"subscription": {
"id": 7,
"name": "danny buys",
"source_wallets": [
"0x4a9f…c21e"
],
"min_trade_eth": 0.05,
"only_action": "buy",
"sizing_mode": "fixed",
"sizing_amount": 0.01,
"delivery_mode": "both",
"webhook_url": "https://your-app.com/rhc/hook",
"is_active": true,
"created_at": "2026-07-28T09:00:00Z",
"updated_at": "2026-07-28T09:00:00Z"
},
"webhook_secret": "<32-byte hex — shown once>",
"note": "Save the webhook_secret — it will not be shown again. Payloads are signed HMAC-SHA256 over `<timestamp>.<body>` in the X-MadeOnSol-Signature header."
}/rhc/copytrade/subscriptions/{id}Fetch one rule by integer id. Scoped to your account — a rule you don't own returns 404, never someone else's row. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Rule ID |
{
"chain": "robinhood",
"subscription": {
"id": 7,
"name": "danny buys",
"source_wallets": [
"0x4a9f…c21e"
],
"min_trade_eth": 0.05,
"only_action": "buy",
"sizing_mode": "fixed",
"sizing_amount": 0.01,
"delivery_mode": "both",
"webhook_url": "https://your-app.com/rhc/hook",
"is_active": true
}
}/rhc/copytrade/subscriptions/{id}Partial update — send only the fields you want changed; an empty body is a 400. The per-chain source_wallets cap is re-checked on update. No new webhook_secret is issued: to rotate one, delete and recreate the rule. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Rule ID |
| source_wallets | string[] | — | Replace the tracked EVM wallets (tier cap re-applied) |
| min_trade_eth | number | — | New ETH threshold |
| only_action | string | — | buy / sell / both |
| sizing_mode | string | — | fixed / proportional / percent_source |
| sizing_amount | number | — | New ETH size or multiplier |
| delivery_mode | string | — | webhook / websocket / both |
| webhook_url | string | null | — | New HTTPS URL, or null to clear |
| name | string | null | — | New label, or null to clear |
| is_active | boolean | — | Pause (false) or resume (true) |
{
"chain": "robinhood",
"subscription": {
"id": 7,
"min_trade_eth": 0.1,
"is_active": true,
"updated_at": "2026-07-28T11:00:00Z"
}
}/rhc/copytrade/subscriptions/{id}Permanently delete a rule. Returns 404 if it isn't yours. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Rule ID |
{
"chain": "robinhood",
"deleted": true
}/rhc/copytrade/signalsThe catch-up path for signals your RHC rules fired — use it to backfill a missed webhook or a dropped WebSocket. Retained 7 days. Always scoped to your own rules. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| subscription_id | integer | — | Filter to one rule (404 if not yours) |
| since | ISO 8601 | — | Signals fired at or after this timestamp |
| limit | integer | 50 | Max signals (1–500) |
{
"chain": "robinhood",
"signals": [
{
"id": 8812,
"subscription_id": 7,
"fired_at": "2026-07-28T09:14:02.318Z",
"source_wallet": "0x4a9f…c21e",
"action": "buy",
"token_address": "0x8c3b…9f04",
"token_symbol": "CASHCAT",
"token_name": "Cash Cat",
"source_eth_amount": 0.215,
"suggested_eth_amount": 0.01,
"price_usd": 0.0021,
"dex": "uniswap-v4",
"tx_hash": "0x7d1a…8e3f",
"delivered": true,
"delivered_at": "2026-07-28T09:14:02.904Z"
}
],
"count": 1
}/rhc/price-alertsYour Robinhood Chain MC dip/recovery alerts, active and inactive. Per-chain quota: PRO 5, ULTRA 25, BUSINESS 125 active alerts — independent of your Solana price-alert budget. PRO+.
{
"chain": "robinhood",
"alerts": [
{
"id": 31,
"name": "CASHCAT dip watch",
"token_address": "0x8c3b…9f04",
"token_symbol": "CASHCAT",
"baseline_mc_usd": 3300000,
"drop_pct": 20,
"recovery_pct": 15,
"status": "armed",
"dip_low_mc_usd": null,
"dip_fired_at": null,
"delivery_mode": "webhook",
"webhook_url": "https://your-app.com/rhc/dip",
"is_active": true,
"expires_at": null,
"created_at": "2026-07-28T09:00:00Z",
"updated_at": "2026-07-28T09:00:00Z"
}
]
}/rhc/price-alertsCreate an MC dip alert on an RHC token. The token's current market cap is captured at create time as baseline_mc_usd — an untracked token, or one with no MC to baseline against, is a 400 rather than a silently dead alert. IMPORTANT: RHC alerts are evaluated on a ~15s POLL of our chain price table, not the live in-memory loop the Solana alerts use — effective latency is that interval plus the token's own price-update cadence. Do not assume Solana parity. Returns webhook_secret once. PRO+ (5 / 25 / 125 active alerts, per-chain quota).
| Name | Type | Default | Description |
|---|---|---|---|
| token_address | string | required | RHC token 0x address (lowercased on write) |
| drop_pct | number | required | MC drop threshold from baseline, 0.01–99.99 |
| recovery_pct | number | — | Optional follow-up threshold when MC recovers from the dip low, 0.01–1000 |
| name | string | — | Optional label (1–64 chars) |
| delivery_mode | string | webhook | "webhook", "websocket" or "both" — websocket delivers on rhc:price_alert:events |
| webhook_url | string | — | HTTPS URL — required unless delivery_mode is "websocket" |
{
"chain": "robinhood",
"alert": {
"id": 31,
"name": "CASHCAT dip watch",
"token_address": "0x8c3b…9f04",
"token_symbol": "CASHCAT",
"baseline_mc_usd": 3300000,
"drop_pct": 20,
"recovery_pct": 15,
"status": "armed",
"delivery_mode": "webhook",
"webhook_url": "https://your-app.com/rhc/dip",
"is_active": true,
"created_at": "2026-07-28T09:00:00Z"
},
"webhook_secret": "<32-byte hex — shown once>",
"evaluation": {
"mode": "polled",
"interval_seconds": 15,
"note": "RHC alerts are evaluated on a ~15s poll, not a live price loop — do not assume parity with the sub-second Solana alerts."
},
"note": "Save the webhook_secret — it will not be shown again."
}/rhc/price-alerts/{id}Fetch one alert by integer id, including its live dip state (status, dip_low_mc_usd, dip_fired_at). 404 if it isn't yours. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Alert ID |
{
"chain": "robinhood",
"alert": {
"id": 31,
"token_address": "0x8c3b…9f04",
"token_symbol": "CASHCAT",
"baseline_mc_usd": 3300000,
"drop_pct": 20,
"recovery_pct": 15,
"status": "dipped",
"dip_low_mc_usd": 2410000,
"dip_fired_at": "2026-07-28T12:42:11Z",
"is_active": true
}
}/rhc/price-alerts/{id}Only four fields are mutable: name, delivery_mode, webhook_url, is_active. token_address, drop_pct and recovery_pct are IMMUTABLE by design — moving a threshold on an already-dipped alert would make its recorded events uninterpretable, so delete and recreate instead. Sending an immutable field is a 400. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Alert ID |
| name | string | null | — | New label, or null to clear |
| delivery_mode | string | — | webhook / websocket / both |
| webhook_url | string | null | — | New HTTPS URL, or null to clear |
| is_active | boolean | — | Pause (false) or resume (true) |
{
"chain": "robinhood",
"alert": {
"id": 31,
"name": "CASHCAT dip watch v2",
"is_active": false,
"updated_at": "2026-07-28T15:00:00Z"
}
}/rhc/price-alerts/{id}Permanently delete an alert and its event history. 404 if it isn't yours. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Alert ID |
{
"chain": "robinhood",
"deleted": true
}/rhc/price-alerts/eventsDip and recovery events fired by your RHC alerts, newest first — the audit / catch-up path for a missed delivery. Retained 30 days. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| alert_id | integer | — | Filter to one alert (404 if not yours) |
| event_type | string | — | "dip" or "recovery" |
| since | ISO 8601 | — | Events fired at or after this timestamp |
| limit | integer | 50 | Max events (1–500) |
{
"chain": "robinhood",
"events": [
{
"id": 902,
"alert_id": 31,
"event_type": "dip",
"fired_at": "2026-07-28T12:42:11Z",
"token_address": "0x8c3b…9f04",
"baseline_mc_usd": 3300000,
"current_mc_usd": 2410000,
"drop_pct_actual": 26.97,
"dip_low_mc_usd": 2410000,
"recovery_pct_actual": null,
"delivered": true,
"delivered_at": "2026-07-28T12:42:11.812Z"
}
],
"count": 1
}/rhc/kol/coordination/alertsYour Robinhood Chain KOL-convergence rules — fire when N+ tracked KOLs buy the same token inside a rolling window. Per-chain quota: PRO 5, ULTRA 20, BUSINESS 100 rules, separate from the Solana coordination budget. PRO+.
{
"chain": "robinhood",
"rules": [
{
"id": "b41c…",
"name": "3 KOLs in 15m",
"min_kols": 3,
"window_minutes": 15,
"min_score": 0,
"cooldown_min": 30,
"score_jump_break": 20,
"min_mc_usd": null,
"max_mc_usd": null,
"delivery_mode": "websocket",
"webhook_url": null,
"is_active": true,
"created_at": "2026-07-28T09:00:00Z",
"updated_at": "2026-07-28T09:00:00Z"
}
]
}/rhc/kol/coordination/alertsFire when min_kols distinct tracked KOLs converge on one RHC token inside window_minutes. Unlike copy-trade, coordination rules DO take an MC band (min_mc_usd / max_mc_usd). Scoring is v1: the quality leg is real (7d winrate from the RHC KOL score matview) while earliness is defaulted on RHC — treat min_score accordingly. Returns webhook_secret once. PRO+ (5 / 20 / 100 rules, per-chain quota).
| Name | Type | Default | Description |
|---|---|---|---|
| min_kols | integer | 3 | Distinct KOL buyers needed to fire (2–50) |
| window_minutes | integer | 15 | Rolling convergence window (1–60) |
| min_score | integer | 0 | Minimum coordination score, 0–100 |
| cooldown_min | integer | 30 | Per-token cooldown between firings (1–1440) |
| score_jump_break | integer | 20 | Re-fire inside cooldown if the score jumps by this much (0–100) |
| min_mc_usd | number | null | — | Lower market-cap bound (0–1e12) |
| max_mc_usd | number | null | — | Upper market-cap bound (0–1e12); must be ≥ min_mc_usd |
| name | string | — | Optional label (1–64 chars) |
| delivery_mode | string | websocket | "websocket", "webhook" or "both" — websocket delivers on rhc:kol:coordination |
| webhook_url | string | — | HTTPS URL — required unless delivery_mode is "websocket" |
{
"chain": "robinhood",
"rule": {
"id": "b41c…",
"name": "3 KOLs in 15m",
"min_kols": 3,
"window_minutes": 15,
"min_score": 0,
"cooldown_min": 30,
"score_jump_break": 20,
"min_mc_usd": null,
"max_mc_usd": null,
"delivery_mode": "websocket",
"webhook_url": null,
"is_active": true,
"created_at": "2026-07-28T09:00:00Z"
},
"webhook_secret": null,
"scoring": {
"score_version": "v1",
"quality": "7d winrate from the RHC KOL score matview",
"earliness": "defaulted on RHC — no scout-score equivalent yet"
}
}/rhc/kol/coordination/alerts/{id}Fetch one rule by UUID. Scoped to your account — 404 for anything you don't own. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Rule ID |
{
"chain": "robinhood",
"rule": {
"id": "b41c…",
"name": "3 KOLs in 15m",
"min_kols": 3,
"window_minutes": 15,
"min_score": 0,
"cooldown_min": 30,
"delivery_mode": "websocket",
"is_active": true
}
}/rhc/kol/coordination/alerts/{id}Partial update of any rule field; an empty body is a 400. The min_mc_usd ≤ max_mc_usd check only runs when you send BOTH bounds in the same request — the DB constraint is the backstop for the one-sided case. No webhook_secret is re-issued. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Rule ID |
| min_kols | integer | — | 2–50 |
| window_minutes | integer | — | 1–60 |
| min_score | integer | — | 0–100 |
| cooldown_min | integer | — | 1–1440 |
| score_jump_break | integer | — | 0–100 |
| min_mc_usd | number | null | — | Lower MC bound, or null to clear |
| max_mc_usd | number | null | — | Upper MC bound, or null to clear |
| name | string | null | — | New label, or null to clear |
| delivery_mode | string | — | websocket / webhook / both |
| webhook_url | string | null | — | New HTTPS URL, or null to clear |
| is_active | boolean | — | Pause (false) or resume (true) |
{
"chain": "robinhood",
"rule": {
"id": "b41c…",
"min_kols": 4,
"is_active": true,
"updated_at": "2026-07-28T15:00:00Z"
}
}/rhc/kol/coordination/alerts/{id}Permanently delete a coordination rule. 404 if it isn't yours. PRO+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Rule ID |
{
"chain": "robinhood",
"deleted": true
}/rhc/kol/first-touches/subscriptionsYour subscriptions to the moment a tracked KOL touches an RHC token for the FIRST time — the earliest signal we can emit for a KOL/token pair. ULTRA+ only (PRO is 0): ULTRA 10, BUSINESS 50 subscriptions, a per-chain quota separate from the Solana first-touch budget.
{
"chain": "robinhood",
"subscriptions": [
{
"id": "9d02…",
"name": "winners only",
"filters": {
"min_kol_winrate": 0.55,
"strategy": "scalper",
"min_first_buy_eth": 0.1
},
"delivery_mode": "websocket",
"webhook_url": null,
"is_active": true,
"created_at": "2026-07-28T09:00:00Z",
"updated_at": "2026-07-28T09:00:00Z"
}
]
}/rhc/kol/first-touches/subscriptionsSubscribe to first-touch events with an optional filters object. RHC deliberately omits the Solana min_scout_tier / min_n_touches filters (there is no scout-score matview on RHC) — min_kol_winrate and strategy are the quality gates instead, and both DROP unscored KOLs rather than treating them as zero. Unknown filter keys are rejected, not ignored. Returns webhook_secret once. ULTRA+ (10 / 50, per-chain quota).
| Name | Type | Default | Description |
|---|---|---|---|
| filters.kol | string | — | Restrict to one KOL EVM address (lowercased on write) |
| filters.min_first_buy_eth | number | — | Minimum size of the first buy, 0–100000 ETH |
| filters.min_kol_winrate | number | — | Minimum 7d winrate as a FRACTION, 0–1 (not 0–100). Unscored KOLs are dropped. |
| filters.strategy | string | — | "scalper", "day_trader", "swing", "inactive" or "unscored" — the RHC hold-time buckets, which differ from the Solana strategy values |
| filters.min_mc_usd | number | — | Lower market-cap bound (0–1e12) |
| filters.max_mc_usd | number | — | Upper market-cap bound (0–1e12); must be ≥ min_mc_usd |
| name | string | — | Optional label (1–64 chars) |
| delivery_mode | string | websocket | "websocket", "webhook" or "both" — websocket delivers on rhc:kol:first_touches |
| webhook_url | string | — | HTTPS URL — required unless delivery_mode is "websocket" |
{
"chain": "robinhood",
"subscription": {
"id": "9d02…",
"name": "winners only",
"filters": {
"min_kol_winrate": 0.55,
"strategy": "scalper",
"min_first_buy_eth": 0.1
},
"delivery_mode": "websocket",
"webhook_url": null,
"is_active": true,
"created_at": "2026-07-28T09:00:00Z"
},
"webhook_secret": null,
"note": "delivery_mode is websocket — subscribe to the rhc:kol:first_touches channel."
}/rhc/kol/first-touches/subscriptions/{id}Fetch one subscription by UUID. 404 for anything you don't own. ULTRA+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Subscription ID |
{
"chain": "robinhood",
"subscription": {
"id": "9d02…",
"name": "winners only",
"filters": {
"min_kol_winrate": 0.55,
"strategy": "scalper"
},
"delivery_mode": "websocket",
"is_active": true
}
}/rhc/kol/first-touches/subscriptions/{id}Partial update; an empty body is a 400. NOTE: `filters` is a whole-object REPLACE, not a merge — send the complete filter set you want, because merging would make removing a filter inexpressible. Send `filters: {}` to clear them all. ULTRA+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Subscription ID |
| filters | object | — | Replaces the whole filter object (same six keys and bounds as POST) |
| name | string | null | — | New label, or null to clear |
| delivery_mode | string | — | websocket / webhook / both |
| webhook_url | string | null | — | New HTTPS URL, or null to clear |
| is_active | boolean | — | Pause (false) or resume (true) |
{
"chain": "robinhood",
"subscription": {
"id": "9d02…",
"filters": {
"min_kol_winrate": 0.6
},
"is_active": true,
"updated_at": "2026-07-28T15:00:00Z"
}
}/rhc/kol/first-touches/subscriptions/{id}Permanently delete a first-touch subscription. 404 if it isn't yours. ULTRA+.
| Name | Type | Default | Description |
|---|---|---|---|
| id | uuid (path) | required | Subscription ID |
{
"chain": "robinhood",
"deleted": true
}Real-time
Sub-second deliveries via webhooks and direct WebSocket. The all-DEX firehose is its own ULTRA-only stream.
Webhooks
PRO 3 webhooks · ULTRA 10. Per-rule secret, automatic retry, auto-disable on repeated failure. Seven registerable events, including rhc:kol_trade for Robinhood Chain (PRO+) — note min_sol and kol_name are Solana-only filters.
/webhooksRegister a webhook URL to receive real-time push notifications for KOL trades and deployer alerts. HTTPS URLs only. Server generates an HMAC-SHA256 secret for payload verification. Pro: 3 webhooks max. Ultra: 10 webhooks max.
| Name | Type | Default | Description |
|---|---|---|---|
| url | string | required | HTTPS webhook URL to receive events |
| events | string[] | required | The complete registerable set: "kol:trade", "kol:coordination", "deployer:alert", "deployer:bond", "wallet_tracker:event", "sniper:deploy" (Pro+; Pro curated to elite/good deployers), "rhc:kol_trade" (Pro+, Robinhood Chain). Anything else is rejected with 400. Price-alert, copy-trade, coordination and first-touch delivery is configured on the rule itself via its own `webhook_url` + per-rule HMAC secret, not through the /webhooks registry. |
| filters | object | {} | Optional filters: min_sol, action (buy/sell), kol_name, deployer_tier[], min_kols. min_sol and kol_name are Solana-only — see the payload-format section before setting them on "rhc:kol_trade". |
{
"webhook": {
"id": 1,
"url": "https://your-app.com/webhooks/madeonsol",
"secret": "a1b2c3d4...your-hmac-secret",
"events": [
"kol:trade",
"deployer:alert"
],
"filters": {
"min_sol": 1
},
"is_active": true,
"created_at": "2026-04-03T12:00:00Z"
},
"note": "Save the secret — it will not be shown again."
}/webhooksList all your registered webhooks with delivery status and failure counts.
{
"webhooks": [
{
"id": 1,
"url": "https://your-app.com/webhooks/madeonsol",
"events": [
"kol:trade",
"deployer:alert"
],
"filters": {
"min_sol": 1
},
"is_active": true,
"last_delivered_at": "2026-04-03T14:30:00Z",
"consecutive_failures": 0
}
]
}/webhooks/{id}Get webhook details and the last 20 delivery attempts with status codes, response times, and errors.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Webhook ID |
{
"webhook": {
"id": 1,
"url": "https://your-app.com/webhooks/madeonsol",
"is_active": true,
"consecutive_failures": 0
},
"recent_deliveries": [
{
"event_type": "kol:trade",
"status_code": 200,
"response_time_ms": 142,
"delivered_at": "2026-04-03T14:30:00Z",
"error": null
}
]
}/webhooks/{id}Update webhook URL, events, filters, or re-enable a disabled webhook. Re-enabling resets the failure counter.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Webhook ID |
| url | string | — | New HTTPS URL |
| events | string[] | — | Updated event types |
| filters | object | — | Updated filters |
| is_active | boolean | — | Re-enable (true) or disable (false) |
{
"webhook": {
"id": 1,
"url": "https://your-app.com/webhooks/madeonsol",
"events": [
"kol:trade"
],
"is_active": true,
"updated_at": "2026-04-03T15:00:00Z"
}
}/webhooks/{id}Permanently delete a webhook and all its delivery history.
| Name | Type | Default | Description |
|---|---|---|---|
| id | integer (path) | required | Webhook ID |
{
"deleted": true
}/webhooks/testSend a sample event payload to your webhook URL to verify it's reachable and correctly processing events. Returns the HTTP status code and response time.
| Name | Type | Default | Description |
|---|---|---|---|
| webhook_id | integer | required | ID of the webhook to test |
{
"success": true,
"status_code": 200,
"response_time_ms": 89
}Payload format
Every delivery carries a timestamp + HMAC-SHA256 signature over the raw body.
Every delivery carries X-MadeOnSol-Timestamp (unix ms) and X-MadeOnSol-Signature (HMAC-SHA256 of <timestamp>.<body> with your secret). Verify and reject anything older than 5 minutes.
X-MadeOnSol-Timestamp: <unix milliseconds> X-MadeOnSol-Signature: <hmac-sha256-hex of "<ts>.<body>"> X-MadeOnSol-Event: kol:trade Content-Type: application/json
import crypto from "node:crypto";
const ts = req.headers["x-madeonsol-timestamp"];
const sig = req.headers["x-madeonsol-signature"];
const body = await readRawBody(req); // raw bytes
if (Math.abs(Date.now() - Number(ts)) > 5 * 60 * 1000) {
return res.status(401).end();
}
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(`${ts}.${body}`)
.digest("hex");
if (!crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(sig)
)) return res.status(401).end();PATCH /webhooks/:id and {"is_active": true}.| kol:trade | KOL wallet buys or sells a token |
| kol:coordination | Multiple KOLs converge on the same token |
| deployer:alert | Tracked deployer launches a new token |
| deployer:bond | Tracked deployer's token graduates bonding curve |
| wallet_tracker:event | Swap or transfer on a wallet in your watchlist (subscriber-scoped) |
| sniper:deploy | Pre-confirm pump.fun deploy detected (PRO+; PRO is curated to elite/good deployers, ULTRA sees every tier) |
| rhc:kol_trade | Tracked KOL buys or sells on Robinhood Chain (PRO+). EVM-native payload — 0x addresses, eth_amount, tx_hash. |
| copytrade:signal | Matched copy-trade rule — configured via POST /copytrade/subscriptions, NOT /webhooks. Uses a per-rule HMAC secret. |
| min_sol | number | Minimum SOL amount (for kol:trade). Solana events only — a silent no-op on rhc:kol_trade, whose payload carries eth_amount, not sol_amount. |
| action | string | "buy" or "sell" (for kol:trade) |
| kol_name | string | Filter by specific KOL name. Solana events only — RHC payloads do not carry this field, so setting it drops every rhc:kol_trade event. |
| deployer_tier | string[] | Filter by deployer tiers: ["elite", "good"] |
| min_kols | number | Minimum KOL count (for kol:coordination) |
WebSocket streams
15 channels on one socket: kol:trades, deployer:alerts, copytrade:signals (PRO/ULTRA), six Robinhood Chain channels — rhc:kol_trades, rhc:copytrade:signals, rhc:price_alert:events, rhc:kol:coordination (PRO+), rhc:dex_trades and rhc:kol:first_touches (ULTRA+) — and the all-DEX firehose on its own ULTRA-only endpoint (2 connections).
/stream/tokenGet a 24-hour authentication token for the WebSocket streaming server. Idempotent while your current token has >6h left (the same token is returned — safe for multi-process clients); on rotation the old token stays valid for 60s. Own rate bucket (10/min) — REST traffic never locks you out of minting. Expiring tokens are rotated server-side and pushed to live connections as a token_refresh frame, so healthy connections are never closed at the 24h mark.
{
"token": "dGhpcyBpcyBhIHNhbXBsZSB0b2tlbg...",
"expires_at": "2026-04-04T12:00:00Z",
"ws_url": "wss://madeonsol.com/ws/v1/stream",
"dex_ws_url": "wss://madeonsol.com/ws/v1/dex-stream (Ultra only)",
"usage": "Connect: wscat -c \"wss://madeonsol.com/ws/v1/stream?token=YOUR_TOKEN\" — then send {\"type\":\"subscribe\",\"channels\":[\"kol:trades\"]}. You receive NO events until you subscribe.",
"subscribe_example": {
"type": "subscribe",
"channels": [
"kol:trades"
]
}
}wss://madeonsol.com/ws/v1/streamReal-time event streaming via direct WebSocket connection to madeonsol.com. After connecting, you MUST send a subscribe message — no events are delivered until the server acks it with {type:'subscribed'}. If no channels are active after 10s the server sends a {type:'hint'} frame. Expiring tokens arrive in-band as {type:'token_refresh'} — store the new token for your next reconnect. Pro: 1 concurrent connection. Ultra: 3 concurrent connections. 30-second heartbeat.
| Name | Type | Default | Description |
|---|---|---|---|
| token | query param | required | Authentication token from POST /stream/token |
{
"_subscribe": {
"type": "subscribe",
"channels": [
"kol:trades",
"deployer:alerts"
],
"filters": {
"min_sol": 1
}
},
"_event_kol_trade": {
"channel": "kol:trades",
"event": "kol:trade",
"data": {
"kol_name": "Cented",
"action": "buy",
"sol_amount": 5.27,
"token_symbol": "PEPE",
"market_cap_usd_at_trade": 28430,
"price_usd_at_trade": 0.0000284,
"mc_change_pct": {
"5m": 8.2,
"1h": 62.1,
"4h": 87
},
"volume_usd": {
"5m": 42000,
"1h": 340000,
"4h": 920000
},
"mev_volume_pct": {
"1h": 18.4
}
},
"ts": 1712160000000
},
"_event_deployer": {
"channel": "deployer:alerts",
"event": "deployer:alert",
"data": {
"deployer_tier": "elite",
"token_symbol": "NEW",
"alert_type": "new_deploy",
"deployer_sol_balance": 42.5301,
"mc_change_pct": {
"5m": 250,
"15m": 480
},
"volume_usd": {
"5m": 12000
}
},
"ts": 1712160000000
},
"_event_graduation": {
"channel": "token:graduations",
"event": "token:graduation",
"data": {
"token_mint": "8vdc...pump",
"token_symbol": "JUNIE",
"time_to_bond_minutes": 38,
"deployer_wallet": "7vfC...rXs2",
"deployer_tier": "rising",
"market_cap_usd": 24180,
"bonded_at": "2026-06-07T09:00:00Z"
},
"ts": 1712160000000
},
"_channels": [
"kol:trades",
"kol:coordination",
"kol:first_touches",
"deployer:alerts",
"wallet_tracker:events",
"copytrade:signals",
"price_alert:events",
"sniper:deploys",
"token:graduations",
"rhc:kol_trades",
"rhc:dex_trades",
"rhc:copytrade:signals",
"rhc:price_alert:events",
"rhc:kol:coordination",
"rhc:kol:first_touches"
],
"_rhc_channels_note": "The last six channels are Robinhood Chain (chain id 4663) and ride the SAME socket as the Solana channels — one token, one connection. Payloads are EVM-native (evm_address, token_address, eth_amount, tx_hash), never the Solana field names. rhc:kol_trades (PRO+), rhc:dex_trades (ULTRA+, every swap on the chain), rhc:copytrade:signals (PRO+, user-scoped to your own /rhc/copytrade rules), rhc:price_alert:events (PRO+, user-scoped to your own /rhc/price-alerts), rhc:kol:coordination (PRO+, user-scoped to your own /rhc/kol/coordination/alerts), rhc:kol:first_touches (ULTRA+). Rule-backed RHC channels deliver nothing until you create the matching rule.",
"_velocity_note": "Every event carrying a token_mint is enriched with velocity context: mc_change_pct, volume_usd (organic, MEV-stripped), and mev_volume_pct keyed by 5m/15m/1h/2h/4h windows. Window keys are only present when the token has been tracked long enough — branch on history_age_seconds rather than probing for missing keys. Reorg-safe (sourced from CONFIRMED-commitment swap stream).",
"_copytrade_note": "copytrade:signals is user-scoped — only signals from your own rules are delivered. Configure rules via POST /copytrade/subscriptions.",
"_graduation_note": "token:graduations fires for EVERY pump.fun graduation (bonding curve complete → PumpSwap migration), tracked deployer or not — unlike deployer:bond on deployer:alerts, which covers tracked deployers only. deployer_tier is 'unranked' for unknown deployers; the deployer_tier array filter applies. Real-time detection paths only — reconciler-recovered bonds (rare, minutes-stale) are not emitted."
}wss://madeonsol.com/ws/v1/dex-streamULTRANormalized real-time trade stream across 15 Solana DEX programs (Pump.fun, Pump AMM, Raydium AMM/CPMM/CAMM, Jupiter v6, Orca Whirlpool, Meteora DBC/DAMM, LaunchLab/Bonk.fun) via direct WebSocket. Ultra-only. 2 concurrent connections per user, up to 10 named subscriptions per connection with independent filters, dynamic updates without disconnect, and optional historical replay (up to 500 trades).
| Name | Type | Default | Description |
|---|---|---|---|
| token | query param | required | Authentication token from POST /stream/token (Ultra tier) |
{
"_subscribe": {
"type": "subscribe",
"sub_id": "fresh-pumpfun",
"replay": 50,
"filters": {
"dex": "pumpfun",
"token_age_max_seconds": 300,
"min_sol": 0.5,
"action": "buy"
}
},
"_update": {
"type": "update",
"sub_id": "fresh-pumpfun",
"filters": {
"dex": [
"pumpfun",
"pumpamm"
],
"min_sol": 1
}
},
"_unsubscribe": {
"type": "unsubscribe",
"sub_id": "fresh-pumpfun"
},
"_list": {
"type": "list"
},
"_event": {
"channel": "dex:trades",
"sub_id": "fresh-pumpfun",
"data": {
"wallet": "7vfC...rXs2",
"mint": "EPjF...Dt1v",
"action": "buy",
"sol_amount": 2.5,
"token_amount": 50000,
"tx_signature": "5K7j...",
"block_time": 1712160000,
"program": "6EF8...wF6P",
"dex": "pumpfun"
},
"replay": false,
"ts": 1712160000000
},
"_filters": "At least one targeting filter required. Targeting: token_mint(s) (max 50), wallet(s) (max 50), dex (pumpfun|pumpamm|pumpswap|raydium|jupiter|orca|meteora|launchlab — single or array), program (raw program ID), deployer_tier (elite|good|moderate|rising|cold|unranked — single or array), token_age_max_seconds, market_cap_max_sol, market_cap_min_sol. Refinement: min_sol, max_sol, action (buy|sell).",
"_notes": "token_age uses a persisted first-seen lookup (survives restarts). market_cap is computed from the in-memory price × cached supply (1h TTL); the first trade for an unseen mint won't match a market_cap filter while the supply fetch is in flight, but every following trade for that mint will. deployer_tier is null/'unranked' for any mint without a tracked deployer. Replay is served from a server-side buffer (not connection-scoped) holding roughly the last 5 minutes of firehose history at typical volume — it backfills trades from before your connection existed. Replayed trades are flagged replay:true, delivered newest-first (sort by block_time client-side), and followed by a replay_done message; you receive the N most recent trades matching your filters.",
"_graduations": "Subscriptions that scope mints via token_mint(s) also receive in-band graduation frames: { channel: 'dex:graduations', sub_id, data: { token_mint, token_symbol, time_to_bond_minutes, deployer_wallet, deployer_tier, market_cap_usd, bonded_at }, ts } — the pump.fun bond lands on the same connection as the trade flow, no separate poll. Subs without mint scoping don't receive them (use the token:graduations channel on /ws/v1/stream for the global feed)."
}/stream/sessionsList your live WebSocket sessions across both stream servers (event stream + DEX firehose). Reflects in-memory connection state, not historical logs, so every id returned can be passed to DELETE /stream/sessions/{id} to free that slot. Use this when a redeploy or process restart on your side leaves a half-open socket holding a connection slot and new connections are rejected with code 4002 (connection limit reached). Pro/Ultra.
{
"sessions": [
{
"id": "48213",
"service": "ws-streaming",
"tier": "ULTRA",
"channels": [
"kol:trades"
],
"connected_at": "2026-06-29T19:42:11Z",
"remote_ip": "203.0.113.7",
"messages_sent": 142
},
{
"id": "48217",
"service": "dex-stream",
"tier": "ULTRA",
"channels": [
"dex:trades"
],
"connected_at": "2026-06-29T19:43:02Z",
"remote_ip": "203.0.113.7",
"messages_sent": 5310
}
],
"count": 2
}/stream/sessions/{id}Force-close one of your own live WebSocket sessions and release its connection slot immediately — the self-serve fix for a 4002 lockout after a deploy overlap (e.g. an old + new instance briefly running at once). The {id} is from GET /stream/sessions; you can only terminate your own sessions. The socket is closed with code 4002. Returns 404 if no live session with that id belongs to your key. Pro/Ultra.
| Name | Type | Default | Description |
|---|---|---|---|
| id | path param | required | Session id from GET /stream/sessions |
{
"evicted": true,
"id": "48213"
}Reference
The boring but useful.
Deployer tiers
Bond rate is the headline outcome: percent of launched tokens that graduate the bonding curve.
| Tier | Criteria | Alert bond rate |
|---|---|---|
| Elite | 5+ deploys, 5+ bonds, 40%+ lifetime, 50%+ recent | ~56% |
| Good | 3+ deploys, 3+ bonds, 25%+ lifetime, 30%+ recent | ~17% |
| Rising | 1–3 deploys with 100% bond rate | Varies |
| Moderate | Lower rates, not tracked for alerts | — |
| Cold | Last 10 outcomes all failed | — |
Errors
All errors return JSON with an error string. Rate-limit headers ship on every response.
401 UnauthorizedMissing or invalid API key.
{"error": "Unauthorized"}403 ForbiddenValid key but your tier doesn't have access to this endpoint.
{"error": "This endpoint requires PRO or ULTRA tier"}422 Unprocessable EntityInvalid request parameter (bad wallet address, out-of-range limit, etc.).
{"error": "Invalid wallet address"}429 Too Many RequestsRate limit hit. Check X-RateLimit-Remaining and retry after X-RateLimit-Reset.
{"error": "Rate limit exceeded. Resets at 2026-04-12T15:00:00Z"}500 Internal Server ErrorSomething went wrong on our side. Check /api/v1/status for service health.
{"error": "Internal server error"}Rate-limit headers on every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (Unix timestamp).
Versioning
Every endpoint lives under /v1. Here is exactly what that promise means.
New endpoints and new optional response fields ship within v1 without prior notice. Write parsers that tolerate unknown fields — that's the only forward-compatibility requirement we place on you.
Within v1, existing response fields never change type or meaning, and documented fields don't disappear. A change that would break a working integration ships as a new endpoint or a new version prefix — never as a mutation of a route you already depend on.
If a v1 endpoint or field must be retired, you get at least 30 days' notice via the changelog and an email to every API key that called it in the preceding 90 days. The endpoint keeps working through the entire window.
Every API change — additive or deprecating — is recorded in the changelog. The machine-readable GET /api/v1/openapi.json spec and GET /api/v1/postman.json collection are regenerated with each release, so codegen pipelines can diff them.
SDKs
TypeScript and Rust for the REST API. TypeScript and Python for x402.
$ npm install madeonsol
$ pip install madeonsol-x402
$ cargo add madeonsol
Authorization: Bearer msk_… on every request. The key is generated at /developer — no payment to start, no signup gates. AI agents that don't have an account can pay per call via /x402.X-RateLimit-Reset so your client can back off precisely. Daily counters reset at midnight UTC.X-MadeOnSol-Signature (HMAC-SHA256 of <timestamp>.<raw-body>). Hash the raw body — NOT the parsed JSON — with your webhook secret and compare with timingSafeEqual. See the payload format section for a Node verifier.npm i madeonsol) or Rust (cargo add madeonsol). x402 agents: TypeScript or Python (pip install madeonsol-x402) — both ship LangChain and CrewAI toolkits. Python REST SDK is on the roadmap; meanwhile any HTTP client works.POST /stream/token again — only one token is active at a time. Subscriptions don't replay automatically across reconnects; re-send the subscribe message and set replay if you need historical fill.before cursors on the time-series endpoints to page back through full history. Leaderboard and PnL rankings aggregate selectable windows up to 180 days. For bulk historical backfills email [email protected].Ready when you are
200 calls/day, no payment to start. Pay by card, USDC, or SOL when you outgrow it.