> Documentation index: https://pmdata.dev/llms.txt. Full docs in one file: https://pmdata.dev/llms-full.txt

# API Reference

Source: https://pmdata.dev/docs/api-reference

> Historical market data downloads — daily Parquet files and UpDown ZIP archives.

Base API Endpoint: **https://api.pmdata.dev/v1**

## V1 Parquet API

`https://api.pmdata.dev/v1/{exchange}/{data_type}/{YYYY}/{MM}/{DD}/{symbol}.parquet`

Returns one market or instrument's historical data for one data type and UTC date as a Parquet file. For Polymarket, `symbol` is the `market_slug`; for Chainlink, it is the instrument symbol, such as `BTCUSD`; for Predict.fun, it is the numeric `market_id` for `l2` and `onchain_fills`, and `markets_lifecycle` for `lifecycle` (one file per day with every market).

See [historical data details](https://pmdata.dev/docs/historical-data-details/overview) for availability and [data schemas](https://pmdata.dev/docs/schemas/overview) for file contents.

To find Polymarket markets and the dates PMData has data for, see the [markets catalog](https://pmdata.dev/docs/schemas/markets-catalog).

### Path parameters

All path parameters are required.

| Name | Type | Description |
| --- | --- | --- |
| `exchange` | string | `polymarket`, `chainlink` or `predict_fun`. |
| `data_type` | string | Data type to download. See the supported values below. |
| `YYYY/MM/DD` | string | Valid UTC date with a four-digit year and two-digit month and day, e.g. `2026/08/08`. |
| `symbol` | string | Polymarket `market_slug`, Chainlink instrument symbol, or Predict.fun `market_id` (`markets_lifecycle` for `lifecycle`). Identifiers are case-sensitive. |

### Available data types

| Exchange | Data types |
| --- | --- |
| `polymarket` | [`l2`](https://pmdata.dev/docs/schemas/l2), [`trades`](https://pmdata.dev/docs/schemas/trades), [`onchain_fills`](https://pmdata.dev/docs/schemas/onchain-trades) |
| `chainlink` | [`streams`, `streams_twap30s`, `streams_twap60s`](https://pmdata.dev/docs/schemas/chainlink) |
| `predict_fun` | [`l2`](https://pmdata.dev/docs/schemas/predict-fun/l2), [`onchain_fills`](https://pmdata.dev/docs/schemas/predict-fun/onchain-fills), [`lifecycle`](https://pmdata.dev/docs/schemas/predict-fun/lifecycle) |

Chainlink downloads require a paid plan (Plus: Polymarket or Plus: Predict.fun). Free accounts can download Polymarket data older than 3 weeks (21 days). Supported symbols are listed in [Chainlink historical data details](https://pmdata.dev/docs/historical-data-details/chainlink).

Predict.fun is a separate product with its own allowance: free accounts can download Predict.fun data older than 3 weeks, and data from the last 3 weeks needs Plus: Predict.fun (Plus: Polymarket does not include it). Predict.fun files hold the order book of each market's first outcome only; the `outcome` parameter returns `400`. See [Predict.fun historical data details](https://pmdata.dev/docs/historical-data-details/predict-fun).

### Example

Request one market's L2 data:

```text
https://api.pmdata.dev/v1/polymarket/l2/2026/08/08/will-jd-vance-win-the-2028-us-presidential-election.parquet
```

Request one day of Predict.fun market lifecycle updates:

```text
https://api.pmdata.dev/v1/predict_fun/lifecycle/2026/10/01/markets_lifecycle.parquet
```

### Response

A successful request returns `200 OK` with a Parquet file and consumes one download quota unit. Repeated downloads consume quota again.

Unavailable files return `404 Not Found` and do not consume quota. For Polymarket `trades` and `onchain_fills`, a `404` on a day the market was recorded means it had no trades that day; the [markets catalog](https://pmdata.dev/docs/schemas/markets-catalog) lists which markets were recorded on which days.

This endpoint returns the complete file; byte-range requests are supported by the ZIP API below.

## ZIP API

`https://api.pmdata.dev/v1/polymarket/{data_type}/{YYYY}/{MM}/{DD}/{asset}-{timeframe}.zip`

Returns a ZIP archive of Parquet files for one UpDown asset and timeframe, one data type and one UTC day. This lets you download a day's recorded markets in one request.

ZIP archives use the UpDown dataset. The dated `.parquet` endpoint uses the full-market dataset. See [Polymarket historical data details](https://pmdata.dev/docs/historical-data-details/polymarket) for coverage.

### Path parameters

All path parameters are required.

| Name | Type | Description |
| --- | --- | --- |
| `data_type` | string | `l2`, `trades` or `onchain_fills`. Each archive contains one data type. |
| `YYYY/MM/DD` | string | Valid UTC date with a four-digit year and two-digit month and day, e.g. `2026/08/08`. |
| `asset` | string | `btc`, `eth`, `sol`, `xrp`, `bnb`, `hype` or `doge`, subject to data availability. |
| `timeframe` | string | `5m`, `15m` or `1h`. |

### Example

Download one UTC day of BTC 5-minute UpDown L2 data:

```text
https://api.pmdata.dev/v1/polymarket/l2/2026/08/08/btc-5m.zip
```

### Response and download quota

A successful request returns `200 OK` with `Content-Type: application/zip`. The archive contains the available market Parquet files for the requested series and date. An unavailable archive returns `404 Not Found`.

Quota is charged per archive and data type:

| Timeframe | Download quota units |
| --- | ---: |
| `5m` | 72 |
| `15m` | 24 |
| `1h` | 6 |

### Resuming downloads

ZIP downloads support a single byte range. Send `Range: bytes=START-` to resume an interrupted download, or `Range: bytes=START-END` to request a specific portion. A valid range returns `206 Partial Content` with a `Content-Range` header.

Requests starting after byte 0 do not consume additional download quota. A full download or a range starting at byte 0 consumes the archive's normal quota. Suffix ranges and multiple ranges are not supported; invalid or out-of-bounds ranges return `416 Range Not Satisfiable`.

## Errors

| Status | Meaning |
| --- | --- |
| `401 Unauthorized` | The API key is missing, invalid, or expired. |
| `400 Bad Request` | An invalid `outcome` value, `outcome` on a data type that does not support it, or any `outcome` on Predict.fun. |
| `403 Forbidden` | The account is blocked from downloading, a free account requested Chainlink data or Polymarket data from the last 3 weeks, or an account without Plus: Predict.fun requested Predict.fun data from the last 3 weeks. |
| `404 Not Found` | The path or parameters are invalid, or the requested file is unavailable. |
| `416 Range Not Satisfiable` | The requested ZIP byte range is invalid or out of bounds. |
| `429 Too Many Requests` | The account's download quota has been used up. |

Error responses generally contain a JSON `error` field and may include a `message`. A free account requesting Chainlink data receives `403 Forbidden`:

```json
{
  "error": "Chainlink data is not included in the free tier. Please upgrade at https://pmdata.dev/pricing"
}
```

A free account requesting Polymarket data from the last 3 weeks receives `403 Forbidden`:

```json
{
  "error": "Data from the last 3 weeks is not included in the free tier. Please upgrade at https://pmdata.dev/pricing"
}
```

An account without Plus: Predict.fun requesting Predict.fun data from the last 3 weeks receives `403 Forbidden`:

```json
{
  "error": "Predict.fun data from the last 3 weeks requires the Plus: Predict.fun plan. Please upgrade at https://pmdata.dev/pricing"
}
```

When a free account has insufficient download quota, the API returns `429 Too Many Requests`:

```json
{
  "error": "You have used up all your free download quota. Please upgrade at https://pmdata.dev/pricing",
  "message": "You have used up all your free download quota. Please upgrade at https://pmdata.dev/pricing"
}
```

Paid accounts with insufficient download quota receive `429 Too Many Requests`:

```json
{
  "error": "Too Many Requests",
  "message": "Download quota has been used up."
}
```

An invalid ZIP range returns an empty body with a `Content-Range: bytes */FILE_SIZE` header.

## Deprecated endpoints

**These endpoints still work and return the same data as the V1 API.** Use the V1 endpoints above for new code.

`https://api.pmdata.dev/download/{data_type}/{market_slug}.parquet`

Supports UpDown 5m, 15m and 1h markets only.

`https://api.pmdata.dev/polymarket/{asset}-{timeframe}/{data_type}/{asset}-{timeframe}_{data_type}_{YYYY}-{MM}-{DD}.zip`

Returns the same file as the [ZIP API](#zip-api).

`https://api.pmdata.dev/chainlink/{symbol}/{data_type}/{symbol}_{data_type}_{YYYY}-{MM}-{DD}.parquet`

Returns the same file as the [V1 Parquet API](#v1-parquet-api) for Chainlink.

`/get-download-url`, `/get-download-urls` and the `poly_snapshot` and `snapshot` data types return `410 Gone`. To get order book snapshots, download `l2` data and generate them with [l2_to_snapshot.py](https://github.com/mileswangs/pm-cookbook/blob/main/data/l2_to_snapshot.py).
