SWAPS

Every DEX swap on Solana, decoded.

One record per fill: venue, wallet, pool, amounts, fees, price impact and post-trade reserves. Stream it as it lands, or query the same rows back by token, wallet, signature or time window.

Venues decoded
10
Swap endpoints
6
Documented fields
21
Response, p95
<50ms
Pipelinelive · public demo stream

Validator to decoded fill.

Connecting
0 frames this session
Inspector
Hover or focus a node to hold the flow and read what is passing through it. Every value comes from the last swap this page received.
feed
connecting
frames this session
0
events decoded
read live on /products
last venue
wss://ws.dexploit.dev/ws/swapsconnecting

A real EventSource against the public swap feed, proxied so the key stays on the server. The unfiltered firehose is throttled to about six events a second here so a marketing page cannot melt a browser tab; a subscription of your own is not.

Scanner

Watch a fill get decoded and tagged.

A live swap lands, its instructions are read, the balance deltas are reconciled, and the trader's wallet-intel tags are stamped on. Every value is the record's own; the tags are the engine's, not the page's.

Recent whale fills · connecting
0 received · 0 scanned
1Transaction
slot447,531,800
block time13:16:40 UTC
venuePumpSwap
2Instructions
programpumpswap
swap legix_index 0
directiontoken → SOL
amount_in9,983,945,659,087
amount_out14,977,475,416,957
3Balances
SOL+14977.5
token, base units9,983,945,659,087
price, SOL / token0.01555
traderDRLf…exAx
4Tags

Stampedlast 8
  • 13:16:40PumpSwapwhale-sized fill
  • 18:40:17PumpSwapwhale-sized fill
  • 01:04:24PumpSwapwhale-sized fill
  • 02:15:32PumpSwapwhale-sized fill
  • 16:06:07PumpSwapwhale-sized fill
  • 01:59:44PumpSwapwhale-sized fill
  • 18:34:05PumpSwapwhale-sized fill
  • 01:37:27PumpSwapwhale-sized fill

Tags are the engine's, relayed from maker_tags on the frame; the one badge computed here is the size class, at the 10 SOL default of GET /swaps/whale. Most traders carry no tags, and the scanner says so rather than inventing one.

Surface

Six paths, and filters that run before serialisation.

Every path returns the same record, so the shape you learn once holds for history, ranges, whales, a single signature, a wallet and a mint.

Endpoints
  • GET/swapsNewest fills first, with filters
  • GET/swaps/rangeA time or slot window, paged
  • GET/swaps/whaleFills above a lamport threshold
  • GET/swaps/{signature}One transaction, returned bare
  • GET/swaps/trader/{wallet}A wallet's history plus lifetime stats
  • GET/swaps/token/{mint}Every pool for a mint, plus token stats
Query filters
  • tokenstring

    Mint address: aggregates across every pool

  • traderstring

    Wallet address, matched against user

  • poolstring

    One pair_address

  • dexstring

    The venue name, not the integer id

  • is_buyboolean

    true is SOL → token, false is token → SOL

  • min_solinteger

    Lamports, and it must be a whole number

  • limit / offsetinteger

    100 per page; page while has_more is true

Swap schema
Identity
  • signaturestringSolana transaction signature, base58, full
  • slotint64The slot the transaction landed in
  • timestampint64Epoch milliseconds; seconds on the WebSocket
  • dexint 1–10Integer venue id; the stream sends the name
  • pair_addressstringThe on-chain pool / LP account
  • token_addressstringThe non-SOL side of the pool
  • userstringTrader wallet, full, not truncated
Direction and size
  • is_buybooleantrue is SOL → token
  • sol_amountint64Lamports: divide by 1e9 for SOL
  • token_amountint64Base units: divide by 10**quote_decimals
Price
  • price_per_tokennumberLamports per atomic token unit: raw, not SOL per token
  • pool_pricenumberPost-trade mid in SOL per whole token
  • price_impact_bpsintFill against pre-trade mid, basis points
Fees
  • feeint64LP fee paid, in lamports
  • fee_bpsintEffective LP fee in basis points
  • creator_feeint64Creator-set fee: pump.fun and meteora_dbc
  • creator_fee_bpsintThe same fee expressed in basis points
Pool state
  • base_decimalsintDecimals of the SOL side, typically 9
  • quote_decimalsintDecimals of the token side
  • real_sol_reservesint64Pool SOL reserves after this swap
  • real_token_reservesint64Pool token reserves after this swap
Worth knowing

Six things that cost people an afternoon.

price_per_token

It is lamports per atomic token unit, not SOL per token. Convert with price_per_token * 10**quote_decimals / 1e9. Read straight, it overstates a six-decimal token by 1000×. If you want a price and not a fill, use pool_price, which is already adjusted.

two wire shapes

REST sends is_buy as a boolean, dex as an integer and timestamp in epoch milliseconds. The stream sends swap_type as "buy" / "sell", dex as the venue string, and seconds. Same event, two encodings, deliberately.

min_sol

Lamports, parsed as an unsigned 64-bit integer. min_sol=20000 means 0.00002 SOL, not twenty thousand, and min_sol=20000.5 returns HTTP 400 min_sol: invalid digit found in string.

nulls are venue-specific

fee, creator_fee, price_impact_bps and cashback come back null on venues that do not report them. Fall back to the _bps siblings. virtual_*_reserves are populated only on pump.fun bonding curves.

pool_address vs pair_address

The swap stream keys the pool as pool_address; REST and the OHLCV feed key the same on-chain account as pair_address. Joining the two surfaces means normalising the name, not the value.

the envelope

Every path returns { swaps, total, has_more } and pages by incrementing offset, except /swaps/{signature}, which returns the swap object bare.

Workbench

Filter server-side, then take the client code.

Size and venue filters are applied before the response is built, so what you pay to receive is what you asked for.

Request

Newest fills first. Filter by venue, token or size.

Runs against the live API from your browser. No key needed here: the demo key is applied server-side.

curl -s 'https://api.dexploit.dev/swaps?limit=5' \
  -H 'x-api-key: $DEXPLOIT_API_KEY'
Responsep95 engine <50ms

Press Run to execute this request against the live API.

Decoding

What the engine does before you see a fill.

Instruction decoding, server-side

Each venue encodes a swap differently. The engine decodes 10 protocols into one record, so your client has no per-venue branches.

UnifiedSwap · 15 fields, identical across venues

Wallet tags travel with the fill

Trader classification is attached to the swap itself rather than requiring a second lookup per wallet.

trader_tags: repeated string

Eleven filter fields

Tokens, traders, pools, venues, size bounds, direction, signature and wallet tags, all applied before the bytes leave the server.

SwapFilter · swap_stream.proto
Plans

Rate limits, stated per second.

Starterentry
$0
Rate
20 RPS
History
Full history
Support
Community
Developer
$50/mo
Rate
100 RPS
Connections
10 concurrent
History
Full history
Support
Email
Pro
$199/mo
Rate
500 RPS
Connections
50 concurrent
History
Full history
Support
Priority

Limits are per second. The plans have no monthly request quota, so none is quoted here.