Skip to main content
Most Solana OHLCV APIs poll pool account state every block or two and build a candle from those snapshots. The price comes from reserves_a / reserves_b, the volume comes from differencing reserves between snapshots. Dexploit doesn’t do that. We process every swap event from the Yellowstone gRPC stream as it arrives, normalize it across protocols (Pump.fun, PumpSwap, Raydium, Meteora), and aggregate the events into bars.

Why this matters for you

Building from events instead of state changes a few things you can rely on:
  • Volume is exact. volume_sol and volume_token on each candle are the sum of actual swap amounts within the bar.
  • Trade counts are real. trade_count, buy_count, sell_count, and unique_traders are direct counts. State-snapshot APIs can’t produce these.
  • No phantom bars. When a pool has zero trades during a 1-minute interval, that interval has no bar. We don’t carry-forward the previous close.
  • Bar boundaries are clean. 1-minute bars start at :00. RPC drops or block-time jitter don’t shift them.

What’s in a candle

{
  "timestamp": "2026-05-09T12:34:00Z",
  "pair_address": "...",
  "token_address": "...",
  "base_mint": "So11111111111111111111111111111111111111112",
  "timeframe": "1m",
  "open": 0.0000178,
  "high": 0.0000182,
  "low":  0.0000176,
  "close": 0.0000181,
  "volume_sol": 12340000000,
  "volume_token": 691234000000,
  "trade_count": 47,
  "buy_count": 25,
  "sell_count": 22,
  "unique_traders": 31
}
base_mint is always wrapped SOL — prices are quoted in SOL.
Both volume_sol and volume_token are integers in base units, despite the names:
  • volume_sol is lamports — divide by 1e9 to get SOL (1234000000012.34 SOL).
  • volume_token is the token’s base units — divide by 10 ** quote_decimals for the human-readable amount.

Comparison with the account-update model

Account-update modelSwap-event model (Dexploit)
SourcePoll pool reservesYellowstone swap stream
Volume accuracyApproximate (delta of reserves)Exact (sum of swap amounts)
Empty barsCarries forward last closeSkipped (no trades = no bar)
Trade countNot availablePer bar
Late RPC blocksBars shift / duplicateBars stay aligned

Getting the data

GET /api/v1/candles for a time range, GET /api/v1/candles/latest for the most-recent N bars. Both require pair_address, not token mint. For real-time bars and ticks, subscribe over WebSocket.