Stream guide

pumpapi signal stream

The pumpapi WebSocket streams live pump.fun signal and market data — arms, graduations, whale moves, trades and candles — delivered within milliseconds of detection. There is no anonymous or free tier — every connection requires an API key backed by an active paid subscription.

Endpoint wss://pumpws.bubudev.win/connection/websocket · Auth required — subscription API key in connect data.apikey · Protocol Centrifugo (WebSocket, RFC 6455)

Quick start

Connect and receive events in under 10 lines (npm i centrifuge):

JavaScript
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("signals", ({ data }) => {
  console.log(data.kind, data.mint, data.payload);
});

No SDK? Talk the raw protocol directly — e.g. with websocat:

Raw WebSocket JSON
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":"signals"}}

Authentication

  1. Open the dashboard, sign in, pick a plan and press Pay — you get a one-time SOL deposit address (valid 24h).
  2. Send the exact amount (0.5 / 1.5 / 4 SOL). The monitor confirms on-chain within ~30 seconds and issues your key.
  3. The key appears under Centrifugo API key on the dashboard — pass it as data.apikey when connecting (snippet above).
Enforcement is server-side: anonymous connects are rejected, and every subscribe re-checks your subscription. Weekly keys get signals only — market data needs monthly or higher. When your subscription lapses (after the 24h grace), the server disconnects active sessions automatically. Treat the key like a password; wrong payment amounts are logged, not credited. Renewals and coupons never change it — if it leaks, use Rotate key on the dashboard: the old key dies immediately, open sessions are disconnected, and every key you ever issued stays in your key history.

Channels

ChannelContainsTier
signalsEvery signal: arms, graduations, migrations, whale moves, milestonesAny tier
signals:mint:<mint>Signals for one token mint (base58)Any tier
marketdataTrades, migrations, live/closed candlesMonthly +
marketdata:mint:<mint>Market data for one tokenMonthly +

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.

Envelope v1
{
  "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 · signals

The 9 kinds published to signals. Arms, graduations, whale moves and milestones — the detection firehose, available on every tier. Fields with no value are omitted — code against undefined.

arm

A token passed the entry filter set (volume, dev reputation, path tags). The primary “watch this” signal — fired while the token is still on the bonding curve.

Example event
{
  "v": 1,                    // envelope schema version
  "id": "0f5c9a3e-8f0c-4a2d-9e1b-7c6d5a4b3c2d",   // unique id — dedupe / trace
  "kind": "arm",             // signal type — switch on this
  "ts": 1756915200000,       // event time (ms since epoch)
  "wallTs": 1756915200123,   // server receive time (ms)
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW", // token mint (base58)
  "payload": {
    "kind": "arm",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU",        // token ticker
    "mcapUsd": 42000         // market cap in USD when armed (entry mcap if known)
  }
}

arm_pre_mig

Same filter decision as arm, but the token armed while already near/at migration. A distinct lane because entry mcap behaves differently there.

Example event
{
  "v": 1,
  "id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
  "kind": "arm_pre_mig",
  "ts": 1756915200000,
  "wallTs": 1756915200123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "arm_pre_mig",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "PREX",
    "mcapUsd": 58000         // live market cap in USD at arming time
  }
}

pump

The token graduated (completed the bonding curve) or hit the pump-entry policy. The classic 🚀 alert.

Example event
{
  "v": 1,
  "id": "2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
  "kind": "pump",
  "ts": 1756915260000,
  "wallTs": 1756915260123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "pump",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU",
    "mcapUsd": 69000,        // market cap in USD at pump time
    "uri": "https://ipfs.io/ipfs/QmTokenMetadata7xK9" // token metadata JSON (image, socials)
  }
}

migrate

Raw bonding-curve migration (curve → AMM) without the pump-entry verdict attached. Lower rank than pump on the topic ladder.

Example event
{
  "v": 1,
  "id": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f",
  "kind": "migrate",
  "ts": 1756915230000,
  "wallTs": 1756915230123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "migrate",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU"
  }
}

milestone

Market cap crossed a multiple of the entry mcap (×2, ×5, ×10, ×20 …). A catch-up burst collapses into one message carrying the highest level reached.

Example event
{
  "v": 1,
  "id": "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
  "kind": "milestone",
  "ts": 1756915500000,
  "wallTs": 1756915500123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "milestone",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU",
    "mcapUsd": 340000,       // market cap in USD when the milestone fired
    "level": 8               // multiple reached, ×100 scale → 8 = ×8 from entry
  }
}

whale

A tracked wallet made a large single or cumulative move on a mint (buy or sell), caught by the whale detector on the trade firehose.

Example event
{
  "v": 1,
  "id": "5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b",
  "kind": "whale",
  "ts": 1756915600000,
  "wallTs": 1756915600123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "whale",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU",
    "mcapUsd": 120000,       // market cap in USD at trade time
    "uri": "https://ipfs.io/ipfs/QmTokenMetadata7xK9"
  }
}

whale_armed

Whale detection on a token that had already fired arm — the strongest continuation lane (whale activity + filter agreement).

Example event
{
  "v": 1,
  "id": "6f7a8b9c-0d1e-2f3a-4b5c-6d7e8f9a0b1c",
  "kind": "whale_armed",
  "ts": 1756915610000,
  "wallTs": 1756915610123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "whale_armed",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU",
    "mcapUsd": 125000,       // market cap in USD at trade time
    "uri": "https://ipfs.io/ipfs/QmTokenMetadata7xK9"
  }
}

bc_mid

A watched token crossed the bonding-curve midpoint (~50% progress) with real volume behind it — a pre-graduation momentum marker.

Example event
{
  "v": 1,
  "id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d",
  "kind": "bc_mid",
  "ts": 1756915300000,
  "wallTs": 1756915300123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "bc_mid",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU",
    "mcapUsd": 24000,        // market cap in USD at trigger time
    "uri": "https://ipfs.io/ipfs/QmTokenMetadata7xK9"
  }
}

leg2

A token that already fired 🚀 dumped ≥80% from peak, held a tight base, then reclaimed +15% with net big-wallet inflow — the 'leg 2' continuation signal.

Example event
{
  "v": 1,
  "id": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e",
  "kind": "leg2",
  "ts": 1756922400000,
  "wallTs": 1756922400123,
  "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
  "payload": {
    "kind": "leg2",
    "mint": "5hBzKpR3vNqXw7TjLmYc8UdAeBsFgHjKlMnOpQrStUvW",
    "symbol": "BUBU",
    "mcapUsd": 18400,       // market cap in USD at reclaim time
    "uri": "https://ipfs.io/ipfs/QmTokenMetadata7xK9"
  }
}

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.