> ## 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.

# Token price history across every pool

> Get USD OHLCV candles for any token, aggregated across every pool it trades in, with one DexPaprika call. No pool picking, no pair math.

## What you'll build

A USD price chart for any token on any of our networks, from one call per range. The candles are aggregated across every pool the token trades in, so you skip the step that usually comes first: finding the right pool and converting its pair price to dollars.

By the end you will have:

* A curl that returns hourly candles for a token
* A Python function that pulls a longer range in pages and returns a DataFrame
* A TypeScript version for a web chart
* A way to continue the same series live

<Warning>
  **This endpoint needs a Dev, Pro or Enterprise plan.** Keyless requests and free keys get `403` with `{"message":"this endpoint requires a Dev or Pro plan"}`. On the free tier you can build the same chart from a single pool with [pool OHLCV](/tutorials/retrieve-historical-data). Compare plans on [pricing](https://dexpaprika.com/api/pricing) and get your key in [console.dexpaprika.com](https://console.dexpaprika.com).
</Warning>

***

## Why a token series, not a pool series

A token rarely trades in one place. [WETH on Ethereum](/api-reference/tokens/get-a-tokens-latest-data-on-a-network) sits in hundreds of thousands of pools in our index (`summary.pools` on the token), paired with stablecoins, with other majors and with long-tail tokens. Charting it from one pool has three problems:

1. **You have to choose the pool.** The busiest one today may not be the busiest one next month, so a backtest built on it quietly changes venue.
2. **The price is in pair terms.** A WETH/USDC pool prices WETH in USDC. A WETH/WBTC pool prices it in WBTC. You convert, or you only ever use stablecoin pairs.
3. **One pool's volume is not the token's volume.** A single pool undercounts activity, often by a lot.

The token endpoint answers all three. Every candle is a volume-weighted USD price across the token's pools on that network, and `volume` is the USD traded across all of them.

***

## The call

Hourly WETH candles for the last 24 hours:

```bash theme={null}
curl -H "Authorization: $DEXPAPRIKA_API_KEY" \
  "https://api-pro.dexpaprika.com/networks/ethereum/tokens/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2/ohlcv?start=-24h&interval=1h&limit=24"
```

Two things to get right from the first request:

* **Host.** Paid plans use `api-pro.dexpaprika.com`. The key goes in the `Authorization` header as the entire value, nothing in front of it.
* **`interval` and `limit`.** They default to `24h` and `10`. Leave them out and you get ten daily candles, which is rarely what a chart wants.

| Parameter | What it does |
| - | - |
| `start` | Required. `-24h`, `-7d`, `-90m`, an RFC3339 timestamp, a date or Unix seconds. |
| `end` | Optional, same formats. |
| `interval` | `1m`, `5m`, `10m`, `15m`, `30m`, `1h`, `6h`, `12h` or `24h`. |
| `limit` | Candles per request, 1 to 1000. |

The response is an array of candles, oldest first. Here is UNI on Ethereum for three hours on 29 September, a fixed range you can repeat:

```bash theme={null}
curl -H "Authorization: $DEXPAPRIKA_API_KEY" \
  "https://api-pro.dexpaprika.com/networks/ethereum/tokens/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984/ohlcv?start=2026-09-29T05:00:00Z&end=2026-09-29T08:00:00Z&interval=1h&limit=3"
```

```json theme={null}
[
  {"time_open":"2026-09-29T05:00:00Z","time_close":"2026-09-29T06:00:00Z","open":8.5630146329623,"high":8.661425871121041,"low":8.5630146329623,"close":8.661425871121041,"volume":425749},
  {"time_open":"2026-09-29T06:00:00Z","time_close":"2026-09-29T07:00:00Z","open":8.661568793754963,"high":8.760416399493314,"low":8.599524076158955,"close":8.757341687363281,"volume":279004},
  {"time_open":"2026-09-29T07:00:00Z","time_close":"2026-09-29T08:00:00Z","open":8.75679778753968,"high":8.951270464962873,"low":8.756419288173142,"close":8.94618973724396,"volume":714215}
]
```

Prices are USD at full precision; round them for display, not before you store them. `volume` is the USD value traded in the token across all its pools during the candle, as a whole number.

***

## Pull a longer range in Python

One request returns up to 1000 candles. A month of hourly candles fits in one call; a day of one-minute candles does not. This function walks forward in windows of 1000 candles until it reaches `end`:

```python theme={null}
import os
from datetime import datetime, timedelta, timezone

import pandas as pd
import requests

API = "https://api-pro.dexpaprika.com"
HEADERS = {"Authorization": os.environ["DEXPAPRIKA_API_KEY"]}
STEP = {"1m": 60, "5m": 300, "10m": 600, "15m": 900, "30m": 1800,
        "1h": 3600, "6h": 21600, "12h": 43200, "24h": 86400}


def token_ohlcv(network, token, start, end, interval="1h"):
    step = timedelta(seconds=STEP[interval] * 1000)
    rows, cursor = [], start
    while cursor < end:
        window_end = min(cursor + step, end)
        r = requests.get(
            f"{API}/networks/{network}/tokens/{token}/ohlcv",
            headers=HEADERS,
            params={
                "start": cursor.isoformat().replace("+00:00", "Z"),
                "end": window_end.isoformat().replace("+00:00", "Z"),
                "interval": interval,
                "limit": 1000,
            },
            timeout=30,
        )
        r.raise_for_status()
        rows.extend(r.json())
        cursor = window_end
    df = pd.DataFrame(rows)
    if df.empty:
        return df
    df["time_open"] = pd.to_datetime(df["time_open"])
    return df.drop_duplicates("time_open").set_index("time_open")


end = datetime.now(timezone.utc)
df = token_ohlcv(
    "ethereum",
    "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    start=end - timedelta(days=2),
    end=end,
    interval="5m",
)
print(df.tail())
```

Each request costs one credit, however many candles it returns, so 1000-candle windows are also the cheapest way to page.

<Note>
  On Dev, `start` must be inside the last 30 days. Asking for more returns `403` with a message naming the plan that lifts the limit. Pro and Enterprise have no plan limit on history. The table is on [OHLCV limits by plan](/knowledge-base/rate-limits#ohlcv-limits-by-plan).
</Note>

***

## Chart it in TypeScript

The same call from a browser app or a server route. The candle shape maps directly onto most charting libraries:

```typescript theme={null}
type Candle = {
  time_open: string;
  time_close: string;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
};

async function tokenOhlcv(network: string, token: string, start: string, interval = "1h", limit = 500) {
  const url = new URL(`https://api-pro.dexpaprika.com/networks/${network}/tokens/${token}/ohlcv`);
  url.search = new URLSearchParams({ start, interval, limit: String(limit) }).toString();
  const res = await fetch(url, { headers: { Authorization: process.env.DEXPAPRIKA_API_KEY! } });
  if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
  return (await res.json()) as Candle[];
}

const candles = await tokenOhlcv("solana", "So11111111111111111111111111111111111111112", "-7d", "1h", 168);
const series = candles.map((c) => ({
  time: Date.parse(c.time_open) / 1000,
  open: c.open,
  high: c.high,
  low: c.low,
  close: c.close,
}));
```

Keep the key on the server. A key shipped in browser code is a key anyone can read.

***

## Three things that will surprise you

**Quiet intervals have no candle.** A candle exists only for an interval in which the token traded. On a large token at `1h` you will not notice; on a small token at `1m` you will see gaps. Fill them on your side if your chart library needs a continuous axis, usually by carrying the previous close forward with zero volume.

**The last candle may still be open.** If the current interval has not ended, the last candle's `time_close` is earlier than a full interval after `time_open`, and its values keep moving. Re-read it on your next poll instead of treating it as final.

**This is not a pool price.** On a token with a dominant pool the two series sit close together. Where liquidity is split, or one pool is thin, they can differ, and that difference is the point: the token series reflects where the volume actually traded.

***

## Continue the series live

The same token candles are available as a stream on [`/sse/ohlcv`](/streaming/ohlcv-streaming), pushed as each bucket closes, on the same paid plans. Load history from this endpoint, then subscribe for new candles:

```bash theme={null}
curl --http1.1 -N -H "Authorization: $DEXPAPRIKA_API_KEY" \
  "https://streaming-pro.dexpaprika.com/sse/ohlcv?method=token_ohlcv&chain=ethereum&address=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&interval=60s"
```

Key the store on the candle's open time and overwrite on repeat, because the stream can republish a candle with late trades included. The [streaming guide](/streaming/ohlcv-streaming) covers resume and cost.

***

## Where to go next

* [Token OHLCV reference](/api-reference/tokens/get-ohlcv-data-for-a-token): every parameter and response code
* [Pool OHLCV](/tutorials/retrieve-historical-data): one pool's history, available on the free tier
* [OHLCV limits by plan](/knowledge-base/rate-limits#ohlcv-limits-by-plan): intervals and history per plan
* [Pricing](https://dexpaprika.com/api/pricing) and [console.dexpaprika.com](https://console.dexpaprika.com): plans and your key
