---
name: dexpaprika-api
description: "Query on-chain DEX data and stream real-time crypto prices using DexPaprika -- token prices, liquidity pools, OHLCV history, swap transactions, advanced pool filtering, and live price streaming via SSE across 33+ blockchains. Use this skill whenever the user wants to fetch crypto token prices, look up pool or DEX data, get historical candlestick data, find new pools, filter pools by volume/transactions/age, stream live prices, build real-time dashboards, or build anything that needs on-chain DEX data. Also use when the user mentions DexPaprika, dexpaprika, streaming crypto prices, or SSE price feeds. REST docs: https://docs.dexpaprika.com -- Streaming docs: https://docs.dexpaprika.com/streaming/introduction"
---

# DexPaprika API

Free API for on-chain DEX data and real-time price streaming. 33+ blockchains, 25M+ tokens, 27M+ pools. No API key, no authentication.

| Service | Base URL | Purpose |
|---|---|---|
| REST API | `https://api.dexpaprika.com` | Token data, pools, OHLCV, transactions, search |
| Streaming API | `https://streaming.dexpaprika.com` | Real-time price + pool-reserve updates via SSE (`/sse/prices`, `/sse/reserves`). ~1s prices, block-level reserves. [Full docs](https://docs.dexpaprika.com/streaming/introduction) |
| CLI | `curl -sSL .../install.sh \| sh` | Terminal tool wrapping the full API. Install: `curl -sSL https://raw.githubusercontent.com/coinpaprika/dexpaprika-cli/main/install.sh \| sh` |

All examples use curl, but any HTTP client works. The CLI (`dexpaprika-cli`) wraps every endpoint into simple commands with `--output json --raw` for scripting. REST responses are JSON. Streaming responses are Server-Sent Events.

---

## Core concepts

**Network IDs** are lowercase chain identifiers: `ethereum`, `solana`, `bsc`, `arbitrum`, `base`, `polygon`, `optimism`, `avalanche`, etc. Get the full list from `GET /networks`.

**Token addresses** are the on-chain contract addresses (e.g., `0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2` for WETH on Ethereum, `So11111111111111111111111111111111111111112` for SOL on Solana).

**Pool addresses** are the on-chain liquidity pool contract addresses. Find them via token pools or network pools endpoints.

If you don't know the network or address for a token, use search first.

---

## Endpoints

### Search (start here when you don't have addresses)

```
GET /search?query={query}
```

Search tokens, pools, and DEXes by name, symbol, or address. Case-insensitive. Use this to resolve "what's the ETH price" into the actual network + address you need.

**Example:** Find Jupiter token
```bash
curl "https://api.dexpaprika.com/search?query=jupiter"
```

---

### Token price and details

```
GET /networks/{network}/tokens/{token_address}
```

Returns name, symbol, chain, decimals, USD price, fully diluted valuation, liquidity, and volume/transaction stats at multiple time windows (24h, 6h, 1h, 30m, 15m, 5m).

**The price is at** `response.summary.price_usd`

**Example:** Get SOL price
```bash
curl "https://api.dexpaprika.com/networks/solana/tokens/So11111111111111111111111111111111111111112"
```

Extract just the price:
```bash
curl -s "https://api.dexpaprika.com/networks/solana/tokens/So11111111111111111111111111111111111111112" | jq '.summary.price_usd'
```

---

### Batch token prices

```
GET /networks/{network}/multi/prices?tokens={addr1},{addr2},{addr3}
```

Fetch USD prices for multiple tokens in one request. Comma-separated addresses, max 10 per request. Unknown or unpriced tokens are silently omitted from the response.

**Example:** WETH + USDC on Ethereum
```bash
curl "https://api.dexpaprika.com/networks/ethereum/multi/prices?tokens=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2,0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
```

Response is an array of `{id, chain, price_usd}` objects. Order is not guaranteed.

---

### Top pools on a network

```
GET /networks/{network}/pools?page={1}&limit={10}&order_by={volume_usd}&sort={desc}
```

List top liquidity pools. Pages are 1-indexed, max 100 per page. Order by: `volume_usd`, `price_usd`, `transactions`, `last_price_change_usd_24h`, `created_at`.

**Example:** Top 5 Ethereum pools by volume
```bash
curl "https://api.dexpaprika.com/networks/ethereum/pools?limit=5&order_by=volume_usd&sort=desc"
```

---

### Advanced pool filtering (new)

```
GET /networks/{network}/pools/filter
```

Filter pools with range queries on volume, transactions, and creation date. This is the endpoint to use for building pool screeners, finding high-volume pools, or discovering recently created pools that meet specific criteria.

**Parameters:**

| Parameter | Type | Description |
|---|---|---|
| `page` | integer | Page number, **1-indexed** (default: 1) |
| `limit` | integer | Items per page, 1-100 (default: 50) |
| `volume_24h_min` | number | Min 24h volume in USD |
| `volume_24h_max` | number | Max 24h volume in USD |
| `txns_24h_min` | integer | Min transactions in last 24h |
| `created_after` | integer | UNIX timestamp -- only pools created after this |
| `created_before` | integer | UNIX timestamp -- only pools created before this |
| `sort_by` | string | `volume_24h` (default), `txns_24h`, `created_at` |
| `sort_dir` | string | `asc` or `desc` (default: `desc`) |

Note: `volume_7d_min`, `volume_30d_min`, `liquidity_usd_min`, `liquidity_usd_max` exist in the spec but are not functional yet -- they return empty results.

All filters combine with AND logic. The response includes `page_info` with `total_items` and `total_pages`.

**Example:** High-volume Ethereum pools (>$100k daily volume)
```bash
curl "https://api.dexpaprika.com/networks/ethereum/pools/filter?volume_24h_min=100000&sort_by=volume_24h&sort_dir=desc"
```

**Example:** Recently created Solana pools with activity
```bash
curl "https://api.dexpaprika.com/networks/solana/pools/filter?created_after=1709251200&txns_24h_min=50&sort_by=created_at&sort_dir=desc"
```

---

### Pool details

```
GET /networks/{network}/pools/{pool_address}?inversed={false}
```

Returns liquidity, reserves, pricing, token pair info, and DEX metadata for a specific pool. Set `inversed=true` to flip the price ratio (token1/token0 instead of token0/token1).

---

### Pool OHLCV (historical candlesticks)

```
GET /networks/{network}/pools/{pool_address}/ohlcv?start={timestamp}&interval={24h}&limit={30}
```

Historical price candlestick data. `start` is required (ISO 8601 or UNIX timestamp). Optional `end` (max 1 year from start).

**Intervals:** `1m`, `5m`, `10m`, `15m`, `30m`, `1h`, `6h`, `12h`, `24h`
**Max data points:** 366 per request

**Example:** Last 30 days of daily candles for a pool
```bash
curl "https://api.dexpaprika.com/networks/ethereum/pools/0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640/ohlcv?start=2025-01-01&interval=24h&limit=30"
```

---

### Pool transactions

```
GET /networks/{network}/pools/{pool_address}/transactions?page={1}&limit={20}
```

Recent swaps, liquidity adds, and removes. Reverse chronological order. Pages 1-indexed, max 100 pages. For deep pagination, use `cursor` parameter (transaction ID) instead of page numbers.

Each transaction includes: token amounts (`amount_0`, `amount_1`), volumes (`volume_0`, `volume_1`), USD prices (`price_0_usd`, `price_1_usd`), token symbols, sender/recipient, and timestamps.

---

### Pools for a token

```
GET /networks/{network}/tokens/{token_address}/pools?order_by={volume_usd}&sort={desc}&limit={10}
```

Find all pools containing a specific token. Optional: add `address` parameter to filter to pools paired with a second specific token. Add `reorder=true` to make the queried token the primary token in all metrics.

---

### DEXes on a network

```
GET /networks/{network}/dexes
```

List all DEXes on a network with their identifiers. Use the `dex` id to filter pools:

```
GET /networks/{network}/dexes/{dex}/pools
```

---

### Networks

```
GET /networks
```

Returns all supported blockchain networks with their IDs. Use these IDs in all other endpoints.

---

### Platform stats

```
GET /stats
```

High-level counts: total networks, DEXes, pools, and tokens. Useful for health checks.

---

## Streaming API -- Real-time prices and reserves via SSE

Stream live token prices and pool reserves over Server-Sent Events. Works with any HTTP client that supports streaming. Full docs: https://docs.dexpaprika.com/streaming/introduction

**Base URL:** `https://streaming.dexpaprika.com` (no landing page; only the `/sse/*` paths below work)

Two feeds, same transport:
- `/sse/prices` -- token price updates (~1s cadence per asset)
- `/sse/reserves` -- block-level pool reserve updates (push-based, USD-denominated)

The legacy `/stream` path is still accepted but **deprecated**; it now emits a `warning` event on connect and will be removed. The legacy `/reserves/stream` has been retired.

### Stream a single token (GET)

```bash
curl -N "https://streaming.dexpaprika.com/sse/prices?method=token_price&chain=ethereum&address=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
```

### Stream multiple tokens (POST) -- recommended for 2+ tokens

Send a JSON array of assets. Single connection, up to **25 assets**.

```bash
curl -N -X POST "https://streaming.dexpaprika.com/sse/prices" \
  -H "Accept: text/event-stream" \
  -H "Content-Type: application/json" \
  -d '[
    {"chain": "solana",   "address": "So11111111111111111111111111111111111111112",  "method": "token_price"},
    {"chain": "ethereum", "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",   "method": "token_price"}
  ]'
```

Each asset object requires `chain` (network ID), `address` (token contract), and `method` (`token_price`, or the deprecated `t_p` for the legacy compact shape).

### Stream pool reserves (GET, single pool)

```bash
curl -N "https://streaming.dexpaprika.com/sse/reserves?method=pool_reserves&chain=ethereum&address=0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640"
```

`method=pool_reserves` follows one pool. `method=token_reserves` follows every pool containing a given token.

### SSE event formats

Default `token_price` event (full field names):

```
data: {"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","chain":"ethereum","price":"2255.59","timestamp":1778847592,"timestamp_price":1778847592,"token_price":1778847592}
event: token_price
```

`reserve_update` event:

```
data: {"chain":"ethereum","pool_id":"0x88e6...","block":25100507,"tokens":[{"token_id":"0xa0b8...","reserve":"70835095690418","delta":"12018780248","price_usd":1.00,"reserve_usd":70837306.69,"delta_usd":12019.15}, ...],"total_reserve_usd":102848662.93,"total_delta_usd":8.80}
event: reserve_update
```

Keep-alive and notice events:

```
event: ping     | data: {"time": 1778847639}            # every ~15s
event: warning  | data: {"message": "..."}              # deprecation notices, etc.
event: error    | data: {"message": "asset not found"}  # terminating error
```

| Field (`token_price`) | Meaning |
|---|---|
| `address` | Token address |
| `chain` | Chain ID |
| `price` | USD price as string (parse as decimal) |
| `timestamp` | Server send time (unix seconds) |
| `timestamp_price` | Price observation time (unix seconds) |

The legacy `t_p` method instead emits `{a, c, p, t, t_p}` short-keyed objects. Deprecated; do not use in new code.

### Python streaming example

```python
import requests, json

assets = [
    {"chain": "ethereum", "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "method": "token_price"},
    {"chain": "solana",   "address": "So11111111111111111111111111111111111111112",  "method": "token_price"}
]

r = requests.post("https://streaming.dexpaprika.com/sse/prices",
    headers={"Accept": "text/event-stream", "Content-Type": "application/json"},
    json=assets, stream=True)

# Buffer one SSE message between blank lines, then dispatch.
# Wire emits `data:` before `event:`; a line-by-line parser would miss
# the event type. Grouping first is mandatory.
msg_lines = []
for line in r.iter_lines(decode_unicode=True):
    if line:
        msg_lines.append(line)
        continue

    event_type, data_str = "message", None
    for ml in msg_lines:
        if ml.startswith("event:"):
            event_type = ml.split(":", 1)[1].strip()
        elif ml.startswith("data:"):
            data_str = ml[5:].lstrip()
    msg_lines = []

    if event_type == "token_price" and data_str is not None:
        data = json.loads(data_str)
        print(f"{data['chain']} {data['address']}: ${data['price']}")
```

### Streaming constraints

- **Max 25 subscriptions** per POST connection. The two endpoints reject 26+ entries with different wording: `POST /sse/prices` returns `{"message":"too many assets, max 25 allowed"}`, `POST /sse/reserves` returns `{"message":"too many subscriptions"}`.
- **Max 10 concurrent SSE streams per IP.** The 11th returns `429` with `{"message":"ip stream limit exceeded"}`.
- **Ping interval:** 15 seconds. Use a missing `ping` as a connection-liveness signal.
- **All assets must be valid** -- one invalid asset cancels the entire stream with HTTP 400.
- Validate assets via REST `/search` before streaming.
- Reconnect with exponential backoff on disconnect.

### Streaming errors

| Status | Meaning |
|---|---|
| 200 | Connected, streaming |
| 400 | Bad params, unsupported chain, asset not found, or one invalid asset in batch |
| 429 | IP stream limit exceeded (`{"message":"ip stream limit exceeded"}`) -- retry with backoff |

Errors during an active stream arrive as SSE events: `event: error` + `data: {"message": "..."}`. Non-fatal notices (deprecations, etc.) arrive as `event: warning`. Handle HTTP errors (before stream starts), SSE errors (during), and treat unknown event names as no-ops.

---

## Constraints and limits

### REST API
- **Rate limit:** 10,000 requests per day
- **Batch prices:** max 10 tokens per request
- **Pagination:** max 100 items per page
- **OHLCV:** max 366 data points per request, max 1 year range
- **Transactions:** max 100 pages of pagination
- **Pagination:** all endpoints are 1-indexed (page=0 is silently treated as page=1)

### Streaming API
- **Max subscriptions per POST connection:** 25 (`/sse/prices`, `/sse/reserves`)
- **Concurrent SSE streams per IP:** 10 (`429 ip stream limit exceeded` on the 11th)
- **Ping interval:** 15 seconds (`event: ping`)
- **All assets must be valid** or entire stream is cancelled

---

## Error handling

| Status | Meaning | What to do |
|---|---|---|
| 200 | Success | Parse JSON response |
| 400 | Bad request (invalid params, too many tokens, bad sort field) | Check parameter values and constraints above |
| 404 | Network, token, or pool not found | Verify the network ID and address; use /search to find correct values |
| 410 | Endpoint deprecated (old /pools) | Use `/networks/{network}/pools` instead |
| 429 | Rate limit exceeded | Back off and retry; consider caching responses |
| 500 | Server error | Retry with backoff |

When a batch price request contains only invalid tokens, you get HTTP 200 with an empty array -- not an error.

---

## Common workflows

### "What's the price of X?"
1. `GET /search?query=X` to find the network and token address
2. `GET /networks/{network}/tokens/{address}` to get price at `.summary.price_usd`

### "Show me the top pools on Ethereum"
1. `GET /networks/ethereum/pools?limit=10&order_by=volume_usd&sort=desc`

### "Find new pools with high volume"
1. `GET /networks/{network}/pools/filter?created_after={unix_timestamp}&volume_24h_min=50000&sort_by=created_at&sort_dir=desc`

### "Get historical price data for a token"
1. Find the token's pools via `GET /networks/{network}/tokens/{address}/pools?order_by=volume_usd&sort=desc&limit=1` (the highest-volume pool is the best source)
2. `GET /networks/{network}/pools/{pool_address}/ohlcv?start={date}&interval=24h&limit=30`

### "Compare prices of multiple tokens"
1. `GET /networks/{network}/multi/prices?tokens={addr1},{addr2},{addr3}`

### "Stream live price updates for a token"
1. `GET https://streaming.dexpaprika.com/sse/prices?method=token_price&chain={network}&address={token_address}`

### "Build a real-time dashboard tracking multiple tokens"
1. Validate tokens exist via REST: `GET /search?query={name}` or `GET /networks/{network}/tokens/{address}`
2. `POST https://streaming.dexpaprika.com/sse/prices` with JSON array of `{chain, address, method: "token_price"}` objects (up to 25 per connection)
3. Parse SSE events, read price from the `price` field (string -- parse as decimal for precision)

### "Monitor a token's price with alerts"
1. Stream the token via GET or POST to `streaming.dexpaprika.com/sse/prices`
2. Compare each incoming `price` value against your threshold
3. Reconnect with exponential backoff on disconnect

### "Watch a pool's liquidity in real time"
1. `GET https://streaming.dexpaprika.com/sse/reserves?method=pool_reserves&chain={network}&address={pool_address}`
2. Each `reserve_update` event carries `block`, per-token `reserve`/`delta`, USD prices, and `total_delta_usd` (signed dollar change for the block)
3. For multi-pool/multi-token coverage, POST a JSON array (up to 25) to `/sse/reserves` mixing `pool_reserves` and `token_reserves` entries

---

## What this skill does NOT cover

- **CoinPaprika centralized exchange data** -- that's a different API (`api.coinpaprika.com`)
- **Trading or swapping** -- DexPaprika is read-only; it does not execute trades

---

## Full documentation

- [REST API reference](https://docs.dexpaprika.com/api-reference/introduction)
- [Streaming API docs](https://docs.dexpaprika.com/streaming/introduction)
- [Tutorials](https://docs.dexpaprika.com/tutorials/tutorial_intro)
