> For the complete documentation index, see [llms.txt](https://docs.tardis.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tardis.dev/historical-data-details/polymarket.md).

# Polymarket

Polymarket historical data is available since **2026-05-25**.

{% embed url="<https://api.tardis.dev/v1/exchanges/polymarket>" %}
See Polymarket historical data coverage: channels, dataset date ranges and incidents. Find CLOB token IDs through the Polymarket API as described below.
{% endembed %}

### Downloadable **CSV** files

Historical CSV datasets for the first day of each month are **available to download without API key**. See [downloadable CSV files documentation](/downloadable-csv-files/overview.md).

Polymarket CSV exports use CLOB token IDs as per-symbol file names. The grouped daily trades file uses the `PREDICTIONS` symbol.

| data type             | symbol                                                                        | date       |                                                                                                                                                                                  |
| --------------------- | ----------------------------------------------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| trades                | PREDICTIONS                                                                   | 2026-06-01 | [Download sample](https://datasets.tardis.dev/v1/polymarket/trades/2026/06/01/PREDICTIONS.csv.gz)                                                                                |
| trades                | 57661695455036831478287776153129850803351574978201924270494418960712051882696 | 2026-06-01 | [Download sample](https://datasets.tardis.dev/v1/polymarket/trades/2026/06/01/57661695455036831478287776153129850803351574978201924270494418960712051882696.csv.gz)              |
| book\_ticker          | 97903420938606091954598995247916642127489952123621529862160273048309855576367 | 2026-06-01 | [Download sample](https://datasets.tardis.dev/v1/polymarket/book_ticker/2026/06/01/97903420938606091954598995247916642127489952123621529862160273048309855576367.csv.gz)         |
| incremental\_book\_L2 | 27240772368842340548393958038359200077022257197570320676979474039971830802302 | 2026-06-01 | [Download sample](https://datasets.tardis.dev/v1/polymarket/incremental_book_L2/2026/06/01/27240772368842340548393958038359200077022257197570320676979474039971830802302.csv.gz) |
| quotes                | 27240772368842340548393958038359200077022257197570320676979474039971830802302 | 2026-06-01 | [Download sample](https://datasets.tardis.dev/v1/polymarket/quotes/2026/06/01/27240772368842340548393958038359200077022257197570320676979474039971830802302.csv.gz)              |
| book\_snapshot\_5     | 27240772368842340548393958038359200077022257197570320676979474039971830802302 | 2026-06-01 | [Download sample](https://datasets.tardis.dev/v1/polymarket/book_snapshot_5/2026/06/01/27240772368842340548393958038359200077022257197570320676979474039971830802302.csv.gz)     |
| book\_snapshot\_25    | 27240772368842340548393958038359200077022257197570320676979474039971830802302 | 2026-06-01 | [Download sample](https://datasets.tardis.dev/v1/polymarket/book_snapshot_25/2026/06/01/27240772368842340548393958038359200077022257197570320676979474039971830802302.csv.gz)    |

### API Access and data format

Historical data format is the same as provided by real-time Polymarket WebSocket APIs with addition of local timestamps. Polymarket symbols in Tardis.dev APIs are CLOB token IDs, not event slugs or market questions. In Polymarket market channel messages this identifier appears as `asset_id`.

Symbol filters apply to per-token market data such as `book`, `price_change`, `last_trade_price`, and `best_bid_ask`. Market-level channels such as `tick_size_change`, `new_market`, `market_resolved`, and `sport_result` do not require symbols.

If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview.md) or official [client libs](/api/quickstart.md) that can perform data normalization client-side.

{% tabs %}
{% tab title="Python" %}

```python
# pip install tardis-dev
import asyncio
from tardis_dev import Channel, replay

symbols = [
    "27240772368842340548393958038359200077022257197570320676979474039971830802302",
    "33657678411548069412646838419011738363351964246263910293068444617014480555282",
]

async def main():
    async for local_timestamp, message in replay(
        exchange="polymarket",
        from_date="2026-06-01",
        to_date="2026-06-02",
        filters=[
            Channel(name="price_change", symbols=symbols),
            Channel(name="book", symbols=symbols),
        ],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Polymarket real-time stream
        print(local_timestamp, message)

asyncio.run(main())
```

See [Python client docs](/python-client/quickstart.md).
{% endtab %}

{% tab title="Node.js" %}

```javascript
// npm install tardis-dev
// Save as replay.mjs
import { replay } from 'tardis-dev';

const symbols = [
  '27240772368842340548393958038359200077022257197570320676979474039971830802302',
  '33657678411548069412646838419011738363351964246263910293068444617014480555282'
];

const messages = replay({
  exchange: 'polymarket',
  from: '2026-06-01',
  to: '2026-06-02',
  filters: [
    { channel: 'price_change', symbols },
    { channel: 'book', symbols }
  ],
  apiKey: 'YOUR_API_KEY'
});

// messages as provided by Polymarket real-time stream
for await (const { localTimestamp, message } of messages) {
  console.log(localTimestamp, message);
}
```

See [Node.js client docs](/node-client/quickstart.md).
{% endtab %}

{% tab title="cURL & HTTP API" %}

```bash
filters='[
  {"channel":"price_change","symbols":[
    "27240772368842340548393958038359200077022257197570320676979474039971830802302",
    "33657678411548069412646838419011738363351964246263910293068444617014480555282"
  ]},
  {"channel":"book","symbols":[
    "27240772368842340548393958038359200077022257197570320676979474039971830802302",
    "33657678411548069412646838419011738363351964246263910293068444617014480555282"
  ]}
]'

curl --compressed --get 'https://api.tardis.dev/v1/data-feeds/polymarket' \
  --data-urlencode 'from=2026-06-01' \
  --data-urlencode "filters=${filters}" \
  --data-urlencode 'offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01&filters=%5B%7B%22channel%22%3A%22price_change%22%2C%22symbols%22%3A%5B%2227240772368842340548393958038359200077022257197570320676979474039971830802302%22%2C%2233657678411548069412646838419011738363351964246263910293068444617014480555282%22%5D%7D%2C%7B%22channel%22%3A%22book%22%2C%22symbols%22%3A%5B%2227240772368842340548393958038359200077022257197570320676979474039971830802302%22%2C%2233657678411548069412646838419011738363351964246263910293068444617014480555282%22%5D%7D%5D&offset=0>" %}
Example API response for Polymarket historical market data request
{% endembed %}

See [HTTP API docs](/api/http-api-reference.md).
{% endtab %}

{% tab title="cURL & tardis-machine" %}

```bash
replay_options='{
  "exchange":"polymarket",
  "filters":[
    {"channel":"price_change","symbols":[
      "27240772368842340548393958038359200077022257197570320676979474039971830802302",
      "33657678411548069412646838419011738363351964246263910293068444617014480555282"
    ]},
    {"channel":"book","symbols":[
      "27240772368842340548393958038359200077022257197570320676979474039971830802302",
      "33657678411548069412646838419011738363351964246263910293068444617014480555282"
    ]}
  ],
  "from":"2026-06-01",
  "to":"2026-06-02"
}'

curl --get 'http://localhost:8000/replay' \
  --data-urlencode "options=${replay_options}"
```

[Tardis-machine](/tardis-machine/quickstart.md) is a locally runnable server that exposes API allowing efficiently requesting historical market data for whole time periods in contrast to [HTTP API](/api/http-api-reference.md) that provides data only in minute by minute slices.

See [tardis-machine](/tardis-machine/quickstart.md) docs.
{% endtab %}
{% endtabs %}

### Download data for a Polymarket event

Tardis.dev does not mirror Polymarket's full instrument catalog. The `availableSymbols` field in `/v1/exchanges/polymarket` is empty, and `/v1/instruments/polymarket` does not enumerate CLOB token IDs. Use Polymarket's public [Gamma API](https://docs.polymarket.com/api-reference/introduction) as the source of truth for events, markets, outcomes and token IDs. It does not require an API key.

Polymarket [groups one or more markets under an event](https://docs.polymarket.com/concepts/markets-events). Each market outcome has its own CLOB token ID, which Tardis.dev uses as the symbol. For a known event, start with its Polymarket URL and use the value after `/event/` as the event slug. The examples below:

1. fetch the event from Gamma,
2. select a market by its question and an outcome by its label,
3. map the outcome to its CLOB token ID, and
4. download the corresponding Tardis.dev CSV dataset.

They use [this historical event](https://polymarket.com/event/what-price-will-ethereum-hit-may-25-31-2026), market `Will Ethereum dip to $1,800 May 25-31?` and outcome `No`. Change those values, `data_type` and `date` for your use case.

{% tabs %}
{% tab title="Python" %}

```python
# pip install requests
import json
import os
from pathlib import Path

import requests

event_slug = "what-price-will-ethereum-hit-may-25-31-2026"
market_question = "Will Ethereum dip to $1,800 May 25-31?"
outcome = "No"
data_type = "trades"
date = "2026-06-01"

response = requests.get(
    f"https://gamma-api.polymarket.com/events/slug/{event_slug}",
    timeout=30,
)
response.raise_for_status()
event = response.json()

market = next(
    (item for item in event["markets"] if item["question"] == market_question),
    None,
)
if market is None:
    raise ValueError("Market not found. Check market_question against the event page.")

outcomes = json.loads(market["outcomes"])
token_ids = json.loads(market["clobTokenIds"])
if outcome not in outcomes:
    raise ValueError(f"Outcome must be one of: {', '.join(outcomes)}")
token_id = token_ids[outcomes.index(outcome)]

date_path = date.replace("-", "/")
url = f"https://datasets.tardis.dev/v1/polymarket/{data_type}/{date_path}/{token_id}.csv.gz"
output = Path(f"polymarket_{data_type}_{date}_{token_id}.csv.gz")
headers = {}
if api_key := os.getenv("TARDIS_API_KEY"):
    headers["Authorization"] = f"Bearer {api_key}"

with requests.get(url, headers=headers, stream=True, timeout=(10, 300)) as response:
    response.raise_for_status()
    with output.open("wb") as file:
        for chunk in response.iter_content(chunk_size=1024 * 1024):
            file.write(chunk)

print(token_id)
print(output)
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
// Save as polymarket-download.mjs
import { createWriteStream } from 'node:fs';
import { Readable } from 'node:stream';
import { pipeline } from 'node:stream/promises';

const eventSlug = 'what-price-will-ethereum-hit-may-25-31-2026';
const marketQuestion = 'Will Ethereum dip to $1,800 May 25-31?';
const outcome = 'No';
const dataType = 'trades';
const date = '2026-06-01';

const eventResponse = await fetch(
  `https://gamma-api.polymarket.com/events/slug/${encodeURIComponent(eventSlug)}`
);
if (!eventResponse.ok) throw new Error(`Gamma API returned ${eventResponse.status}`);
const event = await eventResponse.json();

const market = event.markets.find((item) => item.question === marketQuestion);
if (!market) throw new Error('Market not found. Check marketQuestion against the event page.');

const outcomes = JSON.parse(market.outcomes);
const tokenIds = JSON.parse(market.clobTokenIds);
const outcomeIndex = outcomes.indexOf(outcome);
if (outcomeIndex === -1) throw new Error(`Outcome must be one of: ${outcomes.join(', ')}`);
const tokenId = tokenIds[outcomeIndex];

const datePath = date.replaceAll('-', '/');
const url = `https://datasets.tardis.dev/v1/polymarket/${dataType}/${datePath}/${tokenId}.csv.gz`;
const output = `polymarket_${dataType}_${date}_${tokenId}.csv.gz`;
const headers = process.env.TARDIS_API_KEY
  ? { Authorization: `Bearer ${process.env.TARDIS_API_KEY}` }
  : {};

const datasetResponse = await fetch(url, { headers });
if (!datasetResponse.ok) throw new Error(`Datasets API returned ${datasetResponse.status}`);
await pipeline(Readable.fromWeb(datasetResponse.body), createWriteStream(output));

console.log(tokenId);
console.log(output);
```

{% endtab %}

{% tab title="cURL and jq" %}

```bash
#!/usr/bin/env bash
set -euo pipefail

event_slug='what-price-will-ethereum-hit-may-25-31-2026'
market_question='Will Ethereum dip to $1,800 May 25-31?'
outcome='No'
data_type='trades'
date='2026-06-01'

token_id="$(
  curl --silent --show-error --fail \
    "https://gamma-api.polymarket.com/events/slug/${event_slug}" |
    jq --exit-status --raw-output \
      --arg question "${market_question}" \
      --arg outcome "${outcome}" '
        (.markets[] | select(.question == $question)) as $market
        | ($market.outcomes | fromjson) as $outcomes
        | ($market.clobTokenIds | fromjson) as $tokens
        | ($outcomes | index($outcome)) as $index
        | if $index == null then error("outcome not found") else $tokens[$index] end
      '
)"

date_path="${date:0:4}/${date:5:2}/${date:8:2}"
output="polymarket_${data_type}_${date}_${token_id}.csv.gz"
curl_args=(--fail --location --output "${output}")
if [[ -n "${TARDIS_API_KEY:-}" ]]; then
  curl_args+=(--header "Authorization: Bearer ${TARDIS_API_KEY}")
fi

curl "${curl_args[@]}" \
  "https://datasets.tardis.dev/v1/polymarket/${data_type}/${date_path}/${token_id}.csv.gz"

printf '%s\n%s\n' "${token_id}" "${output}"
```

{% endtab %}
{% endtabs %}

The example date is the first UTC day of a month, so it works without an API key. Set `TARDIS_API_KEY` for other dates. A `404` means no file was exported for that token, data type and date, or that the requested date has not been exported yet. Use a data type from the CSV table above and a date between the market's `startDate` and `endDate`.

Gamma returns `outcomes` and `clobTokenIds` as JSON-encoded arrays. Values at the same index belong together; the examples preserve this mapping rather than treating an event or market slug as a tradable symbol.

#### Discover events without a URL

For a specific event, Polymarket recommends fetching the event by the slug from its URL. For broader discovery, [fetch events with pagination or tag filters](https://docs.polymarket.com/market-data/fetching-markets); each event includes its markets:

```bash
curl --silent --show-error --fail --get \
  'https://gamma-api.polymarket.com/events' \
  --data-urlencode 'tag_slug=crypto' \
  --data-urlencode 'active=true' \
  --data-urlencode 'closed=false' \
  --data-urlencode 'order=volume24hr' \
  --data-urlencode 'ascending=false' \
  --data-urlencode 'limit=20' \
  --data-urlencode 'offset=0' |
  jq -r '.[] | [.title, .slug] | @tsv'
```

Increase `offset` by `limit` until Gamma returns an empty array. Gamma also provides a `/markets` endpoint for market-level pagination. Starting from `/events` is usually simpler when the user-facing event may contain multiple related markets.

#### Discover traded tokens from grouped trades

The grouped `PREDICTIONS` trades file is an alternative when you need every token that traded on a specific UTC date and do not need event, question or outcome metadata. Its `symbol` column contains CLOB token IDs.

Download `https://datasets.tardis.dev/v1/polymarket/trades/YYYY/MM/DD/PREDICTIONS.csv.gz` as `polymarket_trades_YYYY-MM-DD_PREDICTIONS.csv.gz`, then run this example to create a list of per-token order book dataset URLs:

```python
import csv
import gzip
from pathlib import Path

date = "2026-06-01"
data_type = "incremental_book_L2"
trades_file = Path(f"polymarket_trades_{date}_PREDICTIONS.csv.gz")

with gzip.open(trades_file, mode="rt", newline="") as file:
    token_ids = sorted({row["symbol"] for row in csv.DictReader(file)})

date_path = date.replace("-", "/")
urls = [
    f"https://datasets.tardis.dev/v1/polymarket/{data_type}/{date_path}/{token_id}.csv.gz"
    for token_id in token_ids
]
Path(f"polymarket_{data_type}_{date}_urls.txt").write_text("\n".join(urls) + "\n")
print(f"Found {len(token_ids)} traded tokens")
```

This method finds only tokens with at least one trade in that file; it misses non-trading markets and does not map tokens back to events or outcomes. A generated URL can still return `404` when no file of that data type was exported. `PREDICTIONS` is not a CLOB token ID and cannot be used for order book datasets or raw replay symbol filters.

#### Replay raw data for a token

Use the same CLOB token ID as the symbol in Tardis.dev replay filters. For example:

```json
[
  {
    "channel": "book",
    "symbols": [
      "57661695455036831478287776153129850803351574978201924270494418960712051882696"
    ]
  }
]
```

The Python, Node.js, HTTP API and tardis-machine examples above show how to pass these filters for a historical date range.

### Captured real-time channels

{% embed url="<https://docs.polymarket.com/market-data/websocket/market-channel>" %}
See Polymarket market WebSocket API docs providing documentation for captured CLOB market channel message format
{% endembed %}

{% hint style="info" %}
Click any channel below to see [HTTP API](/api/http-api-reference.md#data-feeds-exchange) response with historical data recorded for it.
{% endhint %}

* [book](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22book%22%2C%22symbols%22%3A%5B%2227240772368842340548393958038359200077022257197570320676979474039971830802302%22%2C%2233657678411548069412646838419011738363351964246263910293068444617014480555282%22%5D%7D%5D\&offset=0) Full order book snapshots on subscription and after trades that affect the book. Initial subscription data can include several book objects in one message.
* [price\_change](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22price_change%22%2C%22symbols%22%3A%5B%2227240772368842340548393958038359200077022257197570320676979474039971830802302%22%2C%2233657678411548069412646838419011738363351964246263910293068444617014480555282%22%5D%7D%5D\&offset=0) Price level updates from new or cancelled orders. A single message can include updates for multiple outcome tokens in `price_changes[]`.
* [last\_trade\_price](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22last_trade_price%22%2C%22symbols%22%3A%5B%2257661695455036831478287776153129850803351574978201924270494418960712051882696%22%5D%7D%5D\&offset=0) Trade execution updates
* [best\_bid\_ask](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22best_bid_ask%22%2C%22symbols%22%3A%5B%2297903420938606091954598995247916642127489952123621529862160273048309855576367%22%2C%2225478893375766865676296946735029591994839079976867058408152132323725402792931%22%5D%7D%5D\&offset=0) Best bid and ask price updates
* [tick\_size\_change](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22tick_size_change%22%7D%5D\&offset=1) Minimum tick size changes. This is a market-level event; symbol filters do not narrow results.
* [new\_market](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22new_market%22%7D%5D\&offset=10) New market creation events with market metadata. This is a market-level event; symbol filters do not narrow results.
* [market\_resolved](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22market_resolved%22%7D%5D\&offset=0) Market resolution events with winning outcome metadata. This is a market-level event; symbol filters do not narrow results.
* [sport\_result](https://api.tardis.dev/v1/data-feeds/polymarket?from=2026-06-01\&filters=%5B%7B%22channel%22%3A%22sport_result%22%7D%5D\&offset=0) Live sports scores, periods, and game status updates. This channel is collected from Polymarket's separate Sports WebSocket and is not symbol-filtered.

### Market data collection details

[Market data collection infrastructure](/faq/general.md#what-is-your-infrastructure-setup) for Polymarket is located in GCP europe-west2 (London, Europe).

Polymarket's exchange infrastructure is located in AWS eu-west-2 (London, Europe).

CLOB market data is captured via Cloudflare-proxied WebSocket connections to `wss://ws-subscriptions-clob.polymarket.com/ws/market`. Sports results are captured from Polymarket's separate Sports WebSocket at `wss://sports-api.polymarket.com/ws`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tardis.dev/historical-data-details/polymarket.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
