WEBSOCKETTrades and bars, pushed as they land.
One socket carries every decoded swap; a second carries OHLCV bars that update mid-bar and again when they seal. Filters run server-side, so a browser can hold a single connection and receive only the pools it asked for.
- Venues decoded
- 10
- Bar timeframes
- 8
- Pairs
- 1.2M+
- Wire format
- JSON
Validator to frame.
- feed
- connecting
- frames this session
- 0
- events decoded
- read live on /products
- last venue
- —
This tape is a connection, not a recording.
The rows arrive over a public demo bridge to wss://ws.dexploit.dev/ws/swaps, the same socket an API key opens. Beside it is one swap exactly as the authenticated stream sends it.
wss://ws.dexploit.dev/ws/swapsconnectingswap framecaptured · meteora_damm_v2{"type": "swap","signature": "3rjMq3C7Zp4eDDRtKwEBmVFXErFt4twvUVryNerBgkrx…","slot": 420984167,"timestamp": 1779279483,"dex": "meteora_damm_v2","swap_type": "sell","trader": "rk4jdi7srE6VKtxPeCKnqpEe7uJdZLLdpv1qAPK8LRd","token_mint": "8ZiqYN6rEm6PapbhCm5wWWzkRjsYyixgqW3K2384D1C3","pool_address": "DT75gs9fygQxi2Aq2ST1jz9C6FTNcbBjpgSpdDpMDdLX","amount_in": 350832255298,"amount_out": 729873626,"sol_amount": 729873626,"token_amount": 350832255298,"virtual_sol_reserves": null,"virtual_token_reserves": null,"real_sol_reserves": 91985332910,"real_token_reserves": 44561454812398,"lp_fee_bps": 1,"protocol_fee_bps": 0,"fee": null,"creator_fee": null,"price_impact_bps": null,"base_decimals": 9,"quote_decimals": 6,"pool_price": 2.0642354092175554e-6,"transfer_fee_in": 0,"transfer_fee_out": 0,"maker_tags": []}
- Demo sampling
- The unfiltered firehose is thinned to 6 events per second for this page. Subscribe with a mint filter and the sampling lifts.
- Demo record
- The bridge forwards the frame's fields with the trader's tags deduplicated, plus the frame's measured length. The tape shows the wallet and signature abbreviated.
- Field names
- The tape renders the bridge's slimmed keys. The frame on the right is the real contract. Integrate against that.
Ask for less, receive less.
Every swap enters at the top. Each active filter owns a beam out of the prism; a frame that matches leaves along it, and a frame that matches nothing is absorbed. On the product, those are bytes the server never sends. Toggle the chips and watch the routing change on live frames.
On the product these fields go in the subscribe message and the server evaluates them before serialising. The absorbed frames are bytes that never leave the data centre. Here the chips run on frames already received, because this demo shares one throttled subscription across every visitor; the counts are still real, one per frame.
Two channels, and the frames you send on them.
- WSS
/ws/swapsDecoded swaps, pool events, discovery rooms - WSS
/ws/ohlcvLive bars, mid-bar and on close
- send
subscribeOpen the set. Filters are optional and AND together - op
addUnion new (pair, timeframe) subjects, no reconnect - op
removeDrop subjects; the ack reports the new total - op
unsubscribeClear every subject on the connection - send
joinRoom mode: transaction:{mint}, wallet:{addr}, rugs - send
pingServer replies pong
pump_funpump_swapraydium_ammraydium_clmmraydium_cpmmorcameteora_dlmmmeteora_damm_v2Frames carry pump_fun and pump_swap; the dexes filter takes the REST spelling, pumpfun and pumpswap.
signaturestringBase58 transaction signature. One transaction can carry several swaps
timestampi64Epoch seconds here. REST /swaps uses milliseconds, candles use ISO 8601
swap_typestringLowercase "buy" or "sell". Not is_buy, which is a filter key only
dexstringVenue name. On REST /swaps the same field is an integer id
pool_addressstringThe pool. REST and /ws/ohlcv key the same account as pair_address
sol_amountu64Lamports: divide by 1e9 for SOL
token_amountu64Base units: divide by 10 ** quote_decimals
pool_pricenumberMid after the swap, SOL per whole token, decimals-adjusted
maker_tagsstring[]Wallet-intel classification at swap time: sniper, insider, whale
There is no price field. Use pool_price, or divide the two amounts yourself with the decimals on the frame.
Four things that catch people out.
is_closedA bar is re-sent with is_closed: false on every trade inside it, then once more with true when it seals. Treat the interim frames as an in-progress bar and the final one as authoritative; appending each arrival draws the same bar many times.
signatureA router or aggregator transaction emits several swaps that share one signature and one slot, so sig + slot is not a unique key. Key on the pool and the leg, or you will silently drop half a multi-hop trade.
seconds vs millisecondsOn the same socket, a swap frame carries timestamp in epoch seconds while a pool event carries timestamp_ms in milliseconds. Mixing them is a 1000× error, and it shows up as 1970 or as a date decades out.
subscribe replacesOn /ws/ohlcv a second subscribe discards the live set and installs the new one. To widen a watchlist, send op: "add". Both pair_addresses and timeframes are required.
A socket is not always the right shape.
gRPC gives typed frames and server-bounded flow control for indexers. REST answers a range query without holding a connection open at all.
Filter the feed, inspect a frame.
A live subscription to the public demo stream. Toggle a venue or raise the size floor, then select any frame to see the decoded record behind it.
These toggles filter frames already received. In the product the same fields are applied server-side, so the bytes are never sent.
- waiting for the first frame…
Select a frame to inspect it.
Rate limits, stated per second.
- Rate
- 100 RPS
- Connections
- 10 concurrent
- History
- Full history
- Support
- Rate
- 500 RPS
- Connections
- 50 concurrent
- History
- Full history
- Support
- Priority
- Rate
- Negotiated
- Connections
- Negotiated
- History
- Full history
- Support
- 24/7
This transport starts on Developer ($50/mo). Not included on Starter.
Limits are per second. The plans have no monthly request quota, so none is quoted here.