Documentation Index
Fetch the complete documentation index at: https://docs.dexpaprika.com/llms.txt
Use this file to discover all available pages before exploring further.
DexPaprika API — Verified Reference (2026-03-02)
Every claim in this document was verified against the live API with 72 tests, 72 pass, 0 failures.
Base URLs
| Service | URL | Notes |
|---|
| REST API | https://api.dexpaprika.com | JSON responses, no auth |
| Streaming API | https://streaming.dexpaprika.com | SSE only on /stream path. Bare URL returns {"message":"Not Found"} (404) |
| Streaming docs | https://docs.dexpaprika.com/streaming/introduction | Human-readable docs |
- Pages are 1-indexed.
page=0 is silently treated as page=1.
- Max
limit is 100. Values >100 return HTTP 400 (rejected, not capped).
- Exception:
/pools/filter uses wrapper key results instead of pools.
All paginated responses include:
"page_info": {
"limit": 10,
"page": 1,
"total_items": 7838,
"total_pages": 784
}
Endpoints
GET /networks
Response: Flat array (no wrapper, no page_info).
[
{"id": "ethereum", "display_name": "Ethereum"},
{"id": "solana", "display_name": "Solana"}
]
- 33 networks as of 2026-03-02
- Each item: 2 keys —
id (string), display_name (string)
- Common IDs:
ethereum, solana, bsc, arbitrum, base, polygon, optimism, avalanche
GET /stats
Response: Flat object (no wrapper).
{
"chains": 33,
"factories": 205,
"pools": 28185674,
"tokens": 25916463
}
- 4 keys:
chains, factories, pools, tokens
- Key is
factories, NOT dexes — this is the DEX/factory count
GET /search?query=
Response: Object with 3 array keys.
{
"tokens": [...],
"pools": [...],
"dexes": [...]
}
- Case-insensitive
- Empty query → 400
- Token result shape (15 keys):
| Key | Type | Notes |
|---|
id | string | Contract address |
name | string | |
symbol | string | |
chain | string | Network ID |
type | string | Often empty |
status | string | e.g. "visible" |
decimals | number | |
total_supply | number | |
description | string | |
website | string | |
explorer | string | |
price_usd | number | |
liquidity_usd | number | |
volume_usd | number | |
price_usd_change | number | |
- Pool result shape includes:
id, dex_id, dex_name, chain, created_at_block_number, created_at, volume_usd, transactions, price_usd, last_price_change_usd_5m (nullable), last_price_change_usd_1h (nullable), last_price_change_usd_24h (nullable), tokens (array)
NOTE: Search token shape is DIFFERENT from token details shape. Search tokens do NOT have has_image, added_at, price_stats, summary, or last_updated.
GET /networks//tokens/
Response: Flat object (no wrapper).
Top-level keys (13 total):
| Key | Type | Notes |
|---|
id | string | Contract address |
name | string | |
symbol | string | |
chain | string | |
decimals | number | |
total_supply | number | |
description | string | |
website | string | |
has_image | boolean | |
added_at | string | ISO 8601 |
price_stats | object | See below |
summary | object | See below |
last_updated | string | ISO 8601 |
price_stats (4 keys):
| Key | Type |
|---|
high_24h | number |
low_24h | number |
ath | number |
ath_date | string |
summary (13 keys):
| Key | Type |
|---|
chain | string |
id | string |
price_usd | number |
fdv | number |
liquidity_usd | number |
pools | number |
24h | object |
6h | object |
1h | object |
30m | object |
15m | object |
5m | object |
1m | object |
Price is at: response.summary.price_usd
summary.main_pool does NOT exist. There is no main_pool field anywhere in this response.
Each time window object (8 keys, same shape for all intervals):
| Key | Type | Notes |
|---|
volume | number | Volume in token units |
volume_usd | number | Volume in USD |
sells | number | Plural with ‘s’ |
buys | number | Plural with ‘s’ |
txns | number | Total transactions |
buy_usd | number | |
sell_usd | number | |
last_price_usd_change | number | Percentage |
CRITICAL: Fields are sells and buys (plural). NOT sell/buy (singular). The singular forms do not exist.
GET /networks//multi/prices?tokens=,
Response: Flat array (no wrapper, no page_info).
[
{"chain": "ethereum", "id": "0xc02a...", "price_usd": 1975.75},
{"chain": "ethereum", "id": "0xa0b8...", "price_usd": 1.0001}
]
- Each item: 3 keys —
chain, id, price_usd
- Order is NOT guaranteed
- Max 10 tokens. 11+ returns 400 with
{"message":"max 10 tokens allowed."}
- Invalid/unknown tokens are silently omitted (not an error)
- All-invalid tokens → HTTP 200 with empty array
[]
- Comma-separated addresses in a single
tokens param
GET /networks//pools
Response: {pools: [...], page_info: {...}}
Parameters:
| Param | Values | Default |
|---|
page | 1-indexed integer | 1 |
limit | 1-100 | 10 |
order_by | volume_usd, price_usd, transactions, last_price_change_usd_24h, created_at | volume_usd |
sort | asc, desc | desc |
Pool item keys (14 total):
| Key | Type | Notes |
|---|
id | string | Pool contract address |
chain | string | |
dex_id | string | |
dex_name | string | |
fee | number | |
created_at | string | ISO 8601 |
created_at_block_number | number | |
volume_usd | number | |
transactions | number | |
price_usd | number | |
last_price_change_usd_5m | number/null | Can be null |
last_price_change_usd_1h | number/null | Can be null |
last_price_change_usd_24h | number/null | Can be null |
tokens | array | Token summary objects |
GET /networks//pools/filter
Response: {results: [...], page_info: {...}}
Note: wrapper key is results, not pools.
Parameters:
| Param | Type | Description | Default |
|---|
page | integer | 1-indexed | 1 |
limit | integer | 1-100 | 50 |
volume_24h_min | number | Min 24h volume USD | — |
volume_24h_max | number | Max 24h volume USD | — |
txns_24h_min | integer | Min transactions 24h | — |
created_after | integer | UNIX timestamp | — |
created_before | integer | UNIX timestamp | — |
sort_by | string | volume_24h, txns_24h, created_at | volume_24h |
sort_dir | string | asc, desc | desc |
Non-functional params (accepted but return 0 results): volume_7d_min, volume_30d_min, liquidity_usd_min, liquidity_usd_max
All filters combine with AND logic.
Filter result item keys (7 total):
| Key | Type | Notes |
|---|
address | string | Not id — different from pool listing |
chain | string | |
dex_id | string | |
volume_usd_24h | number | Not volume_usd — different name |
liquidity_usd | number | |
txns_24h | number | Not transactions — different name |
created_at | string | ISO 8601 |
IMPORTANT field name differences from /pools listing:
/pools listing | /pools/filter results |
|---|
id | address |
volume_usd | volume_usd_24h |
transactions | txns_24h |
GET /networks//pools/
Response: Flat object (no wrapper).
Parameters: inversed (boolean, default: false) — flips the token pair price ratio.
Top-level keys (20 total):
| Key | Type |
|---|
id | string |
chain | string |
dex_id | string |
dex_name | string |
factory_id | string |
fee | number |
created_at | string |
created_at_block_number | number |
last_price | number |
last_price_usd | number |
price_time | string |
price_stats | object |
token_reserves | object |
tokens | array |
24h | object |
6h | object |
1h | object |
30m | object |
15m | object |
5m | object |
GET /networks//pools//ohlcv
Response: Flat array (no wrapper).
Parameters:
| Param | Type | Required | Notes |
|---|
start | string | Yes | ISO 8601 or UNIX timestamp |
end | string | No | Max 1 year from start |
limit | integer | No | Max 366. Values >366 return 400. |
interval | string | No | 1m, 5m, 10m, 15m, 30m, 1h, 6h, 12h, 24h |
inversed | boolean | No | Flip price ratio |
Missing start → 400.
Candle keys (7 total):
| Key | Type |
|---|
time_open | string |
time_close | string |
open | number |
high | number |
low | number |
close | number |
volume | number |
GET /networks//pools//transactions
Response: {transactions: [...], page_info: {...}}
Parameters:
| Param | Default | Notes |
|---|
page | 1 | 1-indexed |
limit | 20 | Max 100 |
cursor | — | Transaction ID for deep pagination |
Max 100 pages via page param. Use cursor for deeper.
Transaction item keys (24 total):
| Key | Type |
|---|
id | string |
log_index | number |
transaction_index | number |
factory_id | string |
pool_id | string |
chain | string |
canonical_chain | string |
sender | string |
recipient | string |
token_0 | string |
token_0_symbol | string |
token_1 | string |
token_1_symbol | string |
amount_0 | number |
amount_1 | number |
volume_0 | number |
volume_1 | number |
price_0 | number |
price_0_usd | number |
price_1 | number |
price_1_usd | number |
created_at_block_number | number |
created_at_block_hash | string |
created_at | string |
GET /networks//tokens//pools
Response: {pools: [...], page_info: {...}}
Parameters:
| Param | Default | Notes |
|---|
page | 1 | 1-indexed |
limit | 10 | |
order_by | volume_usd | Same options as pool listing |
sort | desc | |
address | — | Filter to pools paired with this second token |
reorder | false | Make queried token primary in all metrics |
GET /networks//dexes
Response: {dexes: [...], page_info: {...}}
Note: page_info exists but may show total_items: 0 (appears buggy). The limit param may be ignored — all DEXes are returned.
DEX item keys (4 total):
| Key | Type |
|---|
dex_id | string |
dex_name | string |
chain | string |
protocol | string |
GET /networks//dexes//pools
Response: {pools: [...], page_info: {...}}
Same pool item shape as /networks/{network}/pools.
Streaming API
Two SSE feeds on streaming.dexpaprika.com:
| Path | Purpose |
|---|
/sse/prices | Real-time token prices (~1s cadence per asset) |
/sse/reserves | Block-level pool reserve updates with pre-attached USD prices |
/stream | Deprecated alias for /sse/prices. Still accepted; emits a warning event on connect. Will be removed. |
/reserves/stream | Retired. Now returns 404; use /sse/reserves. |
GET /sse/prices (single token)
GET https://streaming.dexpaprika.com/sse/prices?method=token_price&chain={network}&address={token_address}
POST /sse/prices (multiple tokens, up to 25)
POST https://streaming.dexpaprika.com/sse/prices
Content-Type: application/json
Accept: text/event-stream
[
{"chain": "ethereum", "address": "0xc02a...", "method": "token_price"},
{"chain": "solana", "address": "So111...", "method": "token_price"}
]
GET /sse/reserves (single pool or token)
GET https://streaming.dexpaprika.com/sse/reserves?method=pool_reserves&chain={network}&address={pool_address}
GET https://streaming.dexpaprika.com/sse/reserves?method=token_reserves&chain={network}&address={token_address}
POST /sse/reserves (multiple, up to 25)
POST https://streaming.dexpaprika.com/sse/reserves
Content-Type: application/json
Accept: text/event-stream
[
{"chain": "ethereum", "address": "0x88e6...", "method": "pool_reserves"},
{"chain": "ethereum", "address": "0xa0b8...", "method": "token_reserves"}
]
event: token_price
data: {"address":"0xc02a...","chain":"ethereum","price":"2255.59","timestamp":1778847592,"timestamp_price":1778847592,"token_price":1778847592}
Note: Both event:/data: orderings within a single SSE message are valid per the spec, and the server has emitted either during rollout. Parsers must buffer one message at a time (split on blank line) and dispatch on the parsed event type, not on field order.
Field (token_price) | Type | Description |
|---|
address | string | Token address |
chain | string | Chain ID |
price | string | Price in USD. String, not number. Parse as decimal. |
timestamp | integer | Server send time (unix seconds) |
timestamp_price | integer | Price observation time (unix seconds) |
token_price | integer | Alias of timestamp_price |
Other event types you may receive on either feed:
| Event | Payload | Meaning |
|---|
reserve_update | {chain, pool_id, block, previous_block, tokens[], total_reserve_usd, total_delta_usd} | Pool reserves changed on the latest block |
ping | {"time": <unix>} | Keep-alive, every ~15s |
warning | {"message": "..."} | Non-fatal notice (deprecation, etc.) |
error | {"message": "..."} | Stream-terminating error |
t_p | {a, c, p, t, t_p} | Deprecated compact price shape returned by method=t_p |
Streaming constraints
- Max 25 subscriptions per POST connection. 26+ entries get rejected with HTTP 400. The two endpoints use different rejection wording:
POST /sse/prices → {"message":"too many assets, max 25 allowed"}
POST /sse/reserves → {"message":"too many subscriptions"}
- Max 10 concurrent SSE streams per IP. 11th returns
429 {"message":"ip stream limit exceeded"}.
- Ping interval: 15 seconds (
event: ping). Use a missing ping as a connection-liveness signal.
- All assets must be valid — one invalid asset cancels the entire stream with HTTP 400.
- First reserve events on a quiet pool may take seconds-to-minutes (events arrive only on actual on-chain changes).
- Treat unknown event names as no-ops.
Streaming errors
| Status | Cause | Message |
|---|
| 200 | Connected | Stream begins |
| 400 | Bad chain | {"message":"unsupported chain"} |
| 400 | Bad address | {"message":"asset not found"} |
| 400 | Invalid asset in batch | {"message":"unsupported chain"} (entire stream cancelled) |
| 400 | Too many entries in POST body to /sse/prices (26+) | {"message":"too many assets, max 25 allowed"} |
| 400 | Too many entries in POST body to /sse/reserves (26+) | {"message":"too many subscriptions"} |
| 404 | Bare URL, wrong path, or retired /reserves/stream | {"message":"Not Found"} |
| 429 | IP stream limit | {"message":"ip stream limit exceeded"} |
In-stream errors arrive as SSE: event: error + data: {"message": "..."}. Deprecations and other non-fatal notices arrive as event: warning.
Error handling (REST)
| Status | Cause | Example |
|---|
| 200 | Success | Normal response |
| 400 | Invalid params | Bad order_by, sort, sort_by, empty query, limit >100, OHLCV limit >366, >10 batch tokens |
| 404 | Not found | Invalid network, token, or pool address |
| 410 | Deprecated | GET /pools (use /networks/{network}/pools) |
| 429 | Rate limit | 10,000 req/day exceeded |
| 500 | Server error | Retry with backoff |
Constraints summary
| Constraint | Value | Enforcement |
|---|
| Rate limit | 10,000 requests/day | |
| Pagination max per page | 100 | 400 if exceeded |
| Pagination indexing | 1-indexed | page=0 treated as page=1 |
| Batch prices max tokens | 10 | 400 if exceeded |
| OHLCV max data points | 366 | 400 if exceeded |
| OHLCV max range | 1 year | |
| Transaction max pages | 100 | Use cursor for deeper |
| Streaming max assets/request | 2,000 | |
| Streaming global concurrent | 10,000 per server | |
Common token addresses
| Token | Chain | Address |
|---|
| WETH | ethereum | 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 |
| USDC | ethereum | 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 |
| USDT | ethereum | 0xdac17f958d2ee523a2206206994597c13d831ec7 |
| USDC | polygon | 0x2791bca1f2de4661ed88a30c99a7a9449aa84174 |
| SOL | solana | So11111111111111111111111111111111111111112 |
Key gotchas for implementers
sells/buys not sell/buy — plural forms only in token summary time windows
summary.main_pool does not exist — to find a token’s best pool, query /tokens/{address}/pools?order_by=volume_usd&sort=desc&limit=1
- Filter uses different field names than pool listing:
address not id, volume_usd_24h not volume_usd, txns_24h not transactions
- Filter wrapper key is
results, not pools
- Stats key is
factories, not dexes
- Pages are 1-indexed everywhere — page=0 is silently normalized to page=1
- Limits are enforced, not capped — limit=200 returns 400, not 100 results
- Streaming
p is a string — parse as decimal for precision, do not treat as JSON number
- Streaming bare URL is 404 — only
/stream path works
- Search token shape ≠ token details shape — different fields at top level
- OHLCV is the only flat-array list response — all other list endpoints wrap in
{key: [...], page_info: {...}}
- DEXes endpoint
page_info is buggy — may show total_items: 0 while returning all results
- Non-functional filter params (
volume_7d_min, volume_30d_min, liquidity_usd_min, liquidity_usd_max) are accepted but always return 0 results
- First streaming events may take 10-20 seconds — don’t use short timeouts