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 venuesSWAPSOne 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.
wss://ws.dexploit.dev/ws/swapsconnectingA 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.
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.
…
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.
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.
/swapsNewest fills first, with filters/swaps/rangeA time or slot window, paged/swaps/whaleFills above a lamport threshold/swaps/{signature}One transaction, returned bare/swaps/trader/{wallet}A wallet's history plus lifetime stats/swaps/token/{mint}Every pool for a mint, plus token statstokenstringMint address: aggregates across every pool
traderstringWallet address, matched against user
poolstringOne pair_address
dexstringThe venue name, not the integer id
is_buybooleantrue is SOL → token, false is token → SOL
min_solintegerLamports, and it must be a whole number
limit / offsetinteger100 per page; page while has_more is true
signaturestringSolana transaction signature, base58, fullslotint64The slot the transaction landed intimestampint64Epoch milliseconds; seconds on the WebSocketdexint 1–10Integer venue id; the stream sends the namepair_addressstringThe on-chain pool / LP accounttoken_addressstringThe non-SOL side of the pooluserstringTrader wallet, full, not truncatedis_buybooleantrue is SOL → tokensol_amountint64Lamports: divide by 1e9 for SOLtoken_amountint64Base units: divide by 10**quote_decimalsprice_per_tokennumberLamports per atomic token unit: raw, not SOL per tokenpool_pricenumberPost-trade mid in SOL per whole tokenprice_impact_bpsintFill against pre-trade mid, basis pointsfeeint64LP fee paid, in lamportsfee_bpsintEffective LP fee in basis pointscreator_feeint64Creator-set fee: pump.fun and meteora_dbccreator_fee_bpsintThe same fee expressed in basis pointsbase_decimalsintDecimals of the SOL side, typically 9quote_decimalsintDecimals of the token sidereal_sol_reservesint64Pool SOL reserves after this swapreal_token_reservesint64Pool token reserves after this swapprice_per_tokenIt 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 shapesREST 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_solLamports, 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-specificfee, 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_addressThe 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 envelopeEvery path returns { swaps, total, has_more } and pages by incrementing offset, except /swaps/{signature}, which returns the swap object bare.
Pick by the shape of your client, not by a benchmark. The fill is the same either way; only the encoding and the field names change.
wss://ws.dexploit.dev/ws/swapsJSON framesBrowser-native, no build step. Subscribe with server-side filters and read swap_type, the venue string and epoch seconds.
gRPC over HTTP/2ProtobufGenerate a typed client from the published .proto in Python, Go, Rust or Node for a long-running service.
GET /api/v1/candlesJSONThe same fills aggregated into OHLCV across eight timeframes, when you want bars rather than prints.
Size and venue filters are applied before the response is built, so what you pay to receive is what you asked for.
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'Press Run to execute this request against the live API.
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 venuesTrader classification is attached to the swap itself rather than requiring a second lookup per wallet.
trader_tags: repeated stringTokens, traders, pools, venues, size bounds, direction, signature and wallet tags, all applied before the bytes leave the server.
SwapFilter · swap_stream.protoLimits are per second. The plans have no monthly request quota, so none is quoted here.