Wire protocol

Pump.fun WebSocket API

One WebSocket connection. Four channels — every Pump.fun launch, graduation, trade, and live price, delivered sub-450ms from chain confirmation as versioned JSON (wallet transfers coming soon). Subscribe with one message; filter server-side; no program IDs, no log decoding, no funded wallet.

wss://api.anaxer.com/v1/stream?apiKey=YOUR_KEY

Live streams on the free plan · No credit card · Sub-450ms · Flat pricing from $0

Protocol

How the Pump.fun WebSocket works

Three frames: connect, subscribe, receive. Copy the shapes — they match the live gateway.

  1. Connect

    Open a WebSocket to the connect URL, or send Authorization: Bearer on the upgrade (preferred server-side). The first frame is connected — it discloses your per-channel subscription cap.

    Server sendsconnected
    {
      "v": 1,
      "type": "connected",
      "ts": 1751008800000,
      "limits": {
        "connectionsPerStream": 1
      }
    }
  2. Subscribe

    Send one JSON control message with type, id, channel, and filters. The server acks with a subscribed frame echoing your id and filters.

    You sendsubscribe
    {
      "type": "subscribe",
      "id": "grads-1",
      "channel": "graduations",
      "filters": { "minLiquiditySol": 50 }
    }
    Server sendssubscribed
    {
      "v": 1,
      "type": "subscribed",
      "id": "grads-1",
      "channel": "graduations",
      "filters": { "minLiquiditySol": 50 },
      "ts": 1751008800100
    }
  3. Receive

    Data arrives in a versioned envelope. v:1 is additive-only — your parser reads data and survives new optional fields.

    Server sendsenvelope
    {
      "v": 1,
      "channel": "graduations",
      "type": "graduated",
      "sub": "grads-1",
      "ts": 1751009291000,
      "data": {
        "type": "graduated",
        "source": "pump_fun",
        "mint": "2ajrYELtYtvtJd8fQAGXpfQbgXXZe3YjPtNJ9K3bpump",
        "name": "Pepe",
        "symbol": "PEPE",
        "creator": "7BvK3nF2HxR8mP5qW9tL4sY6jC1dA8eU3gN2fM5A1zXY",
        "uri": "https://ipfs.io/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG",
        "mayhemMode": false,
        "socials": {
          "website": "https://www.pepe.vip",
          "twitter": "https://x.com/pepecoineth",
          "telegram": "https://t.me/pepe_coin"
        },
        "liquiditySol": 85.005,
        "timeToGraduateSeconds": 4523,
        "signature": "8Hn2vQ3xR7mLdW9fJcY6zT1nGpK5uA3oXvE2mBpS8dRzL4nJb9FgKtR5zXvY2mNc8hAeQ4WcS7pTz",
        "slot": 309845102,
        "timestamp": 1751009291000
      }
    }

With one WebSocket connection, four channels cover the Pump.fun lifecycle end to end — plus transfers when that stream ships. Events arrive sub-450ms from chain confirmation.

Reference

Pump.fun WebSocket streams: channels, events, and filters

Server-side filters on every channel. Wrong-channel filters are rejected — never silently ignored.

ChannelEventFires whenFiltersPlan
creationscreatedA token launches — fast mode immediately, or enriched: true after website/X/Telegram resolvesources, excludeMayhem, enrichedFree+
graduationsgraduatedA token fills its bonding curve and moves to PumpSwap — includes liquiditySol, timeToGraduateSecondssources, excludeMayhem, minLiquiditySolFree+
tradesswapEvery buy/sell across Pump.fun, PumpSwap, Raydium, Meteora, Orca and moresources, mints, wallets, minVolumeUsd, maxVolumeUsd, solOnlyStarter+
pricespriceA tracked token's USD/SOL price or market cap movessources, mintsStarter+
transferstransferComing soon — wallet-level transfer events for watched addresseswalletsComing soon

Filters AND across fields and OR within a list. An empty {} means everything on that channel. A filter that does not belong on the channel returns invalid_filters — it is not ignored. On Starter, trades require mints (up to 10); Pro may omit mints for the firehose.

Quickstart

Subscribe to Pump.fun graduations in Python or TypeScript

Python uses the standard websockets library — there is no Python SDK. TypeScript uses @anaxer/sdk. Prove the wire with wscat in ten seconds.

import asyncio, json, websockets

API_KEY = "YOUR_API_KEY"  # free at console.anaxer.com

async def main():
    url = f"wss://api.anaxer.com/v1/stream?apiKey={API_KEY}"
    async with websockets.connect(url) as ws:
        await ws.send(json.dumps({
            "type": "subscribe",
            "id": "grads",
            "channel": "graduations",
            "filters": {"minLiquiditySol": 50, "excludeMayhem": True},
        }))
        async for raw in ws:
            msg = json.loads(raw)
            if msg.get("channel") == "graduations":
                g = msg["data"]
                print(g["symbol"], g["liquiditySol"], g["timeToGraduateSeconds"])

asyncio.run(main())
import { connect } from "@anaxer/sdk";

const client = connect({ apiKey: process.env.ANAXER_API_KEY! });

// Track up to 10 tokens on Starter. Pro can omit `mints` for the full firehose.
client
  .stream("trades", { mints: ["YOUR_TOKEN_MINT"], minVolumeUsd: 500 })
  .on("data", (swap) => {
    console.log(swap.wallet, swap.volumeUsd, swap.swap.to.mint);
  });
npx wscat -c "wss://api.anaxer.com/v1/stream?apiKey=YOUR_KEY"
> {"type":"subscribe","id":"launches","channel":"creations","filters":{}}

Full tutorial: Solana WebSocket streams guide · Stream docs

Production

Running a Pump.fun WebSocket in production

Reconnect, heartbeats, backpressure, and close codes — the parts tutorial posts usually get wrong.

Reconnects and gap recovery

Reconnect with jittered backoff and resubscribe — subscriptions do not survive a socket. There is no WebSocket replay: note the last ts or slot you processed and backfill the gap via REST from/to + cursor on /v1/creations, /v1/graduations, or /v1/tokens/:mint/trades. See REST docs.

Heartbeats

Remember: the server never sends unsolicited pings and imposes no pong deadline. Send {"type":"ping"} yourself if your platform needs traffic to keep NATs or proxies open, and treat a missing pong as a dead socket.

Backpressure

Consume faster than you receive, or buffer internally. A client that falls too far behind gets an error frame with slow_consumer, then close 1013. Do not do heavy work inline in the message handler.

Errors and close codes

Most errors are inline v1 error frames and the socket stays open (invalid_filters, subscription_limit, duplicate_id, plan_restricted, …). Only three closes exist: 1008 unauthorized, 1013 slow consumer, 1011 internal — each preceded by an error frame that tells you why. See error docs.

Compare

Pump.fun WebSocket providers compared

WebSocket-scoped — flat USD and live streams on the free plan versus wallets, SOL metering, and Premium-gated streams.

ProviderStreaming on free tierMeteringFunded walletConnections & channelsServer-side filtersBackfill after a drop
AnaxerCreations + graduationsFlat USD — no meteringNoMulti-channel per connection; caps in connected frameYes — every channelREST from/to + cursor
PumpPortalLaunch + migration freeTrades: 0.01 SOL / 10k eventsYes (min 0.02 SOL)One connection per client; hourly bansLimitedLimited
PumpDevFree WS (fee-funded)0.25% on routed trades; caps 25 subs / 50k trade events/moYes (trading)Capped free accountYesLimited
Solana TrackerNo — Datastream from Premium (€397/mo)Tiered EURNoPremium+YesYes
BitqueryNo (full streams at Scale $299/mo)Points + stream-minutes + $10/GBNoMetered GraphQL subscriptionsGraphQL filtersYes

Competitor details from public pricing and docs pages as of July 25, 2026 — verify before relying on them. PumpPortal trade streams meter at 0.01 SOL per 10k events to a linked wallet; PumpDev's free feed is funded by a 0.25% fee on trades routed through them.

Free tier

A free Pump.fun WebSocket — without a catch

On the free plan

  • creations stream — every new launch
  • graduations stream — every bonding-curve fill
  • 2,500 REST requests per month for backfill
  • No credit card to start

What you never pay

  • No funded Solana wallet
  • No SOL-metered events
  • No fees on your trades — we are data-only
  • No compute units or credits to forecast

Live streams on the free plan are the product, not a loss-leader — creations and graduations ship with a free API key, no credit card. Anaxer is data-only: there is no trade fee waiting downstream, no SOL metering, and no wallet linkage. Paid plans buy more channels and throughput, not the removal of a toll.

Streaming into an AI agent instead of a bot? The same channels are exposed to Claude and Cursor through our MCP server — see the Pump.fun API overview.

Pricing

Simple pricing. No compute units. No credits.

Flat monthly plans you can understand in 10 seconds. The bill is the price on the box.

Free

Try it out

$0USD
Start free

Streams

Token Creation

Included

Token Graduation

Included

Token Prices

Not included

DEX Trades

Not included

Wallet Transfers

Coming soon

Stream limits

Connections per stream

1

REST API

Requests / mo

2.5k

Rate limit

30/min
Most popular

Starter

Hobbyists & indie devs getting started

$39USD/mo
Get started

Streams

Token Creation

Included

Token Graduation

Included

Token Prices

Included

DEX Trades

Track up to 10 tokens (SOL pairs via solOnly)

Included

Wallet Transfers

Coming soon

Stream limits

Connections per stream

1

REST API

Requests / mo

250k

Rate limit

300/min

Pro

Built for dev and production environments

$99USD/mo
Get started

Streams

Token Creation

Included

Token Graduation

Included

Token Prices

Included

DEX Trades

All tokens, unlimited

Included

Wallet Transfers

Coming soon

Stream limits

Connections per stream

2

REST API

Requests / mo

2.5M

Rate limit

600/min

Enterprise

High volume, custom limits, dedicated support and an SLA.

Contact us

FAQ

Pump.fun WebSocket — frequently asked questions

Protocol

Open a WebSocket to wss://api.anaxer.com/v1/stream?apiKey=YOUR_KEY, or send your key as an Authorization: Bearer header on the upgrade request (preferred for servers). The first message you receive is a connected frame that includes your plan's per-channel subscription limits. API keys are free — no credit card.

Send one JSON control message: {"type":"subscribe","id":"launches","channel":"creations","filters":{}}. The server acknowledges with a subscribed frame, then pushes events. id is any name you choose (1–64 characters); every event echoes it back as sub so you can route messages when one connection holds several subscriptions.

No. The server never sends unsolicited pings and imposes no pong deadline. You may send {"type":"ping"} and get a pong back — useful for keeping NATs or proxies open and for detecting dead sockets — but it's optional.

Events are not replayed over WebSocket. Reconnect, resubscribe, and backfill the gap with the REST list endpoints using from/to timestamps and cursor pagination — creations, graduations, and per-token trades are all queryable. Note the last timestamp you processed and you can make delivery gapless.

Yes. A single WebSocket can hold subscriptions on creations, graduations, trades, and prices at once. Plan limits apply per channel — the connected frame tells you your cap — so you rarely need more than one connection.

Every data message is a versioned envelope: {v, channel, type, sub, ts, data} with your payload under data. Within v1, changes are additive only — new optional fields or channels never break an existing parser.

Almost all errors arrive as inline error frames and the connection stays open — bad filters, unknown channels, or plan limits never kill the socket. Only three things close it, each after an error frame explaining why: an invalid or revoked key (code 1008), falling too far behind as a slow consumer (1013), or an internal server fault (1011).

Yes — filters are part of the subscribe message, so unwanted events never reach you. Filter creations by Mayhem mode or enrichment, graduations by minimum liquidity, and trades by token, wallet, USD volume, or SOL-paired legs. Filters AND across fields and OR within lists.

Technically yes — the apiKey query parameter works from browser WebSocket (browsers can't set headers on the upgrade). But that exposes your key to anyone reading the page source, so for anything public, keep the connection on your server and relay what the browser needs.

Enriched mode (enriched: true on creations) delivers only after the token's off-chain metadata resolves. If the metadata fetch fails or never resolves, no enriched frame is sent for that mint — it isn't delayed and it isn't null-filled. Run fast mode when you need every launch; enriched when you need socials.

Start building today.

Build your next Solana app in minutes, not weeks.