Quick start
Connect and receive events in under 10 lines (npm i centrifuge):
import { Centrifuge } from "centrifuge";
const client = new Centrifuge("wss://pumpws.bubudev.win/connection/websocket", {
data: { apikey: "<YOUR_PUMP_API_KEY>" }, // pump_… from the dashboard
});
client.connect();
client.subscribe("marketdata", ({ data }) => {
console.log(data.kind, data.mint, data.payload);
});No SDK? Talk the raw protocol directly — e.g. with websocat:
websocat "wss://pumpws.bubudev.win/connection/websocket?format=json"
# then send (one JSON frame per line):
{"id":1,"connect":{"data":{"apikey":"pump_…"}}}
{"id":2,"subscribe":{"channel":"marketdata"}}Authentication
- Open the dashboard, sign in, pick a plan and press Pay — you get a one-time SOL deposit address (valid 24h).
- Send the exact amount (0.5 / 1.5 / 4 SOL). The monitor confirms on-chain within ~30 seconds and issues your key.
- The key appears under Centrifugo API key on the dashboard — pass it as data.apikey when connecting (snippet above).
Channels
| Channel | Contains | Tier |
|---|---|---|
signals | Every signal: arms, graduations, migrations, whale moves, milestones | Any tier |
signals:mint:<mint> | Signals for one token mint (base58) | Any tier |
marketdata | Trades, migrations, live/closed candles | Monthly + |
marketdata:mint:<mint> | Market data for one token | Monthly + |
Any tier = weekly, monthly or quarterly — no subscription, no access. Subscribe to the firehose, or to :mint:<mint> lanes to receive a single token only.
Message envelope
Every publication is a versioned JSON envelope. payload carries the signal metadata verbatim — full examples for each kind below.
{
"v": 1, // envelope schema version
"id": "0f5c9a3e-…", // unique id — dedupe / trace across consumers
"kind": "arm", // signal type — switch on this
"ts": 1756915200000, // event time (ms since epoch)
"wallTs": 1756915200123, // server receive time (ms)
"mint": "5hBz…", // token mint address (when known)
"payload": { … } // full signal metadata — see examples below
}Payload · marketdata
The 3 kinds published to marketdata. Trades, migrations and candles — monthly tier and up. All amounts are SOL-denominated. Fields with no value are omitted — code against undefined.
market.trade
Every pump + pump-amm trade from the firehose, enriched with pool and pricing context. This is the raw feed the candles are built from.
{
"v": 1,
"id": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e",
"kind": "market.trade",
"ts": 1756915700000, // trade time (payload.timestamp) or server time
"wallTs": 1756915700123,
"mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
"payload": {
"kind": "market.trade",
"mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
"symbol": "BUBU",
"action": "buy", // "buy" | "sell"
"marketCapQuote": 142.6, // market cap in QUOTE-TOKEN units — SOL while the
// quote is WSOL; USDC/USDT/USD1/stock pairs report
// raw quote units (#321). The OHLC basis for candles.
"quoteAmount": 3.2, // this trade's volume in quote-token units (absolute)
"timestamp": 1756915700000, // trade time (ms)
"pool": "6Pq8mYcVdRnZ2wXjKfTgH4sLbAeNu7QrYcUvWxZ1p2o", // AMM pool address (post-migration)
"poolCreatedBy": "Gk2mNvBx7QrYcUdAeBsFgHjKlMnOpQrStUvWz3", // pool creator pubkey
"signature": "5XyzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvWz", // tx signature — dedupe key
"txSigner": "Gk2mNvBx7QrYcUdAeBsFgHjKlMnOpQrStUvWz3", // tx signer pubkey
"mayhemMode": false, // pump.fun mayhem-mode flag on the trade
"price": 0.00000021, // trade price
"tokenAmount": 15200000, // token amount moved in this trade
"tokensInPool": 793400000, // token side of pool reserves
"quoteInPool": 167.1, // quote side of pool reserves (quote-token units)
"vTokensInBondingCurve": 0, // virtual tokens on the curve (pre-migration only)
"uri": "https://ipfs.io/ipfs/QmTokenMetadata7xK9",
"breakdown": [ // sub-legs when one tx bundles multiple fills
{ "action": "buy", "trader": "Gk2m…", "tokenAmount": 10000000, "quoteAmount": 2.1 },
{ "action": "buy", "trader": "Gk2m…", "tokenAmount": 5200000, "quoteAmount": 1.1 }
]
}
}market.migrate
Migration event on the market lane — marks the curve→AMM transition together with the market cap it happened at.
{
"v": 1,
"id": "9c0d1e2f-3a4b-5c6d-7e8f-9a0b1c2d3e4f",
"kind": "market.migrate",
"ts": 1756915750000,
"wallTs": 1756915750123,
"mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
"payload": {
"kind": "market.migrate",
"mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
"symbol": "BUBU",
"timestamp": 1756915750000, // migration time (ms)
"marketCapQuote": 168.4, // market cap in quote-token units at migration
"mayhemMode": false
}
}market.candle.live / market.candle.closed
OHLCV candles aggregated from the trade feed on 4 timeframes. `live` re-emits the in-progress bucket on every tick; `closed` fires once at bucket end. All prices are market cap in SOL.
{
"v": 1,
"id": "0d1e2f3a-4b5c-6d7e-8f9a-0b1c2d3e4f5a",
"kind": "market.candle.closed", // "market.candle.live" | "market.candle.closed"
"ts": 1756915680000, // = payload.tsOpen (bucket start), NOT wall time
"wallTs": 1756915740123,
"mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
"payload": {
"kind": "market.candle.closed",
"mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
"symbol": "BUBU",
"tf": "1m", // "1m" | "5m" | "15m" | "1h"
"open": 140.2, // bucket-open market cap (quote-token units)
"high": 152.8, // max market cap (quote-token units) in bucket
"low": 138.9, // min market cap (quote-token units) in bucket
"close": 149.1, // latest market cap (quote-token units) in bucket
"vSol": 22.4, // volume in quote-token units inside the bucket
"trades": 61, // trade count
"buys": 40, // buy count
"sells": 21, // sell count
"tsOpen": 1756915680000, // epoch-aligned bucket start (ms)
"tsClose": 1756915740000 // bucket end (ms) = tsOpen + tf
}
}Subscription lifecycle
- Activation — automatic once payment confirms on-chain (poll every 30s).
- Grace — after expiry you keep receiving for 24h while a renewal lands.
- Renewal — a new tier extends from your current expiry; no lost days.
- Rate limit — 10 new connections/s per IP; reuse one connection, subscribe to many channels.
FAQ
- Sent the wrong amount?
- Payments must match the tier price within 0.001 SOL. Wrong amounts are logged, not credited — generate a new address and send the exact amount.
- Connect rejected with
4004? - Subscription expired beyond the 24h grace window. Renew on the dashboard — the same key works again.
- Can I filter kinds client-side?
- Yes — switch on
envelope.kind. New kinds may be added over time, so ignore unknown values instead of throwing. - Devnet SOL for testing?
- faucet.solana.com (choose Devnet) or
solana airdrop 5 <WALLET> --url devnet.