Skip to main content

madeonsol-x402

PyPI Python Downloads GitHub stars License: MIT

Star on GitHub · 📂 Examples · 📚 API docs

Python SDK for the MadeOnSol Solana KOL intelligence API.

Real-time Solana trading intelligence: track 1,069 KOL wallets with <3s latency on paid keys and x402 pay-per-call (free-tier live feeds are 5-min delayed), score 23,000+ Pump.fun deployers, surface deshred deploy signals ~500ms before on-chain confirmation, score 1M+ early-buyer wallets (incl. dump-cluster detection), push every pump.fun graduation, expose bundle-cohort supply retention (held % of supply), verify any wallet's current on-chain holdings, and stream every DEX trade. Free tier: 200 requests/day across 40+ endpoints (live feeds 5-min delayed) — no signup payment. Get a key at madeonsol.com/pricing.

New in 1.29.0 — deployer reputation as-of a date, and creator-fee rewards. rest.deployer_as_of(wallet, date=) binds GET /deployer-hunter/{wallet}/as-of: the deployer's reputation exactly as it stood on date (default today, UTC) — the latest write-on-change snapshot at or before it, so a backtest sees only what was knowable then. snapshot.snapshot_date can predate the requested date (write-on-change); snapshot.carried is True when the state was recorded earlier and had not changed by then. No snapshot at or before dateas_of: False, snapshot: None — nothing is ever synthesized. date must be ≥ 2026-04-07 and not in the future. rest.deployer_rewards(wallet) binds GET /deployer-hunter/{wallet}/rewards: pump.fun creator-fee rewards, answered two ways that are never merged — collected (what actually reached the wallet: direct vault claims kept 90 days, social-handle claims, shareholder payouts on any token) and attributed (every payout on the tokens it deployed, split to_self/to_others + redirected_pct). Every money field is {sol, usdc, usd}; usd is None (never a silent 0) when a SOL amount exists and no SOL price was available. top_tokens/top_recipients (≤10, USD-sorted) show where attributed fees went, recipients flagged is_self/is_social_pda. Works for non-deployers too (is_deployer: False, attributed empty). Keyed (msk_) API only — not on the x402 rail; BASIC gets HTTP 403.

New in 1.28.0 — token surges & revivals: momentum fires with the honest half attached. rest.tokens_surges(kind=, tier=, mint=, since=, before=, min_mc_usd=, max_mc_usd=, min_buys=, launchpad=, deployer_tier=, exclude_flags=, only_clean=, stats=, days=, limit=) binds GET /tokens/surges (PRO+): every token momentum fire, newest first. Two kinds, one row shape. surge — a token < 30 min old whose market cap runs hard against its launch MC, in three tiers that each fire at most once per mint: early (≤10 min, ≥$12k, ≥3× launch), strong (≤30 min, ≥$30k, ≥6× launch and ≥2× the lowest sample of the last 3 min — it is climbing now), breakout (≤2 min, ≥$45k, ≥8×). A tier must be sustained (current tick and a sample ≥10 s older; nothing fires before 20 s of age) — a same-slot bundle marked to $475k at age 1 s is a spike, not a surge. revival — a token with no 1-minute trade candle for ≥24 h that starts trading again, confirmed only by the tape (≥5 buys, ≥$500 buy volume, MC ≥1.5× the pre-dormancy close), never by the price mark; tier is None. Hard gates on both: liquidity ≥$1.5k and ≥2 % of MC, and the MC gained must be paid for by buy volume (a price mark in a spoof pool moves MC on ~$0). Every row carries the burst tape (source candles / wallet_trades; unique_buyers only where the mint is in trade coverage — wallet_data_available False otherwise, never an inferred zero), kol buyers, the first-20 early_buyers cohort (bundled / sold / sniper wallets), deployer reputation and risk_flags (bundled_launch, few_buyers, wash_pattern, thin_liquidity, cold_deployer, sniper_heavy, early_buyers_exiting, sell_pressure, no_tape_trades, no_prior_price, mint_authority_active, transfer_fee). Rows ≥65 min old carry the +1 h outcome; stats=True prints per-(kind, tier) hit-rates (up_1h_pct, median_peak_multiple, doubled_1h_pct) — out-of-sample by construction. Stream: token:surges (events token:surge / token:revival — the same row minus outcome; subscribe filters kinds, tiers, launchpads, exclude_flags, min_mc_usd / max_mc_usd, deployer_tier) — added to CHANNELS / EVENT_NAMES; the webhook registry accepts token:surge / token:revival with the same filters. LangChain / CrewAI tool: MadeOnSolTokenSurges. Keyed (msk_) API only — not on the x402 rail; BASIC gets HTTP 403.

New in 1.27.1 — stream tokens never expire. POST /stream/token (rest.get_stream_token()) now returns the same token on every call, forever. It stops working only if your subscription lapses or you call rest.get_stream_token(rotate=True) to replace it (the previous value keeps working for 60 s). expires_at and the new next_refresh_at are always None (kept for wire compatibility — do not schedule refreshes on them); the response gains rotated (bool) and lifetime (str). The server never rotates on its own and never sends token_refresh unless you rotated; a 4001 close means "mint again" (lapsed or rotated), never a timer. Prefer Authorization: Bearer <token> on the WebSocket handshake — ?token= still works and is masked in access logs. client.stream() already does the right thing (it calls get_stream_token() on every (re)connect); no code change needed on your side.

New in 1.27.0 — token locks & vesting, upcoming unlocks, and pump.fun creator-fee sharing. Five keyed (PRO+) REST bindings + two WebSocket channels. rest.token_locks(mint, status=, program=, limit=) — every on-chain Streamflow / Jupiter Lock / Bonfida vesting contract on a mint with the schedule (start / cliff / period / end), the terms (cancelable_by_sender — a cancelable lock is a weaker promise — cancelable_by_recipient, transferable, can_topup) and a live-derived view (locked_raw now, unlocked, withdrawn, claimable, status, next_unlock), plus a summary (exact lock_count, distinct_lockers, locked / deposited totals as raw + ui + usd + % of supply, unlocking_7d_* / unlocking_30d_*, nearest next_unlock, active_cancelable_by_sender). rest.token_locks_feed(since=, before=, mint=, sender=, recipient=, program=, kind=, status=, min_usd=, min_pct_of_supply=, include_estimated=, limit=) — cross-token feed of NEW contracts, newest first, cursor pagination.next_since / next_before. rest.token_unlocks(within=, mint=, program=, kind=, min_usd=, min_pct_of_supply=, sort=, limit=) — upcoming unlock EVENTS (cliff / period / final / tranche) inside 1h90d with amount_* and window_amount_*. LP locks are NOT included in any of the three. rest.token_fee_shares(mint) — the pump.fun SharingConfig: who receives what share (bps) of a coin's creator fees, is_admin / is_social_pda (fees earmarked for an X account etc. — social.platform 2 = X, user_id = the platform-native numeric id), redirected_bps, social_bps, is_default: true = 100% to the creator, plus the distributions rollup and config history. rest.token_fee_claims(type=, mint=, recipient=, actor=, social_platform=, social_user_id=, min_sol=, since=, before=, limit=) — the fee-event feed (distribution with payouts[], social_claim, shares_created / shares_updated / shares_reset, creator_transferred, creator_claim only when asked via type=). Fee history starts 2026-08-17. All base-unit amounts (*_raw) are strings; ui / usd / pct are None when decimals or price are unknown. Streams: token:locks (event token:lock, one frame per new contract) and token:fee_claims (event token:fee_claim) — added to CHANNELS / EVENT_NAMES. LangChain / CrewAI tools: MadeOnSolTokenLocks, MadeOnSolTokenLocksFeed, MadeOnSolTokenUnlocks, MadeOnSolTokenFeeShares, MadeOnSolTokenFeeClaims. Keyed (msk_) API only — none of these are on the x402 rail; BASIC gets HTTP 403.

New in 1.26.0 — live holder census: exact holder count, labelled holders, and pools that are named, not just excluded. rest.token_holders(mint) (plus MadeOnSolTokenHolders LangChain / CrewAI tools) binds GET /tokens/{mint}/holders (PRO+): every token account of the mint read from the ledger at confirmed and merged per owner, so concentration.holder_count is EXACT (distinct non-zero owners minus pools / bonding curves / burns) — never a trade-derived estimate; it is null only when the provider refuses the census for a mega-cap, in which case you get the top-20 view and source.census_fallback_reason says so. Each disclosed owner carries our labels (deployer / kol / early_buyer / bundle / bot / dump_cluster — empty means unknown to us, not clean), and excluded[] NAMES what was taken out of the circulating denominator: reason = pool (with dex + pool_address), bonding_curve (pump.fun / LaunchLab), burn, or program_account only when we genuinely cannot attribute the PDA; pool_pct / burned_pct / program_pct split the exclusion. Amounts are raw u64 strings. Disclosure: PRO ranks 1–10, ULTRA 1–50, BUSINESS 1–100 — the maths is tier-independent. Big tokens take 5–30 s upstream: you get 503 holder_scan_in_progress with retry_after_seconds: 20 while the scan finishes into the cache, and the retry is instant. Keyed (v1) only — the census is not on the x402 rail.

New in 1.25.0 — two prices on the trade tape, and the right one is now the default. The trade tape now tells you what a trade actually cost. price_sol/price_usd on each trade are THIS trade's executed price — sol_amount / token_amount, reconciling exactly with the amounts on the same row and with the PnL endpoints. Because sol_amount is the wallet's net SOL movement, that is the trader's all-in effective rate: swap fee and any account rent included, not the pool mid. The market-cap tracker's canonical pool price moved to the new market_price_sol/market_price_usd fields — it is sampled once per token per pool update, so every trade in the same slot shares it. Until now price_sol carried that canonical value and disagreed with the row's own amounts by a 7.9% median (p90 ~74%): a stale market price reads low in a pump and high in a dump, so anything you averaged out of the tape inherited the bias instead of cancelling it. Use price_sol for cost basis, fills and PnL; market_price_sol for a per-token series independent of trade size and direction. Both rest.token_trades(mint) and rest.wallet_trades(address) carry all four fields — wallet_trades returned amounts and no price at all before.

New in 1.24.0 — the Deployer Hunter surface completed. Seven new operations that existed on the API but had no SDK binding: deployer_leaderboard(), deployer_stats(), deployer_profile(), deployer_tokens(), deployer_alert_stats(), deployer_best_tokens() and deployer_recent_bonds() (poll it incrementally with next_since). Read bonding_rate (lifetime) against recent_bond_rate (rolling) — the gap between them is the signal, not either number alone. runner_rate only means something once labeled_tokens >= 3, and an untracked wallet returns a profile with zeroed counters, not a 404, so check total_deployed before reading a 0% bond rate as a track record. Dependency ranges are now bounded to the versions actually tested (@x402/* ^2.x, @solana/kit ^5.5.1) instead of open-ended >=0.0.1, and the lazily-imported x402 peers are marked optional — a keyed install no longer pulls the whole Solana stack.

New in 1.23.0Pool depth / price-impact + dev self-activity on the risk score. rest.token_depth(mint, sizes=None) (GET /tokens/{mint}/depth, PRO+) answers "how much SOL does it take to move the price N%" per pool: each depth-computable pool returns spot_price_sol, fee_pct, source ('stream' for constant-product AMMs served zero-RPC from stream reserves, 'live_rpc' for pump.fun/bonk curves priced from a live read of the curve's VIRTUAL reserves), reserves_age_ms, per-size quotes (size_sol, tokens_out, avg_price_sol, price_impact_pct), and to_move_price (SOL to move price '1pct'/'5pct'/'10pct'). sizes is a CSV string or list of floats (max 8, each >0 and ≤10000; default 0.5,1,5,10); the response carries sol_usd, sizes_sol, primary_pool, and honesty-first unsupported_pools — concentrated pools (CLMM/Orca/DLMM), Meteora-DBC curves, and unclassified pools come back with a reason instead of a wrong number. Exposed as the madeonsol_token_depth (LangChain) / "MadeOnSol Token Depth" (CrewAI) tool. Plus rest.token_risk(mint) responses gain a top-level dev object — deployer self-activity for the mint: wallet, launchpad, deployed_at, create-tx buy_sol/buy_tokens/buy_supply_pct, post-create bought_tokens_after/sold_tokens/sold_sol with first_sell_at/last_sell_at, live on-chain holdings_tokens/holdings_supply_pct, wallet_empty (bool | None), and transferred_out (bool | None — chain balance well below the trade-derived expectation, i.e. tokens moved without a swap) — plus as_of. dev is None when the mint has no tracked deploy row.

New in 1.22.0Batch wallet classification, token trade tape + 7 endpoints go keyless. rest.wallet_batch_classify(["addr1", ...]) returns reputation flags for 1–100 wallets in one call (counts as 1 request): per wallet is_sniper / is_bundler / is_dumper / is_kol (+ kol_name), bot_confidence (string enum 'none'/'low'/'medium'/'high', None when not alpha-tracked), and a dump_cluster block (dump_cohorts, runner_cohorts, total_cohorts, as_of). Flags are pump.fun-pipeline scoped — False = not observed, NOT verified clean; is_bundler is lifetime, is_dumper is a rolling 42d window. rest.token_trades(mint, limit=100, cursor=None, action=None, wallet=None, since=None, until=None) is the mint-scoped trade tape — cursor-paginated raw trades (default FULL history; capture starts 2026-04-12) with a coverage honesty block. Both PRO+. wallet_stats() flags gain the same reputation flags + dump_cluster, and bot_confidence is now correctly a string enum (a server bug made it always None before — real values now). token_risk() inputs and sniper_recent() deploys gain the slot-window sniper_footprint/footprint rollup. The keyless x402 catalog grows 18 → 25: new MadeOnSolClient (keyless-capable) methods token_candles ($0.01), almost_bonded ($0.01), token_top_traders ($0.02), token_cap_table ($0.02), sniper_recent ($0.01), deployer_trajectory ($0.01) — joining token_flow ($0.01).

New in 1.21.0Verified wallet holdings. rest.wallet_holdings(address, limit=200, min_value_usd=0) reads the wallet's actual SPL + Token-2022 token accounts and SOL balance directly from chain, enriches each with our price/MC/name/symbol data, and computes transfer_delta (on-chain amount minus trade-derived net position) to expose non-swap flows — airdrops, insider funding, wallet-hopping. Distinct from wallet_positions (trade-derived FIFO): holdings is "what they actually hold right now". Returns address, sol_balance, holdings (each with mint, symbol, name, amount, amount_raw, decimals, token_program ('spl' | 'token2022'), price_usd, value_usd, market_cap_usd, is_bonded, trade_derived_amount, transfer_delta), a summary (token_accounts, non_zero, returned, priced, total_value_usd, truncated), verified_at, trade_window_days, cache_hit, and ttl_seconds. limit 1–500 (default 200), min_value_usd ≥ 0 (default 0). ULTRA only.

New in 1.20.0Bundle-cohort holdings. rest.token_bundle(mint) reveals how much of a token's supply its launch bundle still holds. The bundle summary carries wallet_count, bundle_kind ('atomic_tx' | 'same_slot' | 'none'), held_pct_of_supply (net-held / circulating supply — the HEADLINE signal, null when supply is unknown), held_ratio (net-held / buy-volume — churn-sensitive, secondary), fully_exited, buy_volume (cumulative buy volume — NOT distinct tokens, can exceed supply), and tokens_held (swap-derived net position). All tiers reach the endpoint, field-gated by tier: BASIC get the bundle summary only (wallets: []), PRO adds the top-10 wallets with flags only (rank, wallet, held_ratio, has_sold, atomic, is_kol), and ULTRA adds per-wallet identity (kol_name, win_rate, bot_confidence, tokens_held).

New in 1.19.0Batch risk scoring + stream-session control. rest.tokens_batch_risk(["mint1", "mint2", ...]) scores 1–50 base58 mints for rug-risk/safety in a single call (counts as 1 request against quota). Returns { "tokens": [...], "count": N } where each entry mirrors the single-mint rest.token_risk() shape (risk_score, band, factors, inputs) plus an as_of ISO-8601 timestamp; untracked mints come back as { "mint", "error": "not_tracked" } and don't fail the batch. tokens preserves de-duplicated input order. PRO/ULTRA only. Plus WebSocket session control: rest.stream_sessions() lists your live sessions across both stream services (each with id, service, tier, channels, connected_at, remote_ip, messages_sent) and rest.kill_stream_session(id) force-terminates one and frees its connection slot — the self-serve fix for a 4002 connection-limit lockout after a deploy overlap leaves a ghost socket. Both PRO/ULTRA only, exposed as the madeonsol_stream_sessions / madeonsol_kill_stream_session (LangChain) and "MadeOnSol Stream Sessions" / "MadeOnSol Kill Stream Session" (CrewAI) tools.

New in 1.18.0Almost-bonded discovery + trending sorts. rest.almost_bonded(min_progress=90, min_velocity_pct_per_min=0.5, deployer_tier="elite", sort="eta_asc", limit=25) returns pre-bond pump.fun tokens near graduation, ranked by velocity (Δprogress/min) — "95% and accelerating" beats "92% stalled". Each token carries progress_pct, velocity_pct_per_min, eta_minutes, stalled, real_sol_reserves, market_cap_usd, liquidity_usd, authorities_revoked, deployer_tier, and age_minutes. sort is 'velocity_desc' (default) / 'progress_desc' / 'eta_asc'. PRO/ULTRA only (keyed). Exposed as the madeonsol_almost_bonded (LangChain) / "MadeOnSol Almost Bonded" (CrewAI) tool. Plus rest.tokens_list(sort=...) gains four momentum sorts — 'mc_change_5m_desc', 'mc_change_1h_desc', 'volume_1h_desc', and 'trending' (composite recent-volume × positive-momentum rank).

New in 1.17.0Token money-flow. client.token_flow(mint, window="1h") (and the async await client.token_flow_async(mint, window="1h")) aggregates buy/sell pressure for a token over a rolling '1h' or '24h' window. Returns mint, window, from, unique_wallets, unique_buyers, unique_sellers, buy_count, sell_count, total_trades, buy_sol, sell_sol, net_sol, and trades_per_wallet. PRO+ (keyed). Also: deployer_alerts() items now carry deployer_sol_balance (float | None) — the deployer wallet's SOL balance at alert time (None for historical rows).

New in 1.16.0Live token snapshot + Signal Scorecard (keyless x402). client.token(mint) returns a live { "token": {...} } snapshot (price_usd/price_sol, market_cap, fdv_usd, liquidity_usd, liquidity_to_mc_ratio, primary_dex, is_token_2022, transfer_fee_bps, top_buyers=[{name, sol_amount}]). client.signal_performance(name, history=False) returns out-of-sample reliability for a named signal (hit_rate, base_rate, lift, sample_n, window_days, test_from/test_to, plus metric_type, outcome, methodology, as_of; per-day series when history=True) — valid names: dump_cluster_count, runner_rate, recycled_early_buyer_count, coordination_count. client.signals() (free) lists the signal catalog.

New in 1.15.0Token OHLCV candles. rest.token_candles(mint, tf="1h", limit=200, from_=None, to=None) returns 1-minute-derived OHLCV candles aggregated to a timeframe ('1m' | '5m' | '15m' | '1h' | '4h' | '1d'). Each candle has t, open, high, low, close, volume_usd, trades, and market_cap_usd. PRO returns OHLCV over the last 30 days; ULTRA adds per-candle net-flow fields (buy_volume_usd, sell_volume_usd, net_volume_usd, buy_count, sell_count, volume_mev_usd, open_liquidity_usd, close_liquidity_usd, high_mc_usd, low_mc_usd) and full history.

New in 1.14.0Token risk score. rest.token_risk(mint) returns a transparent 0–100 rug-risk/safety score (higher = riskier) with a band ('safe' | 'caution' | 'danger'), an explainable factors array, and the raw inputs (mint/freeze authority, liquidity, liq-to-MC ratio, transfer fee, launch cohort, deployer bond rate, KOL signal, blacklist). PRO/ULTRA only.

New in 1.13.0rest.tokens_list() gains three new filter params: min_liq_mc_ratio, max_liq_mc_ratio, and deployer_tier ('elite' | 'good' | 'moderate' | 'rising' | 'cold' | 'unranked'). Response items now include liquidity_to_mc_ratio and deployer_tier. KOL leaderboard entries now include median_hold_minutes_30d and percentile_early_entry_30d. /token/{mint} and /token/batch responses now include liquidity_to_mc_ratio, launch_cohort_sol, and launch_cohort_size.

New in 1.12.1 — Deployer alerts/profiles now carry runner_rate + labeled_tokens (fraction of a deployer's labeled tokens that ran vs dumped, gate on labeled_tokens >= 3) plus avg_time_to_bond_minutes.

New in 1.12Graduation events + dump-cluster detection. Subscribe token:graduations for every pump.fun bond in real time (tracked deployer or not). Buyer-quality breakdown adds dump_cluster_count (out-of-sample: 3+ → 94% dump vs 61% base) + recycled_early_buyer_count. DEX firehose: replay buffer deepened to ~5 min; mint-scoped subs get in-band dex:graduations frames.

New in 1.10Deshred Sniper. client.rest.sniper_recent() — deshred deploy feed ~500ms before on-chain confirmation. PRO: elite/good. ULTRA: all tiers + sniper_watchlist_add(). Use sniper:deploys WebSocket for push.

New in 1.9Price alerts, scout leaderboard, coordination history. client.rest.price_alerts_create() (PRO=5, ULTRA=25). scout_leaderboard(), kol_consensus(), peak_history(), coordination_history(). wallet_stats() now returns derived: win_rate, roi, verdict, biggest_miss.

New in 1.8Universal Wallet API. client.rest.wallet_stats(), wallet_pnl(), wallet_positions(), wallet_trades() — FIFO cost-basis PnL for any Solana wallet. PRO+. Cache hits free.

New in 1.7.1 (2026-05-13) — Velocity field shape corrected to match the API: mc_change_pct, volume_usd, mev_volume_pct are top-level on the token response, each keyed by '5m'/'15m'/'1h'/'2h'/'4h'. The 1.7.0 README documented a velocity[window] shape that didn't match the wire format.

New in 1.7.0 (2026-05-12)Token directory + account inspection. client.rest.tokens_list(min_liq=10000, min_volume_1h_usd=5000, max_mev_share_pct=60, mc_change_1h_min_pct=20, sort="mc_desc", min_liq_mc_ratio=0.05, deployer_tier="elite") filters every active mint by MC band, liquidity floor, primary DEX, authority/safety flags, computed 1h volume, MEV-share ceiling, MC-change deltas, liq/MC ratio, and deployer tier. Response items include liquidity_to_mc_ratio and deployer_tier. Default min_liq=2000 skips phantom-MC dust; pass min_liq=0 to opt out. client.rest.me() — read your tier, daily/burst quota state, and per-feature usage in one call (no header parsing). Velocity / MEV-share fields added to every token response: mc_change_pct, volume_usd, mev_volume_pct (each keyed by '5m'/'15m'/'1h'/'2h'/'4h') plus history_age_seconds. /token/{mint} 400s now ship structured code, reason, received_length, example, and docs. Deprecated avg_entry_mc_usd fully removed.

Quick start (10 seconds)

pip install madeonsol-x402
from madeonsol_x402 import MadeOnSolClient
client = MadeOnSolClient(api_key="msk_...")  # free tier at https://madeonsol.com/pricing
trades = client.kol_feed(limit=5, action="buy")

Authentication

Two options:

Method Parameter / Env var Best for
MadeOnSol API key (recommended) api_key / MADEONSOL_API_KEY Developers — get a free key
x402 micropayments private_key / SVM_PRIVATE_KEY AI agents with Solana wallets

v1.0 breaking change: RapidAPI auth has been removed. The MadeOnSol RapidAPI marketplace was retired on 2026-04-19. If you were using rapidapi_key= or RAPIDAPI_KEY, get a free msk_ key at madeonsol.com/pricing.

Install

pip install madeonsol-x402                    # core SDK
pip install madeonsol-x402[langchain]         # + LangChain tools
pip install madeonsol-x402[crewai]            # + CrewAI tools

x402 dependencies are only needed when using private_key / SVM_PRIVATE_KEY.

Quick Start

from madeonsol_x402 import MadeOnSolClient

client = MadeOnSolClient(api_key="msk_your_api_key_here")

# Real-time KOL trades — each trade now includes
# market_cap_usd_at_trade and price_usd_at_trade (real-time MC at the
# moment the swap fired, sourced from our in-memory price tracker).
trades = client.kol_feed(limit=10, action="buy")
for t in trades["trades"]:
    print(f'{t["kol_name"]} bought {t["token_symbol"]} for {t["sol_amount"]:.2f} SOL @ MC ${t.get("market_cap_usd_at_trade") or "?"}')

# KOL convergence signals
signals = client.kol_coordination(period="24h", min_kols=3)

# KOL leaderboard — 180 days of history
leaders = client.kol_leaderboard(period="7d")  # today | 7d | 30d | 90d | 180d

# Deployer alerts (all tiers can filter by tier)
# Each alert carries deployer_sol_balance (float | None) — deployer wallet
# SOL balance at alert time (None for historical rows).
alerts = client.deployer_alerts(limit=10)
elite_only = client.deployer_alerts(limit=10, tier="elite")

# Token money-flow over a rolling window (PRO+) — sync
flow = client.token_flow("So11111111111111111111111111111111111111112", window="1h")
print(flow["net_sol"], flow["unique_buyers"], flow["unique_sellers"])

# Alpha wallet leaderboard (REST)
top = client.rest.alpha_leaderboard(period="30d", sort="win_rate")

# Wallet Tracker (REST)
client.rest.wallet_tracker_add("WALLET_ADDRESS", label="whale")
events = client.rest.wallet_tracker_trades(limit=50)

# Inspect rate-limit headers from the most recent REST call
print(client.rest.last_rate_limit)
# {'limit': 100, 'remaining': 92, 'reset': 1714000000, 'request_id': 'rid_abc123'}

Token money-flow (new in 1.17)

token_flow(mint, window="1h") aggregates buy/sell pressure for a token over a rolling '1h' or '24h' window. PRO+ (keyed). Both sync and async variants are available:

import asyncio
from madeonsol_x402 import MadeOnSolClient

client = MadeOnSolClient(api_key="msk_...")
mint = "So11111111111111111111111111111111111111112"

# Sync
flow = client.token_flow(mint, window="1h")
print(flow["net_sol"], flow["buy_sol"], flow["sell_sol"])

# Async
async def main():
    flow = await client.token_flow_async(mint, window="24h")
    print(flow["unique_wallets"], flow["trades_per_wallet"])

asyncio.run(main())

Response keys: mint, window, from, unique_wallets, unique_buyers, unique_sellers, buy_count, sell_count, total_trades, buy_sol, sell_sol, net_sol, trades_per_wallet.

Real-time streaming (new in 1.11)

Managed WebSocket stream — auto-reconnect, token fetch (the token never expires; get_stream_token() is called on every (re)connect), and typed callbacks handled for you. Needs the stream extra: pip install "madeonsol-x402[stream]".

import asyncio
from madeonsol_x402 import MadeOnSolREST

client = MadeOnSolREST(api_key="msk_...")

async def main():
    stream = client.stream()

    @stream.on("kol:trade")
    async def on_trade(data, evt):
        print(data["token_symbol"], data["action"])

    stream.subscribe(["kol:trades", "deployer:alerts"])
    await stream.run()   # blocks; manages connection + reconnects

asyncio.run(main())

Channels: kol:trades, kol:coordination, kol:first_touches, deployer:alerts, wallet_tracker:events, copytrade:signals, price_alert:events, sniper:deploys, token:graduations (every pump.fun graduation in real time, tracked deployer or not), token:locks (event token:lock — every NEW Streamflow / Jupiter Lock / Bonfida lock or vesting contract, PRO+; LP locks not included), token:fee_claims (event token:fee_claim — every pump.fun fee event: distributions, social-handle claims, SharingConfig changes, PRO+; history starts 2026-08-17), token:surges (events token:surge — a token < 30 min old running ≥3× / ≥6× / ≥8× its launch MC, tier early / strong / breakout, each once per mint, sustained — and token:revival — ≥24 h with no trade candle, then confirmed buys on the tape, tier None; the same row as rest.tokens_surges() minus outcome, risk_flags included; subscribe filters kinds, tiers, launchpads, exclude_flags, min_mc_usd / max_mc_usd, deployer_tier; PRO+). Lifecycle events: open, close, reconnect, heartbeat, error.

LangChain

from madeonsol_x402.langchain_tools import ALL_TOOLS

# Set MADEONSOL_API_KEY or SVM_PRIVATE_KEY env var
agent = create_react_agent(llm, tools=ALL_TOOLS)

CrewAI

from madeonsol_x402.crewai_tools import ALL_TOOLS

agent = Agent(role="Solana Analyst", tools=ALL_TOOLS)

Endpoints

KOL Intelligence (x402-priced — also reachable via msk_ API key)

Method Description
kol_feed() Real-time KOL trade feed (1,000+ wallets)
kol_coordination() Multi-KOL convergence signals
kol_leaderboard() PnL and win rate rankings — windows: today, 7d, 30d, 90d, 180d (180-day retention)
kol_pairs() KOL affinity matrix — which KOLs co-trade the same tokens
kol_hot_tokens() KOL momentum tokens — accelerating buy interest
kol_trending_tokens() Tokens ranked by KOL buy volume
kol_token_entry_order(mint) Ranked KOL first-buyer order for a token
kol_compare_wallets(wallets) Side-by-side comparison of 2–5 KOL wallets
kol_alerts_recent() Live KOL alert feed — clusters, fresh-token buys, heating-up
deployer_alerts() Pump.fun deployer launches with KOL enrichment
wallet_stats(address) New 1.8 · Universal wallet stats (90d) + cross-product flags. $0.005
wallet_pnl(address) New 1.8 · FIFO cost-basis PnL: realized + unrealized, profit factor, drawdown, daily curve, closed + open positions. $0.02
wallet_positions(address) New 1.8 · Open positions with live unrealized from market-cap tracker. Shares /pnl cache. $0.01
wallet_trades(address, ...) New 1.8 · Cursor-paginated raw trades with action / token / since-until filters. $0.005
token(mint) New 1.16 · Live token snapshot — price_usd/price_sol, market_cap, fdv_usd, liquidity_usd, liquidity_to_mc_ratio, primary_dex, is_token_2022, transfer_fee_bps, top_buyers
signal_performance(name, history=False) New 1.16 · Signal Scorecard — out-of-sample hit_rate/base_rate/lift/sample_n per signal (dump_cluster_count, runner_rate, recycled_early_buyer_count, coordination_count)
signals() New 1.16 · Free — signal catalog with per-signal methodology and performance_endpoint
token_flow(mint, window="1h") New 1.17 · PRO+ · Token money-flow over a rolling 1h/24h window — unique wallets/buyers/sellers, buy/sell counts + SOL, net SOL flow, trades per wallet. Async: token_flow_async(mint, window="1h")
token_candles(mint, tf=, limit=, from_=, to=) New 1.22 · OHLCV candles, keyless (PRO slice: 30d). $0.01
almost_bonded(**filters) New 1.22 · Pre-bond pump.fun tokens near graduation, ranked by velocity. $0.01
token_top_traders(mint, limit=, sort=, window_days=, min_bought_sol=) New 1.22 · Wallets ranked by realized PnL/ROI on a token, enriched with KOL/alpha identity. $0.02
token_cap_table(mint) New 1.22 · Early-buyer cap table with PnL/exit/bundle/KOL flags. $0.02
sniper_recent(since=, deployer_tier=, min_bond_rate=, limit=) New 1.22 · Deshred pre-confirm deploy feed (keyless: elite/good scope) with per-deploy footprint snipe rollup. $0.01
deployer_trajectory(wallet) New 1.22 · Deployer skill curve — streaks, rolling bond rate, trend. $0.01
discovery() Free — list all endpoints and prices (25 keyless x402 endpoints)

REST API — KOL/deployer detail

Method Description
rest.kol_pnl(wallet, period=) Deep per-wallet PnL: equity curve, risk metrics, closed positions. ULTRA adds open positions (tokens bought but not yet sold).
rest.kol_timing(wallet, period=) KOL entry/exit timing profile — available on all tiers
rest.deployer_trajectory(wallet) Deployer skill curve — streaks, rolling bond rate, trend — available on all tiers
rest.deployer_history(wallet, limit=90) New 1.20

Alpha Wallet Intelligence

Scored from 1M+ early-buyer records (wallets seen in the first 20 buyers of Pump.fun tokens).

Method Tier Description
rest.alpha_leaderboard(period=, min_tokens=, sort=, exclude_bots=) All Up to 100 results on Free/Pro; ULTRA unlocks 500 + bot signals
rest.alpha_wallet(wallet) ULTRA Full per-token breakdown + bot_signals array
rest.alpha_linked(wallet) ULTRA Wallets behaviorally linked (co-bought 3+ tokens within 2s)

Token Quality

Method Tier Description
rest.token_cap_table(mint) PRO+ First non-deployer early buyers, enriched with PnL/KOL/bot flags. PRO=10, ULTRA=20
rest.token_buyer_quality(mint) All 0–100 buyer-quality score + full breakdown (5-min cached)
rest.token_risk(mint) PRO+ Transparent 0–100 rug-risk/safety score with band, explainable factors, and raw inputs
rest.token_bundle(mint) New 1.20 · All Bundle-cohort holdings — bundle summary with held_pct_of_supply (headline), bundle_kind, fully_exited. BASIC=summary only, PRO=+top-10 wallet flags, ULTRA=+identity
rest.tokens_batch_risk(mints) New 1.19 · PRO+ Bulk risk scoring for 1–50 mints in one call (1 request). Each entry mirrors token_risk + as_of; untracked mints → {mint, error: "not_tracked"}
rest.token_candles(mint, tf, limit, from_, to) PRO+ 1-minute-derived OHLCV candles by timeframe. PRO=OHLCV/30d, ULTRA=+net flow/full history
rest.token_trades(mint, limit=, cursor=, action=, wallet=, since=, until=) New 1.22 · PRO+ Mint-scoped trade tape — cursor-paginated raw trades, default FULL history (capture starts 2026-04-12, pump.fun-pipeline scoped; see the coverage block)
rest.token_pools(mint) New 1.20 · PRO+ Per-venue liquidity map — every DEX pool a token trades in, live vs parked. pools array + summary with total_liquidity_usd, primary_dex, top_pool_share_pct
rest.token_holders(mint) New · PRO+ Live holder census + concentration — who holds NOW. concentration.holder_count is EXACT (mint-scoped getProgramAccounts census; None only when the provider refuses a mega-cap → top-20 fallback with source.census_fallback_reason, never trade-estimated). Each disclosed owner labelled deployer/kol/early_buyer/bundle/bot/dump_cluster; pools / bonding curves / burns EXCLUDED from the circulating denominator and NAMED in excluded[] (pool+dex+pool_address | bonding_curve | burn | program_account). Amounts are raw u64 STRINGS. Disclosure PRO=10, ULTRA=50, BUSINESS=100. Big tokens: first call may be HTTP 503 holder_scan_in_progress (retry_after_seconds: 20) — scan continues + cached, retry is instant. Exposed as madeonsol_token_holders (LangChain) / "MadeOnSol Token Holders" (CrewAI). Key-mode only (not on the x402 rail)
rest.token_locks(mint, status=, program=, limit=) New 1.27 · PRO+ Token locks & vesting on a mint — every Streamflow / Jupiter Lock / Bonfida vesting contract: schedule (start / cliff / period / end), terms (cancelable_by_sender / _recipient, transferable, can_topup), live-derived locked_raw / unlocked / withdrawn / claimable / status / next_unlock, and a summary (exact lock_count, distinct_lockers, locked / deposited raw + ui + usd + % of supply, unlocking_7d_* / unlocking_30d_*, active_cancelable_by_sender). Base-unit amounts are STRINGS; ui/usd/pct None when unknown. LP locks NOT included. Key-mode only
rest.token_locks_feed(since=, before=, mint=, sender=, recipient=, program=, kind=, status=, min_usd=, min_pct_of_supply=, include_estimated=, limit=) New 1.27 · PRO+ Cross-token feed of NEW lock / vesting contracts, newest first (+ per-row token block). Cursors pagination.next_since / next_before; pushed live on WS token:locks. Backfilled Jupiter rows excluded unless include_estimated=True. Key-mode only
rest.token_unlocks(within=, mint=, program=, kind=, min_usd=, min_pct_of_supply=, sort=, limit=) New 1.27 · PRO+ Upcoming unlock EVENTS (cliff / period / final / tranche) across all active contracts inside within=1h…90d (default 7d): unlock_at, in_seconds, amount_*, window_amount_* (total release over the window), token, lock. `sort=soonest
rest.token_fee_shares(mint) New 1.27 · PRO+ pump.fun creator-fee SharingConfig on a mint: shareholders[] with share_bps, is_admin, is_social_pda (+ social.platform 2 = X, social.user_id numeric id, lifetime claimed), redirected_bps, social_bps, is_default (True = 100% to creator), config.source stream|chain; distributions rollup (per-recipient received, past_recipients), history, recent_distributions. Quote base-unit amounts are STRINGS. Fee history starts 2026-08-17. Key-mode only
rest.token_fee_claims(type=, mint=, recipient=, actor=, social_platform=, social_user_id=, min_sol=, since=, before=, limit=) New 1.27 · PRO+ pump.fun fee-event feed, newest first: distribution (+ payouts[]), social_claim, shares_created / shares_updated / shares_reset, creator_transferred; creator_claim only when requested via type=. Cursor pagination.next_since; pushed live on WS token:fee_claims. History starts 2026-08-17. Key-mode only
rest.tokens_surges(kind=, tier=, mint=, since=, before=, min_mc_usd=, max_mc_usd=, min_buys=, launchpad=, deployer_tier=, exclude_flags=, only_clean=, stats=, days=, limit=) New 1.28 · PRO+ Token momentum fires, newest first — kind='surge' (token < 30 min old vs its LAUNCH MC; tier early ≤10 min ≥$12k ≥3× · strong ≤30 min ≥$30k ≥6× and ≥2× the 3-min low · breakout ≤2 min ≥$45k ≥8×; each once per mint, sustained ≥10 s) or 'revival' (no trade candle ≥24 h, then ≥5 buys / ≥$500 buy volume / ≥1.5× the pre-dormancy MC on the tape — never a price mark; tier None). Each row: burst tape (unique_buyers None outside trade coverage), kol, early_buyers (bundled / sold / sniper), deployer, risk_flags, and outcome (+1 h MC / peak / low) once ≥65 min old. stats=True = per-(kind, tier) hit-rates over days. exclude_flags drops rows carrying ANY listed flag; only_clean=True = no flags. Cursors pagination.next_since / next_before; pushed live on WS token:surges. Retention 60 d. Exposed as madeonsol_tokens_surges (LangChain) / "MadeOnSol Token Surges" (CrewAI). Key-mode only

Deshred Sniper Alerts (new in 1.10)

The fastest path to a new pump.fun launch. Deploys are reconstructed from shred-level (deshred) data and surface ~500ms before the chain confirms them. PRO sees elite + good deployers; ULTRA sees every tier and can keep a custom deployer watchlist. For live push use the sniper:deploy webhook or the sniper:deploys WebSocket channel.

Method Tier Description
rest.sniper_recent(limit=, deployer_tier=, min_bond_rate=, since=, watchlist=) PRO+ Deshred deploy feed, newest first. PRO=elite/good, ULTRA=all tiers. watchlist=True (ULTRA) narrows to your watchlist
rest.sniper_by_deployer(wallet, limit=) ULTRA Deshred deploys for one deployer
rest.sniper_watchlist() ULTRA List your custom deployer watchlist (max 50)
rest.sniper_watchlist_add(wallet=/wallets=, label=) ULTRA Add one or many deployers
rest.sniper_watchlist_remove(wallet) ULTRA Remove a deployer
feed = client.rest.sniper_recent(limit=50, min_bond_rate=0.5)
client.rest.sniper_watchlist_add(wallets=["7dEx...4pQ8", "9aBc...2zZ1"], label="alpha devs")
tracked = client.rest.sniper_recent(watchlist=True)  # ULTRA — only your tracked deployers

KOL Coordination Alerts (v1.1 — push signals)

Real-time push alerts when a cluster of KOLs co-buys the same token. Fires within ~1s of the triggering trade (pg_notify push, not polling). Delivered via WebSocket (kol:coordination channel, user-scoped) and/or HMAC-signed webhook. PRO=5 rules, ULTRA=20.

res = client.rest.coordination_alerts_create(
    name="fresh pump cluster",
    min_kols=4,
    window_minutes=15,     # peak-density window (1-60)
    min_score=70,          # 0-100 composite score cutoff
    include_majors=False,  # filter WIF/BONK/POPCAT
    cooldown_min=60,       # one fire per (rule, token) per 60min...
    score_jump_break=10,   # ...unless score jumps +10 vs last fire
    delivery_mode="both",
    webhook_url="https://you.com/hooks/coord",
)
# store res["webhook_secret"] — shown ONCE

coordination_alerts_list(), coordination_alerts_get(id), coordination_alerts_update(id, **fields), coordination_alerts_delete(id).

Webhook signature: X-MadeOnSol-Signature: sha256=<hmac> where hmac = HMAC-SHA256(webhook_secret, timestamp + "." + rawBody), and X-MadeOnSol-Timestamp carries the unix seconds used.

The kol_coordination() response now includes v1.1 fields: peak_window_start/end, peak_kols, peak_buys (the busiest slice within the period), exited_count + per-KOL exited (net-flow-negative wallets), and coordination_score (0-100). Pass min_score=, window_minutes=, include_majors= to filter.

KOL First-Touch Signal (new in 1.3)

Every "first KOL buy on a token mint" event — when 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.

Backtest: S-tier scouts attract ≥3 follow-on KOLs within 4h ~50% of the time vs ~14% baseline (38d / 491k buys / 72,549 events). Public leaderboard at madeonsol.com/kol/scouts.

# REST query — S-tier scouts on tokens younger than 1h
events = client.rest.first_touches(preset="scout", min_scout_tier="S", limit=20)
for e in events["events"]:
    fk = e["first_kol"]
    print(fk["name"], "scouted", e["token_symbol"], f"(scout_score={fk['scout_score']}%)")

# Webhook subscription (Ultra) — HMAC-signed push
res = client.rest.first_touch_subscriptions_create(
    name="S-tier scouts on pump tokens",
    filters={"min_scout_tier": "S", "mint_suffix": "pump"},
    delivery_mode="webhook",
    webhook_url="https://you.com/hooks/scout",
)
# store res["webhook_secret"] — shown ONCE

CRUD: first_touch_subscriptions_list(), first_touch_subscriptions_get(id), first_touch_subscriptions_update(id, **fields), first_touch_subscriptions_delete(id). ULTRA only — up to 10 active.

Don't poll — push. Median lead time before the second KOL is 12 seconds. WebSocket channel: kol:first_touches (PRO+).

Price Alerts (new in 1.9)

CRUD for token dip/recovery price alerts. Fires via WebSocket (price_alert:events channel) and/or HMAC-signed webhook when a token's market cap crosses your threshold. PRO=5 rules, ULTRA=25.

res = client.rest.price_alerts_create(
    name="SOL dip buy",
    token_mint="So11111111111111111111111111111111111111112",
    condition="below",          # "below" | "above"
    threshold_mc_usd=5_000_000_000,
    cooldown_min=120,
    delivery_mode="both",
    webhook_url="https://you.com/hooks/price",
)
# store res["webhook_secret"] — shown ONCE

price_alerts_list(), price_alerts_get(id), price_alerts_update(id, **fields), price_alerts_delete(id).

LangChain: MadeOnSolPriceAlertsListTool, MadeOnSolPriceAlertsCreateTool. CrewAI: same names via ALL_TOOLS.

Scout Leaderboard & KOL Consensus (new in 1.9)

Method Tier Description
rest.scout_leaderboard(period=, limit=) PRO+ Top scout-tier KOLs ranked by first-touch follow-on rate, win rate, and ROI
rest.kol_consensus(min_kols=, period=) PRO+ Tokens with the strongest KOL agreement signal — weighted by scout score and recent PnL
rest.peak_history(mint) PRO+ Historical peak-density windows for a token — every coordination spike with KOL breakdown
rest.almost_bonded(min_progress=, min_velocity_pct_per_min=, deployer_tier=, sort=, limit=) New 1.18 · PRO+ Pre-bond pump.fun tokens near graduation, ranked by velocity (Δprogress/min) — progress_pct, velocity_pct_per_min, eta_minutes, stalled, deployer_tier
rest.coordination_history(period=, limit=) PRO+ Global coordination event log with token, KOL count, score, and outcome
leaders = client.rest.scout_leaderboard(period="30d", limit=25)
consensus = client.rest.kol_consensus(min_kols=5, period="24h")

Wallet Derived Stats (new in 1.9)

wallet_stats(address) now includes a stats object with derived fields computed from the 90-day trade window:

data = client.rest.wallet_stats("WALLET_ADDRESS")
s = data["stats"]
# s["win_rate"]      — fraction 0-1, tokens sold above cost basis
# s["roi"]           — aggregate return on invested SOL
# s["verdict"]       — "strong" | "profitable" | "neutral" | "losing"
# s["biggest_miss"]  — token with the highest post-exit gain the wallet missed

Copy-Trade Rules (PRO/ULTRA)

Server-side rules that fire signals when one of your watched source wallets trades. Delivered via webhook (HMAC-signed) and/or WebSocket. PRO=3 rules × 5 source wallets each; ULTRA=20 × 50.

Method Description
rest.copy_trade_list() List your rules
rest.copy_trade_create(source_wallets, sizing_amount, ...) Create a rule. Returns webhook_secret once — store it
rest.copy_trade_get(id) Get one rule
rest.copy_trade_update(id, **fields) Update fields or toggle is_active
rest.copy_trade_delete(id) Delete permanently
rest.copy_trade_signals(subscription_id=, since=, limit=) Recent fired signals (up to 7 days, 1–500)

Wallet Tracker

Method Description
rest.wallet_tracker_watchlist() List tracked wallets and remaining capacity (Free: 10, Pro: 50, Ultra: 100)
rest.wallet_tracker_add(wallet_address, label=) Add wallet to watchlist
rest.wallet_tracker_remove(wallet_address) Remove wallet from watchlist
rest.wallet_tracker_update_label(wallet_address, label) Update wallet label
rest.wallet_tracker_trades(wallet=, action=, event_type=, limit=, before=) Historical swap/transfer events (120-day retention)
rest.wallet_tracker_summary(period=, wallet=) Per-wallet stats: swap counts, SOL bought/sold, last event

Universal Wallet API (new in 1.8)

Per-wallet endpoints that work on any Solana wallet, not just curated KOLs. FIFO cost-basis PnL over the last 90 days. PRO+ on every endpoint. Cache hits don't count against your daily quota.

Method Description
rest.wallet_stats(address) Aggregate stats over 90d + cross-product flags (is_kol + kol_name, is_alpha_tracked + bot_confidence 'none'/'low'/'medium'/'high', is_deployer + tokens_deployed; new 1.22: is_sniper / is_bundler / is_dumper + dump_cluster)
rest.wallet_batch_classify(wallets) New 1.22 · Bulk reputation flags for 1–100 wallets in one call — is_sniper/is_bundler/is_dumper/is_kol, bot_confidence, dump_cluster. Pump.fun-pipeline scoped: False = not observed, not verified clean
rest.wallet_pnl(address) Full FIFO cost-basis PnL: realized + unrealized SOL, profit factor, max drawdown, avg + median hold minutes, daily UTC PnL curve, closed positions sorted by pnl desc, open positions with live unrealized from mc-tracker
rest.wallet_positions(address) Open lots only — shares /pnl cache, lighter response
rest.wallet_trades(address, limit=, cursor=, action=, token_mint=, since=, until=) Cursor-paginated raw trades. Default window: last 90 days. limit 1-500

Cost-basis honesty: observable only inside the 90-day data window. Overflow sells (no matching buy in window) are silently discarded rather than fabricated. notes.cost_basis_observable_from makes the cutoff visible per call.

Webhooks + Streaming

Method Description
rest.create_webhook(url, events, filters=) Register webhook. Returns secret once — store it for HMAC verification
rest.list_webhooks() List your webhooks
rest.get_webhook(id) Get one + recent delivery log
rest.update_webhook(id, **kwargs) Update URL, events, filters, or re-enable
rest.delete_webhook(id) Delete permanently
rest.test_webhook(id) Send test payload
rest.get_stream_token(rotate=False) Issue your WebSocket streaming token (returns ws_url + dex_ws_url). Never expires (1.27.1) — same token on every call; rotate=True replaces it (old value works 60 s more). expires_at / next_refresh_at are always None
rest.stream_sessions() New 1.19 · PRO+ · List your live WebSocket sessions (id, service, tier, channels, connected_at, remote_ip, messages_sent) across both stream services
rest.kill_stream_session(id) New 1.19 · PRO+ · Force-terminate one of your sessions by id and free its slot — self-serve fix for a 4002 connection-limit lockout

Rate-limit headers

Every successful REST response captures rate-limit headers in rest.last_rate_limit:

client.rest.alpha_leaderboard()
rl = client.rest.last_rate_limit
# {'limit': 100, 'remaining': 92, 'reset': 1714000000, 'request_id': 'rid_abc123'}
if rl['remaining'] is not None and rl['remaining'] < 5:
    print(f"Throttle warning — {rl['remaining']}/{rl['limit']} requests left")

DEX Firehose (Ultra) — WebSocket

rest.get_stream_token() returns dex_ws_url (Ultra only). Connect with any WebSocket client (websockets, websocket-client, etc.) and use the multi-subscription protocol — up to 10 named subs per connection, each with its own sub_id, server-side filters, and optional replay (up to 500 most recent matching trades) from a server-side buffer holding ~5 minutes of firehose history — it backfills trades from before your connection existed. Replayed trades arrive newest-first flagged "replay": true, then a replay_done frame; sort by block_time client-side.

import asyncio, json, websockets
from madeonsol_x402 import MadeOnSolClient

client = MadeOnSolClient(api_key="msk_...")

async def main():
    token = client.rest.get_stream_token()  # {"token", "ws_url", "dex_ws_url", ...}

    # token MUST be appended as query param
    async with websockets.connect(f"{token['dex_ws_url']}?token={token['token']}") as ws:
        await ws.send(json.dumps({
            "type": "subscribe",
            "sub_id": "fresh-pumpfun",
            "replay": 50,                       # up to 500 from ring buffer
            "filters": {
                "dex": "pumpfun",
                "token_age_max_seconds": 300,
                "min_sol": 0.5,
                "action": "buy",
            },
        }))

        async for raw in ws:
            msg = json.loads(raw)
            if msg.get("channel") == "dex:trades":
                d = msg["data"]
                print(msg["sub_id"], d["dex"], d["action"], d["sol_amount"])

asyncio.run(main())

Operations (all carry sub_id): subscribe, update (replace filters in place), unsubscribe, list, ping. Filters: token_mint(s) (≤50), wallet(s) (≤50), dex (pumpfun | pumpamm | pumpswap | raydium | jupiter | orca | meteora | launchlab), program, deployer_tier, token_age_max_seconds, market_cap_min/max_sol, min_sol, max_sol, action. At least one targeting filter is required. Inbound rate limit: 5 messages/sec.

Full protocol reference: madeonsol.com/api-docs#streaming.

Tiers

Tier Price Wallets tracked Requests/day
BASIC (free) $0 10 200
PRO €43/mo (€430/yr) ≈ $49 50 10,000
ULTRA €131/mo (€1310/yr) ≈ $149 100 + WS events 100,000
BUSINESS €400/mo (€4000/yr) ≈ $449 500 + WS events 500,000

Free tier returns the full REST response shape on 40+ endpoints — real wallets, TX signatures, full precision — with live feeds delayed 5 minutes (delayed responses carry delay/as_of and an X-Data-Delay header). Paid tiers are real-time and unlock webhooks, WebSockets, rule engines, and ULTRA-only data depth; x402 pay-per-call is always real-time. Get a key at madeonsol.com/pricing.

Also Available

Platform Package
TypeScript SDK madeonsol on npm
Rust SDK madeonsol on crates.io
MCP Server (Claude, Cursor) mcp-server-madeonsol · Smithery · Glama
ElizaOS @madeonsol/plugin-madeonsol
Solana Agent Kit solana-agent-kit-plugin-madeonsol

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

madeonsol_x402-1.30.0.tar.gz (107.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

madeonsol_x402-1.30.0-py3-none-any.whl (72.3 kB view details)

Uploaded Python 3

File details

Details for the file madeonsol_x402-1.30.0.tar.gz.

File metadata

  • Download URL: madeonsol_x402-1.30.0.tar.gz
  • Upload date:
  • Size: 107.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for madeonsol_x402-1.30.0.tar.gz
Algorithm Hash digest
SHA256 00508f9591649c334e551a40379625c63e03ec171d1faac003ec04e0449cf160
MD5 889a2ba5b7da2a471633d449a8d65ce5
BLAKE2b-256 9ee3900c14921aee33aa7e23f5ceb76641ee62cc13f90db29a4fb2cf18474647

See more details on using hashes here.

File details

Details for the file madeonsol_x402-1.30.0-py3-none-any.whl.

File metadata

File hashes

Hashes for madeonsol_x402-1.30.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ff1c42f439a46bcb6b280faba3ffbb4ff8819d4cb6bd104085807fdb08ed5068
MD5 d48e5ba642262b0427cdc33ed15e3489
BLAKE2b-256 a6bc0017cb58b3a875eb142f181c7c9d6969d2df4cb540e06bed1902ce215e07

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.30.0 This release

2 files

1.29.0

2 files

1.28.1

2 files

1.28.0

2 files

1.27.1

2 files

1.27.0

2 files

1.26.0

2 files

1.25.0

2 files

1.24.0

2 files

1.23.3

2 files

1.23.2

2 files

1.23.1

2 files

1.23.0

2 files

1.22.0

2 files

1.21.0

2 files

1.20.2

2 files

1.20.1

2 files

1.20.0

2 files

1.19.1

2 files

1.19.0

2 files

1.18.0

2 files

1.17.0

2 files

1.16.0

2 files

1.15.0

2 files

1.14.0

2 files

1.13.0

2 files

1.12.1

2 files

1.12.0

2 files

1.11.1

2 files

1.11.0

2 files

1.10.0

2 files

1.9.0

2 files

1.8.1

2 files

1.8.0

2 files

1.7.3

2 files

1.7.2

2 files

1.7.1

2 files

1.7.0

2 files

1.6.1

2 files

1.6.0

2 files

1.5.0

2 files

1.4.0

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.1

2 files

1.0.0

2 files

0.5.0

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page