# Welcome

The most granular historical and real-time data for cryptocurrency markets — order books, trades, funding, liquidations and more for 50+ exchanges

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="image"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Exchange coverage</strong></td><td>Detailed per-exchange data coverage — available symbols, channels, date ranges and collection details.</td><td><a href="/files/8oAeHvwtiITSwtkIV71u">/files/8oAeHvwtiITSwtkIV71u</a></td><td><a href="/pages/-LrmnoZj89oQppvHaZla">/pages/-LrmnoZj89oQppvHaZla</a></td></tr><tr><td><strong>Downloadable CSV files</strong></td><td>Historical tick-level market data in normalized CSV format — trades, order books, derivatives and more.</td><td><a href="/files/KN4yVGOOPpQfyJjiQ43H">/files/KN4yVGOOPpQfyJjiQ43H</a></td><td><a href="/pages/bFGMWgAgbTAuGtejNMzO">/pages/bFGMWgAgbTAuGtejNMzO</a></td></tr><tr><td><strong>Market data API</strong></td><td>Replay historical data or stream real-time feeds via Python, Node.js, HTTP API or tardis-machine server.</td><td><a href="/files/vlNW1KAq8ABkEmnRUJrt">/files/vlNW1KAq8ABkEmnRUJrt</a></td><td><a href="/pages/FWgFjdwVNpNU4HhTHdVd">/pages/FWgFjdwVNpNU4HhTHdVd</a></td></tr><tr><td><strong>FAQ</strong></td><td>Common questions about data types, order books, billing, subscriptions and more.</td><td><a href="/files/xXQDPTzhvvxJpqd5yAiJ">/files/xXQDPTzhvvxJpqd5yAiJ</a></td><td><a href="/pages/-M0rcb1cHJgbQLKQjGke">/pages/-M0rcb1cHJgbQLKQjGke</a></td></tr></tbody></table>


# Product updates

New exchange coverage, channels, clients and API changes

{% updates format="full" %}
{% update date="2026-08-23" tags="data-coverage" %}

## Aster market data

[Aster](https://www.asterdex.com/) is a decentralized exchange offering spot and perpetual futures markets.

Historical data for both markets is now available from `2026-08-23` UTC onward. It includes trades, order books, and tickers, plus funding, open interest, and liquidations for futures.

Replay, normalization, and real-time streaming are available in Node.js client `tardis-dev` `18.2.0` and Tardis Machine `18.2.0` or newer.

* [See Aster Spot coverage](/historical-data-details/aster).
* [See Aster Futures coverage](/historical-data-details/aster-futures).
  {% endupdate %}

{% update date="2026-08-19" tags="data-coverage" %}

## Bybit full-depth and RPI order books

From `2026-08-19`, Bybit Derivatives raw historical feeds use `orderbook.full` instead of `orderbook.1000` for full-depth order book data and also include the 50-level `orderbook.rpi` feed with separate non-RPI and RPI quantities at each level.

The `orderbook.full` WebSocket feed contains incremental updates only, so Tardis adds initial snapshots from Bybit's full order book REST API. Generated snapshots are marked with `"generated":true` and synchronized with buffered WebSocket updates using `u` and `seq`.

Normalized order book data continues to use `orderbook.50`; no Node.js client update is required.

[See Bybit Derivatives coverage](/historical-data-details/bybit).
{% endupdate %}

{% update date="2026-08-14" tags="data-coverage" %}

## Hyperliquid fast order book normalization

Hyperliquid order book normalization now uses the 5-level `fastBook` feed for real-time streaming and historical data recorded from `2026-06-17` onward. This applies to the Node.js client and the normalized `book_snapshot_5` and `book_snapshot_25` CSV datasets. From that date, both datasets are derived from snapshots currently observed around every 500ms. Earlier historical data continues to use the 20-level `l2Book` feed.

Available in Node.js client `tardis-dev` `18.1.0` or newer.

[See Hyperliquid coverage](/historical-data-details/hyperliquid).
{% endupdate %}

{% update date="2026-07-24" tags="data-coverage" %}

## Gemini WebSocket v3 market data

Gemini raw historical feeds now use Gemini WebSocket API v3 from `2026-07-24` UTC onward. Captured v3 data includes public trades on `trade`, 100ms incremental level 2 order book updates on the Tardis `depth` channel, and native top-of-book updates on `bookTicker`.

Gemini v3 raw payloads use lowercase symbols such as `btcusd`. For backward compatibility with Gemini v2, Tardis symbol IDs and normalized messages remain uppercase, while Gemini filters match symbols case-insensitively so existing filters such as `BTCUSD` continue to work. Historical data recorded before the switch remains available in the legacy v2 format.

[See Gemini coverage](/historical-data-details/gemini).
{% endupdate %}

{% update date="2026-07-10" tags="data-coverage" %}

## Kraken WebSocket v2 market data

Kraken raw historical feeds now use Kraken WebSocket API v2 from `2026-07-10` UTC onward. Captured v2 data includes public trades, 1000-level order books, BBO-triggered tickers, and instrument reference data including tokenized assets.

Kraken v2 also changes exchange-native symbol IDs for pairs containing Bitcoin or Dogecoin: v1 `XBT` and `XDG` become v2 `BTC` and `DOGE`. For example, use `XBT/USD` before the switch and `BTC/USD` from `2026-07-10` onward. This applies to every pair containing either currency.

Kraken v2 real-time streaming and data normalization require Node.js client `tardis-dev` `16.6.3` or newer, or Tardis Machine `16.6.2` or newer.

[See Kraken coverage](/historical-data-details/kraken).
{% endupdate %}

{% update date="2026-06-25" tags="data-coverage" %}

## MEXC Spot and Futures market data

High frequency historical market data is now available for MEXC Spot and MEXC Futures exchanges.

Data normalization for both exchanges is available in Node.js client `tardis-dev` and Tardis Machine `16.6.0` or newer.

* [See MEXC Spot coverage](/historical-data-details/mexc).
* [See MEXC Futures coverage](/historical-data-details/mexc-futures).
  {% endupdate %}

{% update date="2026-06-24" tags="billing" %}

## Account-level data transfer limits

Data transfer limits now apply at the account level for CSV dataset downloads and raw data replay API responses.

[See API rate limits](/api/rate-limits).
{% endupdate %}

{% update date="2026-06-23" tags="data-coverage" %}

## Bybit pre-launch derivatives data

Market data for Bybit Derivatives pre-launch instruments is now available once Bybit moves an instrument into the `ContinuousTrading` phase.

These symbols are included in Bybit Derivatives historical and real-time feeds for supported channels, including trades, order book data, tickers, liquidations, and book ticker data. The [Instruments Metadata API](/api/instruments-metadata-api) marks them with `underlyingType: pre_market`, so clients can distinguish pre-launch contracts from normal crypto-native contracts. Bybit auction-only pre-launch phases remain excluded until continuous trading starts.

[See Bybit Derivatives coverage](/historical-data-details/bybit).
{% endupdate %}

{% update date="2026-06-16" tags="data-coverage" %}

## Hyperliquid fast order book feed

Hyperliquid raw historical feeds now include the `fastBook` channel from `2026-06-17` onward. It is Hyperliquid `l2Book` with `fast: true`, exposed as a separate raw channel with 5-level order book snapshots currently observed around every 500ms.

[See Hyperliquid coverage](/historical-data-details/hyperliquid).
{% endupdate %}

{% update date="2026-06-15" tags="api" %}

## Faster exchange and instrument metadata APIs

[Exchange details](/api/http-api-reference#exchanges-exchange) and [Instruments Metadata API](/api/instruments-metadata-api) responses are now faster and more reliable for large exchanges and broad filters, including options-heavy venues and filters for futures, perpetuals, and options.

Metadata responses now return the full available instrument universe more consistently, including historical or inactive symbols that previously could be omitted on exchanges with very large symbol lists. This makes symbol discovery, availability checks, and automated instrument selection more predictable across supported exchanges.

Metadata refreshes are also more resilient to temporary upstream issues, so newly listed, delisted, and recovered symbols should appear more consistently. The `/v1/exchanges/:exchange` response no longer includes the legacy zero-valued `datasets.stats` placeholder; use `datasets.symbols` for CSV dataset availability.
{% endupdate %}

{% update date="2026-06-05" tags="data-coverage" %}

## Polymarket market data

Historical Polymarket market data is now available for CLOB order books, trades, top-of-book, market lifecycle events, and sports results.

Polymarket replay and data normalization support is available in Node.js client `tardis-dev` `16.5.0` and Tardis Machine `16.5.0`.

[See Polymarket coverage](/historical-data-details/polymarket).
{% endupdate %}

{% update date="2026-05-21" tags="data-coverage" %}

## OKX order book and Tokyo migration

[OKX Spot](/historical-data-details/okex), [Futures](/historical-data-details/okex-futures), [Swap](/historical-data-details/okex-swap), and [Options](/historical-data-details/okex-options) raw order book feeds now use the public `books` channel instead of the colocation-only `books-l2-tbt` channel from `2026-05-21` UTC onward.

The OKX recorders were moved from Hong Kong to Tokyo after OKX announced its [Hong Kong to Tokyo trading server migration](https://www.okx.com/en-eu/help/okx-trading-server-migration-announcement-hong-kong-tokyo) and updated its colocation policy to support DMM/DMT clients only. We were asked to switch from colocation domains to the public network domains `www.okx.com` and `ws.okx.com`. A migration data gap affected OKX feeds on `2026-05-21` from `00:00:00` UTC to `05:16:19` UTC.

Replaying OKX Spot, Futures, Swap, and Options order book data recorded from `2026-05-21` onward requires Node.js client `tardis-dev` `16.4.2` or newer, or Tardis Machine `16.4.2` or newer.
{% endupdate %}

{% update date="2026-05-05" tags="data-coverage" %}

## Bullish market data

Historical Bullish market data is now available, including order book updates, trades, top-of-book updates, tickers, index prices, and perpetual and options data.

Bullish data normalization is available in Node.js client `tardis-dev` `16.4.0` and Tardis Machine `16.4.1`.

[See Bullish coverage](/historical-data-details/bullish).
{% endupdate %}

{% update date="2026-05-05" tags="api" %}

## Optimized filtered raw data replay API requests

Filtered [raw data replay API](/api/http-api-reference#data-feeds-exchange) requests can now use the optional `sliceSize` parameter to fetch up to 10 consecutive minutes per request. Use it to reduce the number of API requests when replaying historical data. Omit `sliceSize` to keep the existing one-minute behavior.

Responses include `x-slice-size` with the slice size used and `x-suggested-slice-size` as a recommendation for future requests with the same filter applied. The recommendation balances fewer requests against response size.

The Node.js client `tardis-dev` `16.3.1`, Python client `tardis-dev` `4.2.0`, and Tardis Machine `16.2.1` use this automatically for filtered historical replay, so library users get fewer API requests without changing replay code.

* [HTTP API Reference](/api/http-api-reference#data-feeds-exchange)
* [Node.js replay docs](/node-client/replaying-historical-data)
* [Python replay docs](/python-client/replaying-historical-data)
  {% endupdate %}

{% update date="2026-04-28" tags="data-coverage" %}

## Bitget V3 market data

Bitget Spot and Bitget Futures raw historical feeds now use [Bitget WebSocket API V3](https://www.bitget.com/api-doc/uta/websocket/public/Order-Book-Channel). Order book collection now uses the `books` full-depth channel.

Bitget Futures also includes the V3 `liquidation` channel. Replaying or normalizing Bitget data recorded from 2026-04-28 onward requires Node.js client `tardis-dev` `16.2.1` or newer, or Tardis Machine `16.1.2` or newer, because older clients do not support the new V3 raw message formats.

* [Bitget Spot coverage](/historical-data-details/bitget)
* [Bitget Futures coverage](/historical-data-details/bitget-futures)
  {% endupdate %}

{% update date="2026-04-24" tags="clients" %}

## Find instrument symbols

You can now find exchange-specific instrument symbols from normalized market filters across multiple exchanges. Use this when you know the market you want, such as active BTC/USDT linear perpetuals, but do not want to hardcode each exchange's symbol format.

The new Node.js `findInstrumentSymbols()` helper and Python `find_instrument_symbols()` helpers use Instruments Metadata API filters and return symbols grouped by exchange.

Available in Node.js client `tardis-dev` `16.2.0` and Python client `tardis-dev` `4.1.0`.

* [Node.js client: Find Instrument Symbols](/node-client/quickstart#findinstrumentsymbols-exchanges-filter-selector)
* [Python client: Find Instrument Symbols](https://docs.tardis.dev/pages/6bEFe9Ft9ydP9Y6G2duh#find_instrument_symbols-...-and-find_instrument_symbols_async)
* [Instruments Metadata API](/api/instruments-metadata-api#client-helpers-for-symbol-discovery)
  {% endupdate %}

{% update date="2026-04-24" tags="api" %}

## Instruments metadata min notional and underlying type

Instruments metadata now includes `minNotional` when an exchange exposes a minimum order value or notional separately from minimum order quantity.

It also includes `underlyingType` for non-option instruments, using `native` for crypto-native instruments and exchange-sourced classifications such as `equity`, `commodity`, `fx`, `index`, `fixed_income`, or `pre_market` when available. The instruments filter endpoint accepts `underlyingType`, so you can query categories such as commodity perpetuals on supported exchanges.

[See Instruments Metadata API](/api/instruments-metadata-api).
{% endupdate %}

{% update date="2026-04-23" tags="data-coverage" %}

## Lighter market data

Historical Lighter market data is now available, including order book updates, trades, tickers, and perpetual and spot market stats.

Data normalization for Lighter is available in Node.js client `tardis-dev` `16.1.1` and Tardis Machine `16.1.0`.

[See Lighter coverage](/historical-data-details/lighter).
{% endupdate %}

{% update date="2026-04-23" tags="data-coverage" %}

## Binance index constituents

You can now replay historical Binance USDS-M Futures index price constituents through the generated `indexConstituents` channel.

Binance's REST endpoint exposes the current index constituents. We record those payloads into the minute-by-minute historical feed, so you can inspect how each index's constituent exchanges, symbols, prices and weights changed over time.

[See Binance USDS-M Futures coverage](/historical-data-details/binance-futures).
{% endupdate %}

{% update date="2026-04-11" tags="data-coverage" %}

## Binance premium index data

You can now replay Binance USDS-M Futures premium index snapshots through the generated `premiumIndex` channel.

This adds access to Binance's REST premium index payloads in the same minute-by-minute historical feed format as our other channels, including `interestRate`, which is not available in the WebSocket `markPrice` stream.

[See Binance USDS-M Futures coverage](/historical-data-details/binance-futures).
{% endupdate %}

{% update date="2026-04-11" tags="clients" %}

## zstd historical replay

Historical replay in the Node.js and Python clients now prefers `zstd` for data feed responses and local cache files.

The result is smaller replay payloads by default, while keeping `gzip` available when you need gzip-compressed slices.
{% endupdate %}

{% update date="2026-03-27" tags="clients" %}

## Unified Python client v3

The Python client is now a unified `tardis-dev` client for historical replay, CSV dataset downloads, cache management and exchange metadata.

It exposes a simpler top-level API for the most common workflows:

* `replay()` for historical market data replay
* `download_datasets()` for CSV dataset downloads
* `clear_cache()` for local cache cleanup
* `get_exchange_details()` for exchange metadata

`replay()` also accepts Python `datetime` values for `from_date` and `to_date`. Naive datetimes are treated as UTC.

[Python client quickstart](/python-client/quickstart) · [Migration notice](/python-client/migration-notice)
{% endupdate %}

{% update date="2026-03-27" tags="clients" %}

## ESM Node.js client

The Node.js client is now ESM-only, with simplified package exports and examples that use native ES module syntax.

[Node.js client quickstart](/node-client/quickstart)
{% endupdate %}

{% update date="2026-03-25" tags="clients" %}

## Tardis Machine Docker images

Tardis Machine Docker images are now published for both x64 and ARM64 architectures, making local replay and streaming easier to run on Apple Silicon machines, ARM servers and standard x64 environments.

[Tardis Machine quickstart](/tardis-machine/quickstart)
{% endupdate %}

{% update date="2026-03-25" tags="clients" %}

## Binance Futures WebSocket endpoints

Our backend services, Tardis Machine, and the Node.js client now handle Binance Futures' split public WebSocket endpoints, keeping real-time streaming aligned with Binance's exchange-side API changes.

This shipped in `tardis-dev` `14.3.0` and `tardis-machine` `14.3.0`.

[See Binance's Important WebSocket Change Notice](https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Important-WebSocket-Change-Notice).
{% endupdate %}

{% update date="2026-03-25" tags="clients" %}

## Gate.io Futures decimal sizes

Tardis Machine and the Node.js client now handle Gate.io Futures decimal-size metadata via `X-Gate-Size-Decimal`, so normalized sizes stay correct for affected contracts.
{% endupdate %}

{% update date="2026-03-17" tags="data-coverage" %}

## Binance funding info

Generated `fundingInfo` channels are now available for Binance USDS-M Futures and Binance COIN Futures.

These channels expose Binance funding cap, floor and interval updates in the historical data feed when Binance publishes adjusted funding information.

[Binance USDS-M Futures](/historical-data-details/binance-futures) · [Binance COIN Futures](/historical-data-details/binance-delivery)
{% endupdate %}

{% update date="2026-03-17" tags="data-coverage" %}

## Binance insurance balance

The generated `insuranceBalance` channel is now available for Binance USDS-M Futures, with snapshots from Binance's insurance fund balance endpoint.
{% endupdate %}
{% endupdates %}


# Market Data Primer

Start here if you are new to crypto exchange market data

Crypto market data is the public record of what exchange APIs publish while orders are submitted, matched, canceled, or amended. This primer gives you the mental model first: what public feeds contain, how orders meet in a matching engine, how trades and book changes are created, and how those events become data you can replay and analyze.

## What exchange APIs publish

For real-time data, centralized crypto exchange APIs publish public market data over WebSocket as JSON messages. A client keeps the connection open, subscribes to a market and data type, and receives messages as the exchange publishes them. Exchange documentation uses names such as channels, streams, topics, or tables for those subscriptions.

![](/files/TSRAcTxDiRjP1IKwJQVQ)

## Where market data comes from

On a centralized exchange, once an order reaches the matching engine, the engine compares it with open orders in that market's limit order book. This primer starts there because public market data is published from the trades and book changes that matching creates.

Inside the book, the core rule is price-time priority: better prices match first; at the same price, older orders have priority. The matching process creates trades and book changes, which public market data feeds then publish.

![](/files/opOU8XqyLTbTrVjVxhEQ)

At a high level:

1. A participant submits a limit order, market order, cancel, or amendment.
2. The matching engine either changes the book or matches the order against open orders.
3. A match creates a trade.
4. The exchange publishes order book updates when book liquidity changes.
5. The exchange publishes trades and related market events when they happen.

## Orders and the Level 2 book

An order book is the exchange's list of open buy and sell limit orders for one market.

In an L2 book, each row is a price level. A level has three pieces: side, price, and size. If several orders sit at the same side and price, the exchange aggregates them into one level. L2 shows total size at each price, not every individual order.

![](/files/sZ5U2HDDu8RgdAGJWGeS)

| Term      | Meaning                                                      |
| --------- | ------------------------------------------------------------ |
| ask level | A price and the total size sellers offer at that price       |
| bid level | A price and the total size buyers bid at that price          |
| best ask  | The lowest ask level; the lowest price to buy immediately    |
| best bid  | The highest bid level; the highest price to sell immediately |
| spread    | The price gap between the best bid and best ask              |

Book depth describes how much detail a feed exposes:

| Depth                | What it shows                                                  |
| -------------------- | -------------------------------------------------------------- |
| L1 / top of book     | Best bid and best ask, with sizes when the feed provides them  |
| L2 / market by price | Aggregated size at each price level                            |
| L3 / market by order | Individual order-level events, when the exchange provides them |

{% hint style="info" %}
For Tardis-specific order book depth, L2/L3 coverage, snapshots, and reconstruction details, see the [Order Books FAQ](/faq/order-books).
{% endhint %}

## Book snapshots and updates

Most exchange APIs send an initial order book snapshot over the WebSocket feed, then publish updates as the book changes. The model is simple: snapshot first, then changes.

![](/files/D4eNYLcUox3nUKsp2uJ8)

A **snapshot** is the book state at one point in time. An **update** is a message with the price levels that changed since the previous book state. One update message can contain several changes, including ask and bid changes.

To follow the current book:

1. Start from a snapshot.
2. Apply the next update.
3. Read the new book.
4. Continue with the next update.

In this L2 model, an update gives the new size for each changed price level. If an update reports the ask at `10100.00` as `2.40 BTC`, the current size at that level becomes `2.40 BTC`. A size of `0` removes the level.

{% hint style="info" %}
Tardis CSV datasets include [incremental L2 book updates](/downloadable-csv-files/data-types#incremental_book_l2) and reconstructed order book snapshots for the [top 25](/downloadable-csv-files/data-types#book_snapshot_25) and [top 5](/downloadable-csv-files/data-types#book_snapshot_5) levels.
{% endhint %}

## Orders and trades

A **limit order** sets an amount and a limit price: buy or sell up to this amount, but only at this price or better. Any unfilled amount becomes an open order in the limit order book.

A **market order** requests an immediate buy or sell against available liquidity. It does not set a limit price; it takes from the book until it is filled or there is not enough liquidity left.

A **trade** happens when an incoming order matches an order already in the book. In the example below, the book has a limit sell order at `100103.00`. A market buy arrives for `0.30 BTC`, so the exchange publishes a trade at `100103.00` for `0.30 BTC`.

![](/files/WIue7y8voBKYsRE4rdPd)

Maker and taker describe the two roles in that match:

* The **maker** order was already in the book and provided liquidity.
* The **taker** order arrived and removed liquidity by matching against it.

{% hint style="info" %}
In Tardis normalized [`trade`](/node-client/normalization#normalizetrades) messages, `side` is the liquidity taker side: `buy` means the taker bought from asks, and `sell` means the taker sold into bids.

Raw exchange feeds are venue-specific, so use the exchange's trade-side fields before mapping them.
{% endhint %}

## Timestamps and message order

When working with market data, separate two time references:

* **Exchange timestamp**: a time field supplied by the exchange. Most messages expose one; some expose several, such as event time and publish time. These are both exchange timestamps, but they are not interchangeable: event time describes when the trade or book change happened; publish time describes when the exchange emitted the message.
* **Arrival timestamp**: when the message reached the recorder or data collector. In Tardis data this is `localTimestamp`.

![](/files/ro3t3tFud9mdYCEXpBNN)

Use the exchange timestamp when you care about the time assigned by the exchange. Use the arrival timestamp when you care about collection order or when the message reached the recorder.

{% hint style="info" %}
The [Data FAQ](/faq/data#how-are-market-data-messages-timestamped) covers timestamp semantics, same-timestamp ordering, and cross-channel synchronization in more detail.
{% endhint %}

## High-frequency and low-frequency data

Frequency describes how much detail a feed preserves, not only how many messages arrive per second.

**High-frequency data** preserves individual exchange events and book changes. It includes trades, L2 book updates, best bid/ask updates, liquidations, and other event feeds when the exchange publishes them.

**Low-frequency data** is aggregated or sampled. It includes candles, periodic book snapshots, and other summaries where exact event sequence is not preserved.

![](/files/l1QnWterbxukoh0L5QL7)

Use high-frequency data when the event sequence matters: reconstructing books, replaying market conditions, simulating execution, or debugging feed behavior.

Use low-frequency data when a summary is enough: charting a price series, comparing volume over longer intervals, or inspecting sampled liquidity. A one-minute candle can tell you the open, high, low, close, and volume for that minute. It cannot tell you the order of trades and book changes inside the minute.

{% hint style="info" %}
Tardis.dev focuses on high-frequency, tick-level market data. Low-frequency views such as candles or sampled book snapshots are derived from tick-level data when needed.
{% endhint %}

## Spot markets

Spot markets trade the asset itself against another asset.

![](/files/S8eDi2j4ZOpBSBb0xzUp)

In `BTC/USDT` spot, BTC is the base asset and USDT is the quote asset. The price is quoted in the quote asset per one unit of the base asset. A price of `100000` means `1 BTC = 100000 USDT`.

A trade for `0.10 BTC` at that price has `10000 USDT` notional. Notional is the quote-asset value of a trade or position.

## Derivative markets

Derivatives do not trade the asset itself. They trade contracts whose value references an underlying asset, index, or market.

Symbol formats are exchange-specific. Many derivative symbols encode product details such as the underlying market, expiry, strike, or contract type.

![](/files/nzmncd3qXPBWBvUnbbQA)

A dated future is a contract with a fixed expiry or settlement date. Traders can open and close positions before expiry; positions open at expiry are settled by the exchange's settlement rules.

A perpetual swap is futures-like, but it has no expiry. Because it does not naturally converge to a settlement date, crypto perpetuals use funding payments between long and short positions to keep the contract price close to a reference market.

An option gives the holder the right, but not the obligation, to buy or sell the underlying at a strike price. It has an expiry and an option type such as call or put.

Derivative-specific market data includes:

| Term                          | Meaning                                                                              |
| ----------------------------- | ------------------------------------------------------------------------------------ |
| funding                       | Periodic payments between long and short perpetual positions                         |
| open interest                 | Total outstanding derivative exposure; the unit is exchange-specific                 |
| liquidation                   | Forced position close events when an account no longer satisfies margin requirements |
| mark price                    | Exchange reference price used for margin, PnL, and liquidation logic                 |
| implied volatility and greeks | Option risk measures published by options markets                                    |

## Derivative contract units

Do not assume every `amount`, `size`, `qty`, or `volume` field means the same unit. In derivative feeds, size is defined by the contract specification. Depending on the venue, it counts contracts, base asset, quote value, notional value, or another exchange-defined unit.

A contract multiplier defines what one contract represents. The contract model defines how price changes turn into PnL and which currency the PnL settles in.

![](/files/tYFb5IOYfaWRSgokCX7I)

Common contract models:

* **Linear**: exposure moves directly with the quoted price, and PnL settles in the quote or margin currency. For a BTCUSDT linear perpetual, a `0.10 BTC` position at `100000 USDT` has `10000 USDT` notional.
* **Inverse**: the contract is quoted in a fiat or stablecoin price, but PnL settles in the underlying asset. For a BTCUSD inverse contract, size is expressed as USD value while profit and loss are paid in BTC.
* **Quanto**: the underlying market, quote currency, and settlement currency are not the same. The exchange multiplier converts price movement into the settlement currency.

{% hint style="info" %}
Use [instrument metadata](/api/instruments-metadata-api) and the exchange contract specification before comparing derivative sizes across venues.
{% endhint %}

## Raw or normalized data

Market data services expose exchange data in two broad formats.

**Exchange-native raw data** keeps the exchange's own message shape, field names, channels, and product-specific details. It is closest to what a live WebSocket client would have received from the exchange API.

**Normalized data** maps common market data events into a shared schema. It is easier to compare across exchanges, but it necessarily hides or renames some exchange-specific fields.

Compare the same BitMEX trade in exchange-native and normalized form:

{% tabs %}
{% tab title="exchange-native" %}

```json
{
  "table": "trade",
  "action": "insert",
  "data": [
    {
      "timestamp": "2019-06-01T00:03:11.589Z",
      "symbol": "ETHUSD",
      "side": "Sell",
      "size": 10,
      "price": 268.7,
      "trdMatchID": "ebc230d9-0b6e-2d5d-f99a-f90109a2b113"
    }
  ]
}
```

{% endtab %}

{% tab title="normalized" %}

```json
{
  "type": "trade",
  "exchange": "bitmex",
  "symbol": "ETHUSD",
  "id": "ebc230d9-0b6e-2d5d-f99a-f90109a2b113",
  "side": "sell",
  "amount": 10,
  "price": 268.7,
  "timestamp": "2019-06-01T00:03:11.589Z",
  "localTimestamp": "2019-06-01T00:03:11.650Z"
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Tardis.dev gives customers access to both exchange-native and normalized data. We record exchange-native source feeds and provide them through raw historical APIs, and we also export normalized CSV datasets and client-library objects built from that source.
{% endhint %}

## Where to go next

Use this primer as the mental model, then choose the reference that matches the next job:

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Data FAQ</strong></td><td>Data sources, timestamps, raw vs normalized data, ordering, and market data coverage.</td><td><a href="/pages/-M0rclc1xUdR6sC0aJL8">/pages/-M0rclc1xUdR6sC0aJL8</a></td></tr><tr><td><strong>API Quickstart</strong></td><td>Start replaying historical market data through the API and official client libraries.</td><td><a href="/pages/FWgFjdwVNpNU4HhTHdVd">/pages/FWgFjdwVNpNU4HhTHdVd</a></td></tr><tr><td><strong>CSV downloads quickstart</strong></td><td>Download normalized CSV datasets for trades, books, quotes, derivatives, liquidations, and options.</td><td><a href="/pages/bFGMWgAgbTAuGtejNMzO">/pages/bFGMWgAgbTAuGtejNMzO</a></td></tr></tbody></table>


# General

Common questions about exchanges, API access and infrastructure

<details>

<summary><strong>What is Tardis.dev and what is your unique value proposition?</strong></summary>

Tardis.dev provides tick-level historical and real-time cryptocurrency market data from 50+ exchanges and offers:

* access to [high frequency historical data](/faq/data#what-does-high-frequency-historical-data-mean), including tick-level order book updates and trades for [derivatives and top spot cryptocurrency exchanges](#which-exchanges-instruments-and-currency-pairs-are-supported)
* [non-standard data types](/faq/data#what-data-types-do-you-support): historical funding, open interest, indexes, liquidations and more
* access via [API](/api/quickstart) and [downloadable CSV files](/downloadable-csv-files/overview)
* data [sourced from real-time WebSocket market data feeds](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints), with documented [collection details](/historical-data-details/overview#market-data-collection-overview)
* [exchange-native](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) and [normalized data format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) support
* [time-machine market replay](#how-does-time-machine-market-replay-work) for reconstructing order book state at historical points in time
* [always available market data backup](#what-is-your-infrastructure-setup)
* [subscription plans](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types) for solo traders, small prop shops, businesses and academic researchers
* [consolidated real-time market data streaming](#do-you-support-consolidated-real-time-market-data-streaming) support via Tardis.dev open source libraries that connect directly to exchanges' public WebSocket APIs (no API key required)
* [professional support](#what-does-professional-support-mean)

**Data use cases**

* market microstructure and order book dynamics research
* trading execution optimization
* tick-level granularity market simulation
* liquidity and lead-lag analysis
* backtesting and optimization of trading strategies
* full historical order book reconstruction at any given point in time
* training machine learning models
* alpha generation
* designing quantitative models
* academic research
* data visualizations

</details>

<details>

<summary><strong>Which exchanges, instruments and currency pairs are supported?</strong></summary>

Over 50 000 distinct instruments & currency pairs across leading derivatives and spot cryptocurrency exchanges are supported. We collect and provide data for all instruments & currency pairs available on a given exchange, with some exceptions for spot exchanges where we collect high-cap currency pairs only (due to exchange API limitations).

{% hint style="info" %}
See [historical data details](/historical-data-details/overview#per-exchange-historical-data-details) for each supported exchange.
{% endhint %}

* Binance
  * [Binance USDS-M Futures](/historical-data-details/binance-futures)
  * [Binance COIN Futures](/historical-data-details/binance-delivery)
  * [Binance European Options](/historical-data-details/binance-european-options)
  * [Binance Spot](/historical-data-details/binance)
  * [Binance US](/historical-data-details/binance-us)
* OKX
  * [OKX Futures](/historical-data-details/okex-futures)
  * [OKX Swap](/historical-data-details/okex-swap)
  * [OKX Options](/historical-data-details/okex-options)
  * [OKX Spot](/historical-data-details/okex)
  * [OKX Nitro Spreads](/historical-data-details/okex-spreads)
* Coinbase
  * [Coinbase Exchange](/historical-data-details/coinbase)
  * [Coinbase International](/historical-data-details/coinbase-international)
* [BitMEX](/historical-data-details/bitmex)
* [Deribit](/historical-data-details/deribit)
* Bybit
  * [Bybit Derivatives](/historical-data-details/bybit)
  * [Bybit Spot](/historical-data-details/bybit-spot)
  * [Bybit Options](/historical-data-details/bybit-options)
* [Kraken Futures](/historical-data-details/cryptofacilities)
* [Kraken](/historical-data-details/kraken)
* Bitfinex
  * [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives)
  * [Bitfinex](/historical-data-details/bitfinex)
* KuCoin
  * [KuCoin Futures](/historical-data-details/kucoin-futures)
  * [KuCoin Spot](/historical-data-details/kucoin)
* [Aster Futures](/historical-data-details/aster-futures)
* [Aster Spot](/historical-data-details/aster)
* [MEXC Spot](/historical-data-details/mexc)
* [MEXC Futures](/historical-data-details/mexc-futures)
* [Crypto.com](/historical-data-details/crypto-com)
* [Bitstamp](/historical-data-details/bitstamp)
* Bitget
  * [Bitget Futures](/historical-data-details/bitget-futures)
  * [Bitget Spot](/historical-data-details/bitget)
* Gate.io
  * [Gate.io Futures](/historical-data-details/gate-io-futures)
  * [Gate.io](/historical-data-details/gate-io)
* HTX
  * [HTX Coin-M Futures](/historical-data-details/huobi-dm)
  * [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap)
  * [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap)
  * [HTX Spot](/historical-data-details/huobi)
* [Gemini](/historical-data-details/gemini)
* [WOO X](/historical-data-details/woo-x)
* [Upbit](/historical-data-details/upbit)
* [Phemex](/historical-data-details/phemex)
* [Delta Exchange](/historical-data-details/delta)
* [Blockchain.com](/historical-data-details/blockchain-com)
* [Bitnomial](/historical-data-details/bitnomial)
* [bitFlyer](/historical-data-details/bitflyer)
* [HitBTC](/historical-data-details/hitbtc)
* [Poloniex](/historical-data-details/poloniex)
* [Hyperliquid](/historical-data-details/hyperliquid)
* [Lighter](/historical-data-details/lighter)
* [Polymarket](/historical-data-details/polymarket)
* [Bullish](/historical-data-details/bullish)
* [dYdX v4](/historical-data-details/dydx-v4)
* Delisted exchanges
  * [FTX](/historical-data-details/ftx)
  * [FTX US](/historical-data-details/ftx-us)
  * [OKCoin](/historical-data-details/okcoin)
  * [AscendEX (BitMax)](/historical-data-details/ascendex)
  * [CoinFLEX](/historical-data-details/coinflex)
  * [Binance Jersey](/historical-data-details/binance-jersey)
  * [Binance DEX](/historical-data-details/binance-dex)
  * [HTX Options](/historical-data-details/huobi-dm-options)
  * [dYdX](/historical-data-details/dydx)
  * [Serum DEX](/historical-data-details/serum)
  * [Mango Markets DEX](/historical-data-details/mango)
  * [Star Atlas DEX](/historical-data-details/star-atlas)

</details>

<details>

<summary><strong>Do you provide discounts?</strong></summary>

No. We do not provide discounts, but we offer [different subscription types](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types) for solo traders, academic users, professionals and businesses.

</details>

<details>

<summary><strong>What does professional support mean?</strong></summary>

Support is handled by people who work with market data collection, exchange APIs, client integrations and data analysis.

For [Business subscriptions](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types), we target an initial priority email response within 8-12 business hours.

For [Professional subscriptions](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types), we target an initial email response within 24-48 business hours.

[Academic and Solo subscriptions](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types) are self-service and do not include dedicated support.

</details>

<details>

<summary><strong>Why would I use your services if I can collect data by myself?</strong></summary>

You can collect exchange market data directly, but doing it reliably is time-consuming and resource-intensive. It requires collection infrastructure, storage, distribution, monitoring, exchange API maintenance, new exchange integrations, and ongoing handling of connection drops, rate limits, latency spikes, and upstream API changes. Supported exchanges publish around 1 TB of new data per day.

We maintain that infrastructure so you can focus on trading and research instead of building an in-house data collection and distribution system. See our [data types](/faq/data#what-data-types-do-you-support), [data sourcing approach](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints), and [subscription types](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types) for details.

</details>

<details>

<summary><strong>How can I download the data?</strong></summary>

You can access historical market data via [API](/api/quickstart) which provides raw data in [exchange native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) or download [CSV datasets](/downloadable-csv-files/overview) with [trades](/downloadable-csv-files/data-types#trades), [incremental order book L2 updates](/downloadable-csv-files/data-types#incremental_book_l2), order book snapshots ([top 25](/downloadable-csv-files/data-types#book_snapshot_25) and [top 5](/downloadable-csv-files/data-types#book_snapshot_5)), [options chains](/downloadable-csv-files/data-types#options_chain), [quotes](/downloadable-csv-files/data-types#quotes), [book tickers](/downloadable-csv-files/data-types#book_ticker), [derivative tickers](/downloadable-csv-files/data-types#derivative_ticker) (open interest, funding, mark price, index price) and [liquidations](/downloadable-csv-files/data-types#liquidations).

[Our client libs](/api/quickstart) provide data in [normalized format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) as well, which can be more flexible than CSV datasets for some use cases but also slower to download due to on-demand, client-side data normalization overhead in comparison to ready to download CSV files.

{% hint style="info" %}
**Replay API** supports custom time windows with minute precision (e.g., `2024-01-15T09:30:00.000Z` to `2024-01-15T16:00:00.000Z`). **CSV datasets** are available as daily files.
{% endhint %}

</details>

<details>

<summary><strong>What can affect CSV dataset download speed?</strong></summary>

CSV dataset download speed depends mainly on the network path between your location and our primary cloud storage in the US East region. Longer cross-continent routes, local network conditions and temporary public Internet congestion can affect throughput.

Very rarely, a cloud storage service may be temporarily slower or unavailable. We recommend using the latest [official Python or Node.js clients](/downloadable-csv-files/overview#download-via-client-libraries). They download multiple files concurrently and automatically retry transient network or storage errors.

</details>

<details>

<summary><strong>How far back is historical data available?</strong></summary>

Data is available since **2019-03-30** for majority of the supported exchanges (that existed at that time).

| **exchange**                                                                  | **available since** | **available until** |
| ----------------------------------------------------------------------------- | ------------------- | ------------------- |
| [Binance USDS-M Futures](/historical-data-details/binance-futures)            | 2019-11-17          |                     |
| [Binance COIN Futures](/historical-data-details/binance-delivery)             | 2020-06-16          |                     |
| [Binance European Options](/historical-data-details/binance-european-options) | 2023-06-15          |                     |
| [Binance Spot](/historical-data-details/binance)                              | 2019-03-30          |                     |
| [Binance US](/historical-data-details/binance-us)                             | 2019-09-25          |                     |
| [OKX Futures](/historical-data-details/okex-futures)                          | 2019-03-30          |                     |
| [OKX Swap](/historical-data-details/okex-swap)                                | 2019-03-30          |                     |
| [OKX Options](/historical-data-details/okex-options)                          | 2020-02-01          |                     |
| [OKX Spot](/historical-data-details/okex)                                     | 2019-03-30          |                     |
| [OKX Nitro Spreads](/historical-data-details/okex-spreads)                    | 2023-12-22          |                     |
| [Coinbase Exchange](/historical-data-details/coinbase)                        | 2019-03-30          |                     |
| [Coinbase International](/historical-data-details/coinbase-international)     | 2024-10-31          |                     |
| [BitMEX](/historical-data-details/bitmex)                                     | 2019-03-30          |                     |
| [Deribit](/historical-data-details/deribit)                                   | 2019-03-30          |                     |
| [Bybit Derivatives](/historical-data-details/bybit)                           | 2019-11-07          |                     |
| [Bybit Spot](/historical-data-details/bybit-spot)                             | 2021-12-04          |                     |
| [Bybit Options](/historical-data-details/bybit-options)                       | 2023-04-05          |                     |
| [Kraken Futures](/historical-data-details/cryptofacilities)                   | 2019-03-30          |                     |
| [Kraken](/historical-data-details/kraken)                                     | 2019-06-04          |                     |
| [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives)         | 2019-09-14          |                     |
| [Bitfinex](/historical-data-details/bitfinex)                                 | 2019-05-23          |                     |
| [KuCoin Futures](/historical-data-details/kucoin-futures)                     | 2024-01-25          |                     |
| [KuCoin Spot](/historical-data-details/kucoin)                                | 2022-08-16          |                     |
| [Aster Futures](/historical-data-details/aster-futures)                       | 2026-08-23          |                     |
| [Aster Spot](/historical-data-details/aster)                                  | 2026-08-23          |                     |
| [MEXC Spot](/historical-data-details/mexc)                                    | 2026-06-25          |                     |
| [MEXC Futures](/historical-data-details/mexc-futures)                         | 2026-06-25          |                     |
| [Crypto.com](/historical-data-details/crypto-com)                             | 2022-06-01          |                     |
| [Bitstamp](/historical-data-details/bitstamp)                                 | 2019-03-30          |                     |
| [Bitget Futures](/historical-data-details/bitget-futures)                     | 2024-11-08          |                     |
| [Bitget Spot](/historical-data-details/bitget)                                | 2024-11-08          |                     |
| [Gate.io Futures](/historical-data-details/gate-io-futures)                   | 2020-07-01          |                     |
| [Gate.io](/historical-data-details/gate-io)                                   | 2020-07-01          |                     |
| [HTX Coin-M Futures](/historical-data-details/huobi-dm)                       | 2019-11-19          |                     |
| [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap)                | 2020-03-28          |                     |
| [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap)         | 2020-10-30          |                     |
| [HTX Spot](/historical-data-details/huobi)                                    | 2019-11-19          |                     |
| [Gemini](/historical-data-details/gemini)                                     | 2019-08-30          |                     |
| [WOO X](/historical-data-details/woo-x)                                       | 2023-01-20          |                     |
| [Upbit](/historical-data-details/upbit)                                       | 2021-03-03          |                     |
| [Phemex](/historical-data-details/phemex)                                     | 2020-03-17          |                     |
| [Delta Exchange](/historical-data-details/delta)                              | 2020-03-30          |                     |
| [Blockchain.com](/historical-data-details/blockchain-com)                     | 2023-02-23          |                     |
| [Bitnomial](/historical-data-details/bitnomial)                               | 2023-01-13          |                     |
| [bitFlyer](/historical-data-details/bitflyer)                                 | 2019-08-30          |                     |
| [HitBTC](/historical-data-details/hitbtc)                                     | 2019-11-19          |                     |
| [Poloniex](/historical-data-details/poloniex)                                 | 2020-07-01          |                     |
| [Hyperliquid](/historical-data-details/hyperliquid)                           | 2024-10-29          |                     |
| [Lighter](/historical-data-details/lighter)                                   | 2026-04-17          |                     |
| [Polymarket](/historical-data-details/polymarket)                             | 2026-05-25          |                     |
| [Bullish](/historical-data-details/bullish)                                   | 2026-04-29          |                     |
| [dYdX v4](/historical-data-details/dydx-v4)                                   | 2024-08-23          |                     |
| [FTX](/historical-data-details/ftx)                                           | 2019-08-01          | 2022-11-13          |
| [FTX US](/historical-data-details/ftx-us)                                     | 2020-05-22          | 2022-11-13          |
| [OKCoin](/historical-data-details/okcoin)                                     | 2019-11-19          | 2025-10-01          |
| [AscendEX (BitMax)](/historical-data-details/ascendex)                        | 2021-03-28          | 2026-07-07          |
| [CoinFLEX](/historical-data-details/coinflex)                                 | 2020-07-14          | 2023-04-07          |
| [Binance Jersey](/historical-data-details/binance-jersey)                     | 2019-10-30          | 2020-11-10          |
| [Binance DEX](/historical-data-details/binance-dex)                           | 2019-06-04          | 2022-10-04          |
| [HTX Options](/historical-data-details/huobi-dm-options)                      | 2021-02-01          | 2021-06-26          |
| [dYdX](/historical-data-details/dydx)                                         | 2021-04-06          | 2024-10-30          |
| [Serum DEX](/historical-data-details/serum)                                   | 2021-06-23          | 2022-11-13          |
| [Mango Markets DEX](/historical-data-details/mango)                           | 2022-01-19          | 2022-10-14          |
| [Star Atlas DEX](/historical-data-details/star-atlas)                         | 2021-10-09          | 2022-09-05          |

</details>

<details>

<summary><strong>Do you provide historical market data in CSV flat files?</strong></summary>

Yes, see [downloadable CSV files documentation](/downloadable-csv-files/overview) for more details.

</details>

<details>

<summary><strong>What programming languages are supported?</strong></summary>

Any programming language that can communicate using HTTPS can communicate with our [HTTP API](/api/http-api-reference).

We provide official [Python](/python-client/quickstart) and [Node.js](/node-client/quickstart) clients for accessing tick-level historical market data.

Finally, our open source, locally runnable [tardis-machine](/tardis-machine/quickstart) server with built-in local data caching provides market data normalization, custom order book snapshot capabilities, and real-time market data streaming support that connects directly to exchanges' WebSocket APIs. It provides both streaming HTTP and WebSocket endpoints returning market data for whole time periods (in contrast to Tardis.dev [HTTP API](/api/http-api-reference), where a single call returns data for a single minute time period) and is available via npm and as a Docker image.

</details>

<details>

<summary><strong>What API protocols can be used to access market data?</strong></summary>

Historical market data provided by [HTTP API](/api/http-api-reference) can be accessed via HTTPS.

Locally runnable [tardis-machine](/tardis-machine/quickstart) server provides both HTTP and WebSocket based APIs for accessing both historical and real-time market data.

</details>

<details>

<summary><strong>How does time-machine market replay work?</strong></summary>

Exchange WebSocket APIs are built for real-time feeds, not historical replay. Locally runnable [Tardis Machine](/tardis-machine/replaying-historical-data#websocket-ws-replay-exchange-exchange-and-from-fromdate-and-to-todate) bridges that gap by replaying historical exchange-native data through a WebSocket API with the same subscribe-style flow as exchange real-time APIs. In many cases, an existing exchange WebSocket client can replay a historical date range by changing the endpoint URL.

</details>

<details>

<summary><strong>Do you support consolidated real-time market data streaming?</strong></summary>

We do not provide a hosted real-time market data API. Exchanges already provide public real-time WebSocket feeds directly, and a hosted Tardis.dev real-time API would add latency and another dependency.

Use the [open source clients and locally runnable Tardis Machine](/api/quickstart) for consolidated real-time streaming. They are self-hosted, free to use, and connect directly to exchange WebSocket APIs without a Tardis.dev API key.

</details>

<details>

<summary><strong>Are there any rate-limits for the API?</strong></summary>

Yes. See [API Rate Limits](/api/rate-limits) for account-level API request and data transfer limits.

</details>

<details>

<summary><strong>How do I obtain my API key?</strong></summary>

An API key can be obtained on [Tardis.dev](https://tardis.dev/) website via [order form](https://tardis.dev/#order). You'll receive it via email after a successful order.

</details>

<details>

<summary><strong>How can I rotate or reset my API key?</strong></summary>

[Contact us](https://tardis.dev/#contact) to rotate or reset your API key. If your key was compromised, let us know so we can replace it as soon as possible.

</details>

<details>

<summary><strong>What is your infrastructure setup?</strong></summary>

#### Market data collection

Highly available [Google Cloud Platform Kubernetes Clusters](https://cloud.google.com/kubernetes-engine/) located in London, UK (europe-west2 region) and Tokyo, Japan (asia-northeast1 region)

#### Market data storage

Two independent, geo-redundant, highly durable storage services

#### Market data distribution

High performance API servers deployed across network of data centers around the globe

</details>

<details>

<summary><strong>What is premium connectivity?</strong></summary>

For Pro and Business subscriptions, we provide premium connectivity powered by [Cloudflare Argo Smart Routing](https://www.cloudflare.com/application-services/products/argo-smart-routing/). Argo Smart Routing optimizes the network path for API requests by routing traffic through Cloudflare's private network backbone instead of the congested public internet.

Argo routes API traffic through Cloudflare's private backbone instead of the public internet, which reduces latency, improves reliability through automatic failover around congestion and outages, and gives more predictable response times regardless of your location.

</details>

<details>

<summary><strong>Do you provide an SLA?</strong></summary>

We do not have a formal SLA in place yet, but all infrastructure is set up to provide the highest availability possible on both data collection and distribution sides with a geo-redundant setup. Both data collection services and public APIs are constantly monitored from multiple locations and our team is immediately notified in case of any issue. We don't perform maintenance that would affect API availability, but in very rare circumstances, if that happens, we'll communicate it in advance. If a formal SLA is something your business requires, [contact us](https://tardis.dev/#contact).

</details>


# Data

Common questions about data types, formats and collection

<details>

<summary><strong>What data types do you support?</strong></summary>

We provide historical market data [sourced from real-time WebSocket APIs](#why-data-source-matters-websocket-feeds-vs-rest-endpoints). Data is available in exchange-native format via the [raw data replay API](/api/http-api-reference#data-feeds-exchange), in normalized CSV datasets, and in normalized format via the [client libraries](/api/quickstart).

The following normalized **tick-level** data types are available via [downloadable CSV data files](/downloadable-csv-files/overview):

* [trades](/downloadable-csv-files/data-types#trades)
* [incremental order book L2 updates](/downloadable-csv-files/data-types#incremental_book_l2)
* order book snapshots ([top 25](/downloadable-csv-files/data-types#book_snapshot_25) and [top 5](/downloadable-csv-files/data-types#book_snapshot_5) levels)
* [options\_chain](/downloadable-csv-files/data-types#options_chain)
* [quotes](/downloadable-csv-files/data-types#quotes)
* [book\_ticker](/downloadable-csv-files/data-types#book_ticker) (best bid/ask from native exchange BBO feeds)
* [derivative tick info](/downloadable-csv-files/data-types#derivative_ticker) (open interest, funding rate, mark price, index price)
* [liquidations](/downloadable-csv-files/data-types#liquidations)

The [raw data replay API](/api/http-api-reference#data-feeds-exchange), available for [Pro and Business subscriptions](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types), provides [exchange-native data](#what-is-a-difference-between-exchange-native-and-normalized-data-format). See [historical data details](/historical-data-details/overview) for captured channels, symbols, and date ranges for each exchange. Captured channels correspond to exchange-specific data feeds, for example [Binance `bookTicker`](/historical-data-details/binance#captured-real-time-channels) or [BitMEX liquidation](/historical-data-details/bitmex#captured-real-time-channels) channels.

The following [normalized data types](#what-is-a-difference-between-exchange-native-and-normalized-data-format) are also available via the [client libraries](/api/quickstart). Normalization runs client-side using raw data replay as the data source:

* trades
* order book L2 updates
* order book snapshots (tick-by-tick, 10ms, 100ms, 1s, 10s etc)
* quotes
* book ticker (best bid/ask from native BBO feeds)
* derivative tick info (open interest, funding rate, mark price, index price)
* liquidations
* options summary
* OHLCV
* volume/tick based trade bars

</details>

<details>

<summary><strong>What does high frequency historical data mean?</strong></summary>

For each exchange, we record the highest granularity available from its [real-time WebSocket feeds](#why-data-source-matters-websocket-feeds-vs-rest-endpoints). High frequency can mean different things because exchange APIs differ. For [Coinbase Exchange](/historical-data-details/coinbase), it can mean [L3 order book data](/faq/order-books#what-l3-order-book-data-can-be-used-for); for [Binance USDS-M Futures](/historical-data-details/binance-futures), all [L2](/faq/order-books#what-l2-order-book-data-can-be-used-for) order book updates; for [Binance Spot](/historical-data-details/binance), order book updates aggregated in 100ms intervals.

</details>

<details>

<summary><strong>How is historical raw market data sourced?</strong></summary>

Raw market data is sourced from exchanges' real-time WebSocket APIs. For cases where an exchange lacks a WebSocket API for a particular data type, we fall back to polling a REST API periodically, e.g., Binance USDS-M Futures open interest data.

{% hint style="info" %}
See [market data collection overview](/historical-data-details/overview#market-data-collection-overview) for more details and why [data source matters](#why-data-source-matters-websocket-feeds-vs-rest-endpoints).
{% endhint %}

</details>

<details>

<summary><strong>Why data source matters — WebSocket feeds vs REST endpoints</strong></summary>

Recording exchanges' real-time WebSocket feeds preserves [the most granular data](#what-does-high-frequency-historical-data-mean) that exchanges publish, including tick-level order book updates that are not available via REST APIs.

WebSocket-sourced historical data reflects what a live trading client would have received, including exchange-side behavior such as [connection drops](#is-provided-raw-market-data-complete), publishing delays during volatile periods, [duplicated trades](#are-exchanges-publishing-duplicated-trades-data-messages), or [crossed books](/faq/order-books#can-reconstructed-order-books-have-bid-ask-overlap) in edge cases. This makes it useful for market microstructure research and realistic replay, but it also means raw data is not corrected after the fact.

For example, during volatility an exchange may publish WebSocket messages with higher-than-usual latency or batch delayed updates. A REST endpoint may return a cleaner history after the fact, but it will not show the conditions a live client saw at that time.

{% hint style="info" %}
See [market data collection overview](/historical-data-details/overview#market-data-collection-overview) for more details.
{% endhint %}

</details>

<details>

<summary><strong>What is a difference between exchange-native and normalized data format?</strong></summary>

Cryptocurrency markets are very fragmented and every exchange provides data in its own bespoke format, which we call **exchange-native data format**.

Our [HTTP API](/api/http-api-reference#data-feeds-exchange) and [client libs](/api/quickstart) can provide market data in this format, meaning data you receive is exactly the same as the live data you would have received from exchanges ("as-is").

{% hint style="info" %}
See [how we collect data](/historical-data-details/overview#market-data-collection-overview) in exchange-native format and [why it's important](#why-data-source-matters-websocket-feeds-vs-rest-endpoints).
{% endhint %}

For example BitMEX trade message looks like this:

```javascript
{
  "table": "trade",
  "action": "insert",
  "data": [
    {
      "timestamp": "2019-06-01T00:03:11.589Z",
      "symbol": "ETHUSD",
      "side": "Sell",
      "size": 10,
      "price": 268.7,
      "tickDirection": "ZeroMinusTick",
      "trdMatchID": "ebc230d9-0b6e-2d5d-f99a-f90109a2b113",
      "grossValue": 268700,
      "homeNotional": 0.08555051758063137,
      "foreignNotional": 22.987424073915648
    }
  ]
}
```

and this is Deribit trade message:

```javascript
{
  "jsonrpc": "2.0",
  "method": "subscription",
  "params": {
    "channel": "trades.ETH-26JUN20.raw",
    "data": [
      {
        "trade_seq": 18052,
        "trade_id": "ETH-10813935",
        "timestamp": 1577836825724,
        "tick_direction": 0,
        "price": 132.65,
        "instrument_name": "ETH-26JUN20",
        "index_price": 128.6,
        "direction": "buy",
        "amount": 1.0
      }
    ]
  }
}

```

In contrast, **normalized data format** means the same, unified format across multiple exchanges. We provide normalized data via our [client libs](/api/quickstart) (data normalization is performed client-side) as well as via [downloadable CSV files](/downloadable-csv-files/overview).

{% hint style="info" %}
Normalization maps [exchange-native WebSocket data](#why-data-source-matters-websocket-feeds-vs-rest-endpoints) into one easier-to-use format across exchanges.

The [exchange-native to normalized mappings](https://github.com/tardis-dev/tardis-node/tree/master/src/mappers) are open source.
{% endhint %}

Sample **normalized** trade message:

```javascript
{
  "type": "trade",
  "symbol": "XBTUSD",
  "exchange": "bitmex",
  "id": "282a0445-0e3a-abeb-f403-11003204ea1b",
  "price": 7996,
  "amount": 50,
  "side": "sell",
  "timestamp": "2019-10-23T10:32:49.669Z",
  "localTimestamp": "2019-10-23T10:32:49.740Z"
}
```

We support following normalized data types via our [client libs](/api/quickstart):

* tick-by-tick trades
* order book L2 updates
* order book snapshots (tick-by-tick, 10ms, 100ms, 1s, 10s etc)
* quotes
* book ticker (best bid/ask from native BBO feeds)
* derivative tick info (open interest, funding rate, mark price, index price)
* liquidations
* options summary
* OHLCV
* volume/tick based trade bars

and [downloadable CSV data files](/downloadable-csv-files/overview):

* [tick-by-tick trades](/downloadable-csv-files/data-types#trades)
* [incremental order book L2 updates](/downloadable-csv-files/data-types#incremental_book_l2)
* tick level order book snapshots ([top 25](/downloadable-csv-files/data-types#book_snapshot_25) and [top 5](/downloadable-csv-files/data-types#book_snapshot_5) levels)
* [options\_chain](/downloadable-csv-files/data-types#options_chain)
* [quotes](/downloadable-csv-files/data-types#quotes)
* [book\_ticker](/downloadable-csv-files/data-types#book_ticker) (best bid/ask from native BBO feeds)
* [derivative tick info](/downloadable-csv-files/data-types#derivative_ticker) (open interest, funding rate, mark price, index price)
* [liquidations](/downloadable-csv-files/data-types#liquidations)

{% hint style="info" %}
**Where to find what — quick reference:**

* **Raw replay** ([HTTP API](/api/http-api-reference#data-feeds-exchange)) — all exchange-native channels in original format. Use this when you need fields or data types not available in normalized format.
* **Downloadable CSV files** ([datasets](/downloadable-csv-files/overview)) — normalized data types listed above (trades, incremental\_book\_L2, book\_snapshot, quotes, book\_ticker, derivative\_ticker, liquidations, options\_chain).
* **Client libs / tardis-machine** ([getting started](/api/quickstart)) — normalized data types plus additional computed types (trade\_bar, book snapshots with custom intervals, OHLCV, etc.), available for both historical replay and real-time streaming.

Not every exchange-native channel has a normalized equivalent. If a data type is available as a raw channel but not listed in normalized types above, it can only be accessed via raw replay.
{% endhint %}

</details>

<details>

<summary><strong>Do you provide market data in normalized format?</strong></summary>

[Normalized market data](#what-is-a-difference-between-exchange-native-and-normalized-data-format) (unified data format for every exchange) is available via our [official libraries](/api/quickstart) and [downloadable CSV files](/downloadable-csv-files/overview). Our [HTTP API](/api/http-api-reference#data-feeds-exchange) provides data only in [exchange-native format](#what-is-a-difference-between-exchange-native-and-normalized-data-format).

</details>

<details>

<summary><strong>What is the difference between `book_ticker` and `quote`?</strong></summary>

Both provide best bid/ask (BBO) data, but from different sources:

* **`book_ticker`** — sourced from exchanges' native WebSocket BBO channels (e.g., Binance `bookTicker`, Bybit `orderbook.1`). Available via [client libraries](/api/quickstart), [tardis-machine](/tardis-machine/quickstart) and [CSV datasets](/downloadable-csv-files/data-types#book_ticker). See [which exchanges support it](#which-exchanges-support-book_ticker-data-type).
* **`quote`** (alias for `book_snapshot_1_0ms`) — derived from L2 order book data. Available on all exchanges that provide L2 data. Also available as [`quotes` CSV dataset](/downloadable-csv-files/data-types#quotes).

Update frequency differs between the two and depends on the exchange. For example, on Binance the native `bookTicker` stream fires significantly more often than L2-derived quotes, because the exchange publishes a dedicated BBO update on every best-price change. On other exchanges the difference may be smaller or negligible. Check the update rates for your specific exchange before choosing.

When using the [replay API](/api/quickstart), `book_ticker` can be replayed starting from any point in time since it is a standalone exchange feed. In contrast, `quote` is derived from L2 order book state, which requires an initial snapshot to reconstruct — snapshots are provided at 00:00 UTC each day (and after each [WebSocket reconnect](#how-frequently-exchanges-drop-websocket-connections)), so replay should start from 00:00 UTC to get accurate quotes.

</details>

<details>

<summary><strong>Does Tardis provide precomputed indicators or OHLCV candles?</strong></summary>

Tardis provides raw tick-level market data (trades, order book updates, funding rates, liquidations, etc.) — not precomputed indicators, aggregated Kline/OHLCV candles, or hosted analytics. OHLCV bars and other derived metrics can be computed client-side from our data, for example using `trade_bar` data type in [tardis-machine](/tardis-machine/quickstart) or [client libraries](/api/quickstart).

</details>

<details>

<summary><strong>Do you provide time based aggregated data as well?</strong></summary>

Our APIs (both [HTTP](/api/http-api-reference#data-feeds-exchange) and [CSV datasets](/downloadable-csv-files/api#datasets-api-details)) provide tick-level data only and do not support time-based aggregated data.

If you need aggregated data (OHLC, interval-based order book snapshots), our [client libs](/api/quickstart) can compute it, but aggregation runs client-side from tick-level data, so it is slower than downloading pre-aggregated files.

</details>

<details>

<summary><strong>What is the historical market data delay in relation to real-time?</strong></summary>

For [raw data replay API](/api/quickstart) the most recent data available is approximately T-6 minutes from the current time.

[Downloadable CSV files](/downloadable-csv-files/overview) for a given day are available on the next day around 06:00 UTC — see [CSV readiness](/downloadable-csv-files/overview) for details.

</details>

<details>

<summary><strong>What is the `channel` field used in the HTTP API and client libs `replay` functions?</strong></summary>

When exchanges publish real-time data messages, they always publish them for the subscription topics clients subscribed to. These subscription topics are also often called "channels" or "streams" in exchange documentation and describe the data type a given message belongs to. For example, [BitMEX](/historical-data-details/bitmex) publishes its trade data via [trade channel](/historical-data-details/bitmex#captured-real-time-channels) and order book L2 update data via [orderBookL2](/historical-data-details/bitmex#captured-real-time-channels).

Since we collect the data for all the channels described in exchanges' details page ([Captured real-time market data channels section](/historical-data-details/bitmex#captured-real-time-channels)) our [HTTP API](/api/http-api-reference#data-feeds-exchange) and [client libs](/api/quickstart) offer filtering capability by those channels names, so for example to get historical trades for [BitMEX](/historical-data-details/bitmex), channel [trade](/historical-data-details/bitmex#captured-real-time-channels) needs to be provided alongside requested instruments symbols (via HTTP API or client lib `replay` function args).

</details>

<details>

<summary><strong>How CSV datasets are split into the files?</strong></summary>

CSV datasets are available in daily intervals split by exchange, data type, and symbol. In addition to standard currency pairs/instrument symbols, each exchange also has special [grouped symbols](/downloadable-csv-files/overview#grouped-symbols) available depending on whether it supports a given market type: SPOT, FUTURES, OPTIONS, PERPETUALS, COMBOS, and PREDICTIONS. That feature is useful if someone is interested in, for example, all Deribit's options instruments trades or quotes data without requesting data for each symbol separately.

</details>

<details>

<summary><strong>How do symbol IDs differ between raw replay and CSV datasets?</strong></summary>

The [`/exchanges/:exchange`](/api/http-api-reference#exchanges-exchange) API returns two separate symbol lists with different ID formats:

* **`availableSymbols[].id`** — used for [raw data replay](/api/http-api-reference#data-feeds-exchange). These are exchange-native symbol IDs as used in WebSocket subscriptions (e.g., `btcusdt` for Binance, `BTC-PERPETUAL` for Deribit).
* **`datasets.symbols[].id`** — used for [CSV dataset downloads](/downloadable-csv-files/overview). These are CSV dataset symbols: they are uppercased, and `/` and `:` are replaced with `-`. They can still contain non-ASCII or reserved URL characters, so URL-encode the symbol path segment when constructing dataset URLs manually. Official clients do this automatically.

The [Instruments Metadata API](/api/instruments-metadata-api) provides `id` for exchange-native symbols and `datasetId` for CSV dataset symbols after the symbol appears in exported dataset metadata.

</details>

<details>

<summary><strong>Does your historical data include delisted or expired instruments?</strong></summary>

Yes. Our historical datasets are survival-bias-free — they include all instruments that were actively trading at the time of data collection, including those that have since been delisted, expired, or renamed by the exchange.

Note that for some spot exchanges, early historical coverage was limited to high-cap currency pairs only. See individual exchange pages in [Historical Data Details](/historical-data-details/overview) for exact coverage boundaries and start dates.

</details>

<details>

<summary><strong>Can the same symbol ID refer to different assets over time?</strong></summary>

Yes. Exchanges may reuse symbol identifiers for different assets — for example, delisting a token and later listing a different token under the same symbol. Tardis passes through symbol IDs as provided by the exchange without modification, so the same symbol string may appear across different time periods for different underlying assets. Verify token identity using additional context such as price levels or exchange announcements.

</details>

<details>

<summary><strong>Do you provide historical futures data?</strong></summary>

Yes. We provide historical futures and perpetual swaps data across leading derivatives venues. See [Historical Data Details](/historical-data-details/overview) for the current exchange list and per-exchange coverage.

</details>

<details>

<summary><strong>What is the difference between futures and perpetual swaps contracts?</strong></summary>

Futures contract is a contract that has expiry date (for example quarter ahead for quarterly futures). Futures contract price converges to spot price as the contract approaches expiration/settlement date. After futures contract expires, exchange settles it and replaces with a new contract for the next period (next quarter for our previous example).

A perpetual swap contract, also commonly called "perp", "swap", "perpetual", or "perpetual future" in crypto exchange nomenclature, is very similar to a futures contract but does not have an expiry date (hence perpetual). To ensure that the perpetual swap contract price stays near the spot price, exchanges employ a mechanism called funding rate. When the funding rate is positive, Longs pay Shorts. When the funding rate is negative, Shorts pay Longs. This mechanism can be quite nuanced and vary between exchanges, so it's best to study each contract specification to learn all the details (funding periods, mark price mechanisms, etc.).

{% hint style="info" %}
See CSV [grouped symbols section](/downloadable-csv-files/overview#grouped-symbols) if you'd like to download data for all futures or perpetual swaps as a single file for given exchange instead one by one for each individual instrument.
{% endhint %}

</details>

<details>

<summary><strong>Do you provide historical options data?</strong></summary>

Yes, we do provide historical options data for [Binance European Options](/historical-data-details/binance-european-options), [OKX Options](/historical-data-details/okex-options), [Deribit](/historical-data-details/deribit), [Bybit Options](/historical-data-details/bybit-options), [Bullish](/historical-data-details/bullish), and [HTX Options](/historical-data-details/huobi-dm-options) (delisted) - see [options chain](/downloadable-csv-files/data-types#options_chain) CSV data type and the corresponding exchange details pages.

</details>

<details>

<summary><strong>Which exchanges support liquidations data type?</strong></summary>

[Liquidations](https://medium.com/tardis-dev/live-liquidations-monitor-for-top-cryptocurrency-exchanges-ac8e429e9556) data is sourced from exchanges' WebSocket APIs when supported, with fallback to polling REST APIs when WebSocket APIs do not support that data type, and can be accessed via [raw data APIs (replaying relevant channels)](/api/quickstart) or as a [normalized data type via CSV downloads](/downloadable-csv-files/data-types#liquidations).

| exchange                                                              | available since | data source                                                                                                                                                                |
| --------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Binance USDS-M Futures](/historical-data-details/binance-futures)    | 2020-01-07      | WS `forceOrder` stream                                                                                                                                                     |
| [Binance COIN Futures](/historical-data-details/binance-delivery)     | 2020-07-08      | WS `forceOrder` stream                                                                                                                                                     |
| [OKX Futures](/historical-data-details/okex-futures)                  | 2020-12-17      | WS `futures/liquidation` channel (before 2021-12-23); WS `liquidations` channel since 2021-12-23                                                                           |
| [OKX Swap](/historical-data-details/okex-swap)                        | 2020-12-18      | WS `swap/liquidation` channel (before 2021-12-23); WS `liquidations` channel since                                                                                         |
| [BitMEX](/historical-data-details/bitmex)                             | 2019-03-30      | WS `liquidation` channel                                                                                                                                                   |
| [Deribit](/historical-data-details/deribit)                           | 2019-03-30      | WS `trades` channel (trades with `liquidation` flag); data available until 2023-10-03 (Deribit removed the liquidation field from public trade subscriptions on that date) |
| [Bybit Derivatives](/historical-data-details/bybit)                   | 2020-11-03      | WS `liquidation` channel (before 2023-04-05); WS `allLiquidation` channel since 2025-02-25                                                                                 |
| [Kraken Futures](/historical-data-details/cryptofacilities)           | 2019-03-30      | WS `trade` channel (trades with `liquidation` type)                                                                                                                        |
| [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives) | 2019-09-14      | WS `liquidations` channel                                                                                                                                                  |
| [Aster Futures](/historical-data-details/aster-futures)               | 2026-08-23      | WS `forceOrder` channel                                                                                                                                                    |
| [Bitget Futures](/historical-data-details/bitget-futures)             | 2026-04-28      | WS `liquidation` channel                                                                                                                                                   |
| [HTX Coin-M Futures](/historical-data-details/huobi-dm)               | 2020-06-23      | WS `liquidation_orders` channel                                                                                                                                            |
| [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap)        | 2020-06-23      | WS `liquidation_orders` channel                                                                                                                                            |
| [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap) | 2020-10-30      | WS `liquidation_orders` channel                                                                                                                                            |
| [Lighter](/historical-data-details/lighter)                           | 2026-04-17      | WS `trade` channel (`liquidation_trades` payload)                                                                                                                          |
| [dYdX v4](/historical-data-details/dydx-v4)                           | 2024-08-23      | WS `trades` channel (trades with `liquidation` type)                                                                                                                       |

{% hint style="info" %}
Binance `forceOrder` streams push snapshot data at most once per second since April 2021 (no longer real-time individual events). Tardis captures exactly what exchanges publish — liquidation data should not be assumed to contain every individual liquidation event.
{% endhint %}

</details>

<details>

<summary><strong>Which exchanges support book_ticker data type?</strong></summary>

`book_ticker` provides top of the book (best bid/ask) data captured directly from exchanges' native WebSocket best bid/offer channels. See [book\_ticker vs quote](#what-is-the-difference-between-book_ticker-and-quote) for how it differs from L2-derived quotes.

| exchange                                                                      | available since | data source                                                         |
| ----------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------- |
| [Binance Spot](/historical-data-details/binance)                              | 2019-09-21      | WS `bookTicker` channel                                             |
| [Binance USDS-M Futures](/historical-data-details/binance-futures)            | 2019-11-17      | WS `bookTicker` channel                                             |
| [Binance COIN Futures](/historical-data-details/binance-delivery)             | 2020-06-16      | WS `bookTicker` channel                                             |
| [Binance European Options](/historical-data-details/binance-european-options) | 2025-12-17      | WS `bookTicker` channel                                             |
| [Binance US](/historical-data-details/binance-us)                             | 2019-09-25      | WS `bookTicker` channel                                             |
| [OKX Futures](/historical-data-details/okex-futures)                          | 2019-03-30      | WS `futures/ticker` channel (before 2021-12-23); WS `bbo-tbt` since |
| [OKX Swap](/historical-data-details/okex-swap)                                | 2019-03-30      | WS `swap/ticker` channel (before 2021-12-23); WS `bbo-tbt` since    |
| [OKX Options](/historical-data-details/okex-options)                          | 2020-02-01      | WS `option/ticker` channel (before 2021-12-23); WS `bbo-tbt` since  |
| [OKX Spot](/historical-data-details/okex)                                     | 2019-03-30      | WS `spot/ticker` channel (before 2021-12-23); WS `bbo-tbt` since    |
| [OKX Nitro Spreads](/historical-data-details/okex-spreads)                    | 2023-12-22      | WS `sprd-bbo-tbt` channel                                           |
| [Coinbase Exchange](/historical-data-details/coinbase)                        | 2019-03-30      | WS `ticker` channel                                                 |
| [Coinbase International](/historical-data-details/coinbase-international)     | 2024-10-31      | WS `LEVEL1` channel                                                 |
| [BitMEX](/historical-data-details/bitmex)                                     | 2019-03-30      | WS `quote` channel                                                  |
| [Deribit](/historical-data-details/deribit)                                   | 2019-10-01      | WS `ticker` channel                                                 |
| [Bybit Derivatives](/historical-data-details/bybit)                           | 2023-04-05      | WS `orderbook.1` channel                                            |
| [Bybit Spot](/historical-data-details/bybit-spot)                             | 2021-12-04      | WS `bookTicker` channel (before 2023-04-05); WS `orderbook.1` since |
| [Kraken Futures](/historical-data-details/cryptofacilities)                   | 2019-03-30      | WS `ticker` channel                                                 |
| [Kraken](/historical-data-details/kraken)                                     | 2019-06-04      | WS `spread` channel before 2026-07-10; WS v2 `ticker` channel since |
| [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives)         | 2019-09-14      | WS `ticker` channel                                                 |
| [Bitfinex](/historical-data-details/bitfinex)                                 | 2019-05-23      | WS `ticker` channel                                                 |
| [KuCoin Futures](/historical-data-details/kucoin-futures)                     | 2024-01-25      | WS `contractMarket/tickerV2` channel                                |
| [KuCoin Spot](/historical-data-details/kucoin)                                | 2022-08-16      | WS `market/ticker` channel                                          |
| [Aster Futures](/historical-data-details/aster-futures)                       | 2026-08-23      | WS `bookTicker` channel                                             |
| [Aster Spot](/historical-data-details/aster)                                  | 2026-08-23      | WS `bookTicker` channel                                             |
| [MEXC Spot](/historical-data-details/mexc)                                    | 2026-06-25      | WS `spot@public.aggre.bookTicker.v3.api.pb@10ms` channel            |
| [Crypto.com](/historical-data-details/crypto-com)                             | 2022-06-01      | WS `ticker` channel                                                 |
| [Bitget Futures](/historical-data-details/bitget-futures)                     | 2024-11-08      | WS `books1` channel                                                 |
| [Bitget Spot](/historical-data-details/bitget)                                | 2024-11-08      | WS `books1` channel                                                 |
| [Gate.io Futures](/historical-data-details/gate-io-futures)                   | 2022-03-17      | WS `book_ticker` channel                                            |
| [Gate.io](/historical-data-details/gate-io)                                   | 2023-04-29      | WS `book_ticker` channel                                            |
| [HTX Coin-M Futures](/historical-data-details/huobi-dm)                       | 2020-06-23      | WS `bbo` channel                                                    |
| [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap)                | 2020-08-17      | WS `bbo` channel                                                    |
| [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap)         | 2020-10-30      | WS `bbo` channel                                                    |
| [HTX Spot](/historical-data-details/huobi)                                    | 2019-11-19      | WS `bbo` channel                                                    |
| [Gemini](/historical-data-details/gemini)                                     | 2026-07-24      | WS `bookTicker` channel                                             |
| [WOO X](/historical-data-details/woo-x)                                       | 2023-01-20      | WS `bbo` channel                                                    |
| [Delta Exchange](/historical-data-details/delta)                              | 2023-04-01      | WS `l1_orderbook` channel                                           |
| [AscendEX](/historical-data-details/ascendex)                                 | 2021-03-28      | WS `bbo` channel                                                    |
| [bitFlyer](/historical-data-details/bitflyer)                                 | 2019-08-30      | WS `lightning_ticker` channel                                       |
| [Hyperliquid](/historical-data-details/hyperliquid)                           | 2025-06-26      | WS `bbo` channel                                                    |
| [Lighter](/historical-data-details/lighter)                                   | 2026-04-17      | WS `ticker` channel                                                 |
| [Polymarket](/historical-data-details/polymarket)                             | 2026-05-25      | WS `best_bid_ask` channel                                           |
| [Bullish](/historical-data-details/bullish)                                   | 2026-04-29      | WS `l1Orderbook` channel                                            |

</details>

<details>

<summary><strong>Do you provide normalized contract amounts for derivatives?</strong></summary>

Data we provide has contract amounts exactly as provided by exchanges' APIs, meaning the `amount` field may represent contracts, base-asset units, or USD depending on the exchange. This can be tricky when comparing across exchanges due to different contract multipliers (e.g., OKX where each contract has a $100 value) or different contract types (linear or inverse).

We provide the [instruments metadata API](/api/instruments-metadata-api) that returns `contractMultiplier`, `inverse`, `contractType`, tick sizes, and more for each instrument in a uniform way, allowing you to normalize contract amounts client-side. Use the following formulas for **futures and perpetual contracts**:

| Contract type             | Base-asset volume                     | USD notional                          |
| ------------------------- | ------------------------------------- | ------------------------------------- |
| Linear (`inverse: false`) | `amount × contractMultiplier`         | `amount × contractMultiplier × price` |
| Inverse (`inverse: true`) | `amount × contractMultiplier / price` | `amount × contractMultiplier`         |

{% hint style="warning" %}
These formulas apply to standard futures and perpetual contracts. Quanto contracts (`quanto_future`, `quanto_perpetual`) and options require different treatment — consult exchange-specific documentation for their volume calculations.
{% endhint %}

</details>

<details>

<summary><strong>Can you record market data for exchange that's not currently supported?</strong></summary>

Yes, we're always open to support new promising exchanges. [Contact us](https://tardis.dev/#contact) and we'll get back to you to discuss the details.

</details>

<details>

<summary><strong>Is provided raw market data complete?</strong></summary>

Raw WebSocket-sourced data can have gaps. Some gaps come from exchange-side behavior, such as exchange maintenance, API outages, [connection drops](#how-frequently-exchanges-drop-websocket-connections), upstream API changes, or unexpected upstream rate limits. Gaps can also come from Tardis.dev market data collection issues.

Historically, collection completeness is around 99.9% and reaches 99.99% on many days. These are historical observations, not guaranteed service levels.

Known incidents in Tardis.dev market data collection are listed in `incidentReports` from the [`/exchanges/:exchange`](/api/http-api-reference#exchanges-exchange) API endpoint. We do not use `incidentReports` as a complete log of exchange maintenance, exchange outages, or other upstream exchange-side issues.

Data gaps caused by exchange outages or collection interruptions are permanent because real-time WebSocket feed messages cannot be retroactively retrieved.

</details>

<details>

<summary><strong>Can exchange data contain invalid or extreme values?</strong></summary>

Yes. Tardis stores and serves exchange payloads exactly as received, without modification or filtering. If an exchange publishes an invalid price, extreme value, or malformed field, it will appear in the data as-is. This preserves full fidelity of the original feed. Apply your own validation and sanitization downstream when consuming raw data.

</details>

<details>

<summary><strong>What time zone is used in the data?</strong></summary>

UTC, always.

</details>

<details>

<summary><strong>How are market data messages timestamped?</strong></summary>

Each message received via WebSocket connection is timestamped with 100ns precision using [synchronized clock](https://developers.google.com/time) at arrival time (before any message processing) and stored in ISO 8601 format. Note that data is collected from different server locations depending on the exchange ([see market data collection overview](/historical-data-details/overview#market-data-collection-overview)). Local timestamps for exchanges collected from the same server location are directly comparable, but cross-region comparisons (e.g., London vs Tokyo) should not be used for sub-millisecond latency analysis.

</details>

<details>

<summary><strong>How are events ordered when multiple messages share the same timestamp?</strong></summary>

Row order in both replay API responses and CSV files reflects the original capture order — the sequence in which messages were received from the exchange WebSocket connection. When multiple events share the same millisecond exchange timestamp, use the row position (or `localTimestamp` ordering) as the tie-breaker rather than rounding or deduplicating by exchange timestamp.

</details>

<details>

<summary><strong>Are trades and order book updates synchronized across channels?</strong></summary>

Exchanges publish different data types (trades, order book updates, tickers, etc.) on independent WebSocket channels — often processed by separate backend services or workers. There is no cross-channel ordering guarantee from exchanges. For example, Deribit explicitly documents that cross-instrument timing is "inherently asynchronous" with separate internal workers per currency. Other exchanges (Binance, Bybit, OKX) are silent on cross-channel ordering, which in practice means no guarantee.

This means a trade's exchange timestamp does not guarantee that the order book state at that exact timestamp reflects the pre- or post-trade book. Similarly, different symbols — even on the same channel — may be served by different backend servers and arrive independently.

Tardis preserves the original message arrival order and never reorders events. In historical replay and CSV files, all messages are sorted by `localTimestamp` (the time we received the message), providing a chronological sequence across data types as observed from our collection servers.

</details>

<details>

<summary><strong>How frequently exchanges drop WebSocket connections?</strong></summary>

As long as an exchange WebSocket API is not hidden behind a Cloudflare proxy (causing relatively frequent "CloudFlare WebSocket proxy restarting, Connection reset by peer" errors), connections are stable for the majority of supported exchanges and there are almost no connection drops during the day. During periods of higher market volatility, some exchanges tend to drop connections more frequently or have larger latency spikes. Overall, it's a nuanced matter that changes over time. If you have any questions regarding a particular exchange, please do not hesitate to [contact us](https://tardis.dev/#contact).

</details>

<details>

<summary><strong>Are exchanges publishing duplicated trades data messages?</strong></summary>

Some exchanges are occasionally publishing duplicated trades (trades with the same ids). Since we collect real-time data we also collect and provide duplicate trades via [API](/api/quickstart) if those were published by real-time WebSocket feeds of exchanges. Our [client libraries](/api/quickstart) have functionality that when working with [normalized data](#what-is-a-difference-between-exchange-native-and-normalized-data-format) can deduplicate such trades, similarly for [downloadable CSV files](/downloadable-csv-files/overview) we deduplicate [tick-by-tick trades](/downloadable-csv-files/data-types#trades) data.

</details>

<details>

<summary><strong>Can timestamps be non-monotonic within a channel?</strong></summary>

That shouldn't happen in theory, but we've detected that for some exchanges when new connection is established sometimes first message for given channel & symbol has newer timestamp than subsequent message, e.g., order book snapshot has newer timestamp than first order book update. This is why we provide data via [API](/api/quickstart) and [CSV downloads](/downloadable-csv-files/overview) for given data ranges based on [local timestamps](#how-are-market-data-messages-timestamped) (timestamp of message arrival) which are always monotonically increasing.

</details>


# Order Books

Common questions about order book depth, snapshots and reconstruction

<details>

<summary><strong>What L2 order book data can be used for?</strong></summary>

L2 data (market-by-price) includes bids and asks orders aggregated by price level and can be used to analyze among other things:

* order book imbalance
* average execution cost
* average liquidity away from midpoint
* average spread
* hidden interest (i.e., iceberg orders)

We provide L2 data in [CSV format as incremental order book L2 updates](/downloadable-csv-files/data-types#incremental_book_l2), [tick-level order book snapshots](/downloadable-csv-files/data-types#book_snapshot_25) (top 25 and top 5 levels) and in [exchange-native](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) format via [API and client libraries that can perform full order book reconstruction](/api/quickstart) client-side.

</details>

<details>

<summary><strong>What L3 order book data can be used for?</strong></summary>

L3 data (market-by-order) includes every order book order addition, update, cancellation and match and can be used to analyze among other things:

* order resting time
* order fill probability
* order queue dynamics

Historical L3 data is currently available via API for [Bitfinex](/historical-data-details/bitfinex), [Coinbase Exchange](/historical-data-details/coinbase) and [Bitstamp](/historical-data-details/bitstamp) - remaining supported exchanges provide [L2 data](#what-l2-order-book-data-can-be-used-for) only.

</details>

<details>

<summary><strong>What is the maximum order book depth available for each supported exchange?</strong></summary>

We always collect full depth order book data as long as exchange's WebSocket API supports it. Table below shows current state of affairs for each supported exchange.

| exchange                                                                  | order book depth                                                                       | order book updates frequency            |
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------- |
| [Binance USDS-M Futures](/historical-data-details/binance-futures)        | top 1000 levels initial order book snapshot, full depth incremental order book updates | real-time, dynamically adjusted         |
| [Binance COIN Futures](/historical-data-details/binance-delivery)         | top 1000 levels initial order book snapshot, full depth incremental order book updates | real-time, dynamically adjusted         |
| [Binance Spot](/historical-data-details/binance)                          | top 1000 levels initial order book snapshot, full depth incremental order book updates | 100ms                                   |
| [Binance US](/historical-data-details/binance-us)                         | top 1000 levels initial order book snapshot, full depth incremental order book updates | 100ms                                   |
| [OKX Futures](/historical-data-details/okex-futures)                      | top 400 levels initial order book snapshot and updates                                 | real-time                               |
| [OKX Swap](/historical-data-details/okex-swap)                            | top 400 levels initial order book snapshot and updates                                 | real-time                               |
| [OKX Options](/historical-data-details/okex-options)                      | top 400 levels initial order book snapshot and updates                                 | real-time                               |
| [OKX Spot](/historical-data-details/okex)                                 | top 400 levels initial order book snapshot and updates                                 | real-time                               |
| [Coinbase Exchange](/historical-data-details/coinbase)                    | full order book depth snapshot and updates                                             | real-time                               |
| [Coinbase International](/historical-data-details/coinbase-international) | order book snapshots and deltas                                                        | real-time                               |
| [BitMEX](/historical-data-details/bitmex)                                 | full order book depth snapshot and updates                                             | real-time                               |
| [Deribit](/historical-data-details/deribit)                               | full order book depth snapshot and updates                                             | real-time                               |
| [Bybit Derivatives](/historical-data-details/bybit)                       | top 25 levels initial order book snapshot and updates                                  | real-time                               |
| [Kraken Futures](/historical-data-details/cryptofacilities)               | full order book depth snapshot and updates                                             | real-time                               |
| [Kraken](/historical-data-details/kraken)                                 | top 1000 levels initial order book snapshot and updates                                | real-time                               |
| [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives)     | top 100 levels initial order book snapshot and updates                                 | real-time                               |
| [Bitfinex](/historical-data-details/bitfinex)                             | top 100 levels initial order book snapshot and updates                                 | real-time                               |
| [KuCoin Futures](/historical-data-details/kucoin-futures)                 | generated Level 2 order book snapshots plus Level 2 deltas                             | real-time                               |
| [KuCoin Spot](/historical-data-details/kucoin)                            | generated Level 2 order book snapshots plus Level 2 deltas                             | real-time                               |
| [Aster Futures](/historical-data-details/aster-futures)                   | top 1000 levels generated REST snapshot plus full depth incremental updates            | real-time, dynamically adjusted         |
| [Aster Spot](/historical-data-details/aster)                              | top 1000 levels generated REST snapshot plus full depth incremental updates            | real-time, dynamically adjusted         |
| [MEXC Spot](/historical-data-details/mexc)                                | generated REST depth snapshots up to 5000 levels plus incremental updates              | 10ms                                    |
| [MEXC Futures](/historical-data-details/mexc-futures)                     | generated REST depth snapshots up to 5000 levels plus incremental updates              | 200ms                                   |
| [Crypto.com](/historical-data-details/crypto-com)                         | order book snapshots and updates                                                       | real-time (5s heartbeat when unchanged) |
| [Bitstamp](/historical-data-details/bitstamp)                             | full order book depth snapshot and updates                                             | real-time                               |
| [Bitget Futures](/historical-data-details/bitget-futures)                 | full depth order book snapshots and updates from 2026-04-28; top 15 snapshots before   | 50ms                                    |
| [Bitget Spot](/historical-data-details/bitget)                            | full depth order book snapshots and updates from 2026-04-28; top 15 snapshots before   | 50ms                                    |
| [Gate.io Futures](/historical-data-details/gate-io-futures)               | top 20 levels order book snapshots                                                     | unknown                                 |
| [Gate.io](/historical-data-details/gate-io)                               | top 30 levels order book snapshots                                                     | unknown                                 |
| [HTX Coin-M Futures](/historical-data-details/huobi-dm)                   | top 150 levels initial order book snapshot and updates                                 | 30ms                                    |
| [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap)            | top 150 levels initial order book snapshot and updates                                 | 30ms                                    |
| [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap)     | top 150 levels initial order book snapshot and updates                                 | 30ms                                    |
| [HTX Spot](/historical-data-details/huobi)                                | top 150 levels initial order book snapshot and updates                                 | 100ms                                   |
| [Gemini](/historical-data-details/gemini)                                 | full order book depth snapshot and updates                                             | v2 real-time; v3 100ms since 2026-07-24 |
| [WOO X](/historical-data-details/woo-x)                                   | REST-bootstrapped order book snapshots plus incremental updates                        | real-time                               |
| [Upbit](/historical-data-details/upbit)                                   | top 15 levels snapshots                                                                | real-time                               |
| [Phemex](/historical-data-details/phemex)                                 | top 30 levels initial order book snapshot and updates                                  | 20ms                                    |
| [Delta Exchange](/historical-data-details/delta)                          | order book snapshots and incremental updates                                           | real-time                               |
| [AscendEX (BitMax)](/historical-data-details/ascendex)                    | order book snapshots followed by real-time deltas                                      | real-time                               |
| [Blockchain.com](/historical-data-details/blockchain-com)                 | Level 2 order book snapshots and deltas                                                | real-time                               |
| [Bitnomial](/historical-data-details/bitnomial)                           | order book snapshots plus price level updates                                          | real-time                               |
| [bitFlyer](/historical-data-details/bitflyer)                             | full order book depth snapshot and updates                                             | real-time                               |
| [HitBTC (high caps)](/historical-data-details/hitbtc)                     | full order book depth snapshot and updates                                             | real-time                               |
| [Poloniex](/historical-data-details/poloniex)                             | full order book depth snapshot and updates                                             | real-time                               |
| [Hyperliquid](/historical-data-details/hyperliquid)                       | order book snapshots                                                                   | unknown                                 |
| [Lighter](/historical-data-details/lighter)                               | order book snapshots and incremental updates                                           | 50ms                                    |
| [Polymarket](/historical-data-details/polymarket)                         | full order book snapshots plus price level updates                                     | real-time                               |
| [Bullish](/historical-data-details/bullish)                               | Level 2 order book snapshots and updates                                               | real-time                               |
| [dYdX v4](/historical-data-details/dydx-v4)                               | order book snapshots and incremental updates                                           | real-time                               |
| [FTX](/historical-data-details/ftx)                                       | top 100 levels initial order book snapshot and updates                                 | real-time                               |
| [FTX US](/historical-data-details/ftx-us)                                 | top 100 levels initial order book snapshot and updates                                 | real-time                               |
| [OKCoin](/historical-data-details/okcoin)                                 | top 400 levels initial order book snapshot and updates                                 | real-time                               |
| [dYdX](/historical-data-details/dydx)                                     | full order book depth snapshot and updates                                             | real-time                               |
| [Binance DEX](/historical-data-details/binance-dex)                       | top 1000 levels initial order book snapshot, full depth incremental order book updates | 100ms                                   |

</details>

<details>

<summary><strong>How are order book data snapshots provided?</strong></summary>

Historical market data available via [HTTP API](/api/http-api-reference#data-feeds-exchange) provides order book snapshots at the beginning of each day (`00:00 UTC`) - [see details](/historical-data-details/overview#collected-order-book-data-details).

We also provide custom order book snapshots with customizable time intervals from tick-by-tick, milliseconds to minutes or hours via [client libs](/api/quickstart) in which case custom snapshots are computed client side from raw data provided via HTTP API as well as via [downloadable CSV files](/downloadable-csv-files/overview) - [book\_snapshot\_25](/downloadable-csv-files/data-types#book_snapshot_25) and [book\_snapshot\_5](/downloadable-csv-files/data-types#book_snapshot_5) .

</details>

<details>

<summary><strong>Do you collect order books as snapshots or in streaming mode?</strong></summary>

Order books are collected in streaming mode - snapshot at the beginning of each day and then incremental updates. [See details](/historical-data-details/overview#collected-order-book-data-details).

We also provide custom order book snapshots with customizable time intervals from tick-by-tick, milliseconds to minutes or hours via [client libs](/api/quickstart) in which case custom snapshots are computed client side from raw data provided via HTTP API as well as via [downloadable CSV files](/downloadable-csv-files/overview) - [book\_snapshot\_25](/downloadable-csv-files/data-types#book_snapshot_25) and [book\_snapshot\_5](/downloadable-csv-files/data-types#book_snapshot_5) .

</details>

<details>

<summary><strong>How incremental_book_l2 CSV dataset is built from real-time data?</strong></summary>

Cryptocurrency exchanges' real-time APIs vary a lot, but for [L2 order book data](#what-l2-order-book-data-can-be-used-for) they all tend to follow a similar flow: first, when a WS connection is established and subscription is confirmed, exchanges send an initial order book snapshot (all existing price levels or top `x` levels depending on exchange), and then start streaming order book update messages (often called deltas). Those updates, when applied to the initial snapshot, result in an up-to-date order book state at a given time.

{% hint style="info" %}
We provide initial L2 snapshots in the `incremental_book_L2` dataset at the beginning of each day (00:00 UTC, [more details](/historical-data-details/overview#collected-order-book-data-details)), and also any time an exchange closes its real-time WebSocket connection, [see details](/faq/data#how-frequently-exchanges-drop-websocket-connections).
{% endhint %}

{% hint style="info" %}
Snapshot rows (`is_snapshot=true`) may contain price levels outside the nominal top-N depth advertised by the exchange (e.g., beyond top 1000 for Binance). This is because snapshots combine the exchange-provided snapshot with any incremental updates buffered during connection setup. Consumers should always reset their local order book state when encountering a new snapshot batch, regardless of depth.
{% endhint %}

Let's take FTX as an example and start with its snapshot order book message (which is frequently called 'partial' in exchange API docs as well).

Remaining bids and asks levels were removed from this sample message for the sake of clarity.

```javascript
{
  "channel": "orderbook",
  "market": "ETH/USD",
  "type": "partial",
  "data": {
    "time": 1601510401.2166328,
    "checksum": 204980439,
    "bids": [
      [
        359.72,
        121.259
      ]
    ],
    "asks": [
      [
        359.8,
        8.101
      ]
    ],
    "action": "partial"
  }
}
```

Such snapshot message maps to the following rows in CSV file:

| exchange | symbol  | timestamp        | local\_timestamp | is\_snapshot | side | price  | amount  |
| -------- | ------- | ---------------- | ---------------- | ------------ | ---- | ------ | ------- |
| ftx      | ETH/USD | 1601510401216632 | 1601510401316432 | true         | ask  | 359.8  | 8.101   |
| ftx      | ETH/USD | 1601510401216632 | 1601510401316432 | true         | bid  | 359.72 | 121.259 |

... and here's a sample FTX orderbook update message.

```javascript
{
  "channel": "orderbook",
  "market": "ETH/USD",
  "type": "update",
  "data": {
    "time": 1601510427.1840546,
    "checksum": 1377242400,
    "bids": [],
    "asks": [
      [
        360.24,
        4.962
      ],
      [
        361.02,
        0
      ]
    ],
    "action": "update"
  }
}
```

Let's see how it maps to CSV format.

| exchange | symbol  | timestamp        | local\_timestamp | is\_snapshot | side | price  | amount |
| -------- | ------- | ---------------- | ---------------- | ------------ | ---- | ------ | ------ |
| ftx      | ETH/USD | 1601510427184054 | 1601510427204046 | false        | ask  | 360.24 | 4.962  |
| ftx      | ETH/USD | 1601510427184054 | 1601510427204036 | false        | ask  | 361.02 | 0      |

See [this answer](#how-can-i-reconstruct-full-order-book-state-from-incremental_book_l2-csv-dataset) if you have doubts how to reconstruct order book state based on data provided in `incremental_book_L2` dataset.

</details>

<details>

<summary><strong>How can I reconstruct full order book state from incremental_book_L2 CSV dataset?</strong></summary>

{% hint style="info" %}
See also [how incremental\_book\_l2 CSV dataset is built from real-time data](#how-incremental_book_l2-csv-dataset-is-built-from-real-time-data).
{% endhint %}

In order to reconstruct full order book state correctly from [`incremental_book_L2`](/downloadable-csv-files/data-types#incremental_book_l2) data:

* Rows before the first snapshot in the file should be skipped — they are buffered updates received before the exchange sent the initial snapshot after a connection restart.
* For each row in the CSV file (iterate in the same order as provided in file):
  * only if the local timestamp of the current row is larger than the previous row local timestamp (`local_timestamp` column value) does it mean you can read your local order book state as consistent. Why? CSV format is flat where each row represents a single price level update, but most exchanges' real-time feeds publish multiple order book level updates via a single WebSocket message that need to be processed together before reading locally maintained order book state. We use local timestamp value here to detect all price level updates belonging to a single 'update' message.
  * if current row is a part of the snapshot (`is_snapshot` column value set to `true`) and previous one was not, reset your local order book state object that tracks price levels for each order book side as it means that there was a connection restart and exchange provided full order book snapshot or it was a start of a new day (each incremental\_book\_L2 file starts with the snapshot)
  * if current row amount **is** set to zero (`amount` column value set to `0`) remove such price level (row's `price` column) from your local order book state as such price level does not exist anymore
  * if current row amount **is not** set to zero update your local order book state price level with new value or add new price level if not exist yet in your local order book state - maintain separately bids and asks order book sides (`side` column value)

Alternatively, we also provide [top 25 and top 5 levels](/downloadable-csv-files/data-types#book_snapshot_25) order book snapshots as CSV datasets ready to download.

</details>

<details>

<summary><strong>Can order book snapshots be empty?</strong></summary>

Yes. For very illiquid instruments (e.g., deep out-of-the-money options or niche currency pairs) order book snapshots can be present but empty — containing no bid or ask levels. This is not a data gap; it reflects the actual state of the order book on the exchange at that time. Subsequent snapshots after reconnects may also be empty if the instrument remains illiquid.

</details>

<details>

<summary><strong>Can reconstructed order books have bid-ask overlap?</strong></summary>

Although it should never happen in theory, in practice due to various crypto exchanges bugs and peculiarities it can happen (very occasionally), see some posts from users reporting those issues:

* <https://www.reddit.com/r/BitMEX/comments/8lbj9e/bidask_ledger_weirdness/>
* <https://www.reddit.com/r/KrakenSupport/comments/emu7xc/websocket_bid_sometimes_not_being_deletedupdated/>
* <https://www.reddit.com/r/KrakenSupport/comments/d1a4nx/websocket_orderbook_receiving_wrong_bid_price_for/>
* <https://twitter.com/coinarb/status/931260529993170944>

We do track sequence numbers of WebSocket L2 order book messages when collecting the data and restart connection when sequence gap is detected for exchanges that do provide those numbers. We observe that even in scenario when sequence numbers are in check, bid/ask overlap can occur.

When such scenario occurs, exchanges tend to 'forget' to publish delete messages for the opposite side of the book when publishing new level for given side - we validated that hypothesis by comparing reconstructed order book snapshots that had crossed order book (bid/ask overlap) for which we removed order book levels for the opposite side manually (as exchange didn't publish that 'delete'), with quote/ticker feeds if best bid/ask matches (for exchanges that provide those) - see [sample code that implements that manual level removal logic](https://github.com/tardis-dev/tardis-node/blob/master/src/orderbook.ts#L65).

If you encounter a crossed book during reconstruction, the recommended approach is to remove overlapping levels from the opposite side. Additionally, crossed states are always resolved by the next snapshot reset (either at 00:00 UTC daily resubscription or after a WebSocket reconnect).

</details>


# Billing and Subscriptions

Common questions about plans, pricing and invoices

<details>

<summary><strong>What is the order process?</strong></summary>

1. Choose a data plan and subscription type in the [order form](https://tardis.dev/#order).
   * available data plans
     * [Perpetuals](#what-is-included-in-perpetuals-data-plan)
     * [Options](#what-is-included-in-options-data-plan)
     * [Spot](#what-is-included-in-spot-data-plan)
     * [Derivatives](#what-is-included-in-derivatives-data-plan)
     * [All Exchanges](#what-is-included-in-all-exchanges-data-plan)
   * available subscription types
     * [Solo](#what-are-the-differences-between-subscription-types)
     * [Academic](#what-are-the-differences-between-subscription-types)
     * [Pro](#what-are-the-differences-between-subscription-types)
     * [Business](#what-are-the-differences-between-subscription-types)
2. Proceed to checkout where you provide your email address and payment details. [See accepted payment methods](https://paddle.com/support/which-payment-methods-do-you-support/).
   * accepted payment methods
     * Credit Cards (Mastercard Visa Maestro American Express Discover Diners Club JCB UnionPay)
     * PayPal
3. Successfully complete your payment and receive an API key via email that allows you to [download CSV datasets](/downloadable-csv-files/overview) and [access historical data via API](/api/quickstart). The API key is valid while your account has an active subscription.

{% hint style="info" %}
For larger orders we also accept [pay through invoicing](#can-i-pay-through-invoicing).
{% endhint %}

</details>

<details>

<summary><strong>Do you provide discounts?</strong></summary>

No. We do not provide discounts, but we offer [different subscription types](#what-are-the-differences-between-subscription-types) for solo traders, academic users, professionals and businesses.

</details>

<details>

<summary><strong>Do you offer one-off purchases or custom data exports?</strong></summary>

No. Historical data is available through subscriptions; we do not sell fixed date ranges or prepare custom data exports.

</details>

<details>

<summary><strong>How do free trials work?</strong></summary>

[Contact us](https://tardis.dev/#contact) to request a trial.

A trial is active for 30 days and includes a randomly selected 7–14-day range of recent historical data. It requires no payment details and expires without converting into a paid subscription.

</details>

<details>

<summary><strong>How does subscription-based access work?</strong></summary>

Subscription-based access uses monthly, quarterly or yearly billing. An active subscription gives access to newly collected market data as it [becomes available](/faq/data#what-is-the-historical-market-data-delay-in-relation-to-real-time), plus [existing historical market data](#do-subscriptions-include-access-to-historical-data-as-well). The historical range depends on the billing interval.

When ordering a subscription, you choose:

* Subscription type — [Academic, Solo, Pro, or Business](#what-are-the-differences-between-subscription-types)
* Data plan — [Perpetuals](#what-is-included-in-perpetuals-data-plan), [Options](#what-is-included-in-options-data-plan), [Spot](#what-is-included-in-spot-data-plan), [Derivatives](#what-is-included-in-derivatives-data-plan) or [All Exchanges](#what-is-included-in-all-exchanges-data-plan)
* Billing interval — [monthly, quarterly or yearly](#do-subscriptions-include-access-to-historical-data-as-well)

For example, an "[All Exchanges](#what-is-included-in-all-exchanges-data-plan)" Business subscription with [yearly billing](#do-subscriptions-include-access-to-historical-data-as-well) gives access to **all available existing historical data via API and CSV files**, plus new data as it becomes available during the yearly billing interval.

The product access scope depends on your subscription type:

* **Academic and Solo** — [downloadable CSV files](/downloadable-csv-files/overview) only
* **Pro and Business** — [downloadable CSV files](/downloadable-csv-files/overview), [raw data replay API](/api/quickstart), [tardis-machine](/tardis-machine/quickstart), and [instruments metadata API](/api/instruments-metadata-api)

</details>

<details>

<summary><strong>What are the differences between subscription types?</strong></summary>

{% hint style="info" %}
Academic subscriptions are available with quarterly or yearly billing and require confirmation of eligibility, for example using a university email address.
{% endhint %}

|                                                                                                                    | Academic | Solo    | Professional | Business          |
| ------------------------------------------------------------------------------------------------------------------ | -------- | ------- | ------------ | ----------------- |
| [Full history access (yearly billing)](#do-subscriptions-include-access-to-historical-data-as-well)                | 4 years  | 4 years | 4 years      | ✓ (all available) |
| [Professional support level](/faq/general#what-does-professional-support-mean)                                     | none     | none    | email        | priority email    |
| [Downloadable CSV files](/downloadable-csv-files/overview)                                                         | ✓        | ✓       | ✓            | ✓                 |
| [Raw data replay API](/api/quickstart) (HTTP API `/data-feeds`)                                                    | —        | —       | ✓            | ✓                 |
| [Tardis Machine replay APIs](/tardis-machine/replaying-historical-data#http-get-replay-normalized-options-options) | —        | —       | ✓            | ✓                 |
| [Instrument metadata API](/api/instruments-metadata-api)                                                           | —        | —       | ✓            | ✓                 |
| [Premium connectivity](/faq/general#what-is-premium-connectivity)                                                  | —        | —       | ✓            | ✓                 |
| Integration assistance                                                                                             | —        | —       | —            | ✓                 |
| Vendor onboarding                                                                                                  | —        | —       | —            | ✓                 |
| Active API keys                                                                                                    | 1        | 1       | 1            | up to 10          |

{% hint style="info" %}
Academic, Solo and Professional include one active API key; Business includes up to 10. All API keys share the account's [API request and data transfer limits](/api/rate-limits).

Each API key can be used from one IP address at a time. [Real-time market data streaming](/faq/general#do-you-support-consolidated-real-time-market-data-streaming) does not require an API key.
{% endhint %}

</details>

<details>

<summary><strong>Do subscriptions include access to historical data as well?</strong></summary>

Yes, **depending on the billing interval**, subscriptions include access to existing historical market data as well:

* **Yearly billing:**
  * **Business subscriptions:** access to **all available historical data** since **2019-03-30** for majority of the supported exchanges ([see exchange details page](/historical-data-details/overview#per-exchange-historical-data-details) for exact date for particular exchange)
  * **Academic, Solo, and Pro subscriptions:** access to **4 years of historical data**, e.g., subscription that has started at 2026-01-01 includes access to historical data since 2022-01-01
* **Quarterly billing:** access to **12 months of historical data**, e.g., subscription that has started at 2026-01-01 includes access to historical data since 2025-01-01
* **Monthly billing (Solo, Pro, and Business only):** access to **4 months of historical data**, e.g., subscription that has started at 2026-01-01 includes access to historical data since 2025-09-01

Historical data access is not a rolling time window, but a fixed starting date since when historical data is available for your subscription.

</details>

<details>

<summary><strong>What is included in "Perpetuals" data plan?</strong></summary>

"Perpetuals" data plan provides access to the following perpetual swaps instruments' market data:

* [Binance USDS-M Futures](/historical-data-details/binance-futures): all perpetual swaps instruments
* [Binance COIN Futures](/historical-data-details/binance-delivery): all perpetual swaps instruments
* [OKX Swap](/historical-data-details/okex-swap): all perpetual swaps instruments
* [BitMEX](/historical-data-details/bitmex): all perpetual swaps instruments
* [Deribit](/historical-data-details/deribit): all perpetual swaps instruments
* [Bybit Derivatives](/historical-data-details/bybit): all perpetual swaps instruments
* [Kraken Futures](/historical-data-details/cryptofacilities): all perpetual swaps instruments
* [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives): all perpetual swaps instruments
* [KuCoin Futures](/historical-data-details/kucoin-futures): all perpetual swaps instruments
* [Aster Futures](/historical-data-details/aster-futures): all perpetual swaps instruments
* [MEXC Futures](/historical-data-details/mexc-futures): all perpetual swaps instruments
* [Crypto.com](/historical-data-details/crypto-com): all perpetual swaps instruments
* [Bitget Futures](/historical-data-details/bitget-futures): all perpetual swaps instruments
* [Gate.io Futures](/historical-data-details/gate-io-futures): all perpetual swaps instruments
* [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap): all perpetual swaps instruments
* [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap): all perpetual swaps instruments
* [WOO X](/historical-data-details/woo-x): all perpetual swaps instruments
* [Phemex](/historical-data-details/phemex): all perpetual swaps instruments
* [Delta Exchange](/historical-data-details/delta): all perpetual swaps instruments
* [bitFlyer](/historical-data-details/bitflyer): FX\_BTC\_JPY
* [Hyperliquid](/historical-data-details/hyperliquid): all perpetual swaps instruments
* [Lighter](/historical-data-details/lighter): all perpetual swaps instruments
* [Bullish](/historical-data-details/bullish): all perpetual swaps instruments
* [dYdX v4](/historical-data-details/dydx-v4): all perpetual swaps instruments
* [FTX](/historical-data-details/ftx) (delisted): all perpetual swaps instruments
* [AscendEX](/historical-data-details/ascendex) (delisted): all perpetual swaps instruments
* [CoinFLEX](/historical-data-details/coinflex) (delisted): all perpetual swaps instruments
* [dYdX](/historical-data-details/dydx) (delisted): all perpetual swaps instruments

"Perpetuals" data plan allows access to [**all available data types**](/faq/data#what-data-types-do-you-support) (trades, order book data, funding, etc.) via [downloadable CSV files](/downloadable-csv-files/overview) and [raw data replay API](/api/quickstart) (for Pro and Business subscription types).

Range of historical data access for "Perpetuals" data plan depends on [billing interval and subscription type](#do-subscriptions-include-access-to-historical-data-as-well).

</details>

<details>

<summary><strong>What is included in "Options" data plan?</strong></summary>

"Options" data plan provides access to the following options exchanges' market data:

* [Binance European Options](/historical-data-details/binance-european-options): all options instruments
* [OKX Options](/historical-data-details/okex-options): all options instruments
* [Deribit](/historical-data-details/deribit): all options instruments
* [Bybit Options](/historical-data-details/bybit-options): all options instruments
* [Bullish](/historical-data-details/bullish): all options instruments
* [HTX Options](/historical-data-details/huobi-dm-options) (delisted): all options instruments

"Options" data plan allows access to [**all available data types**](/faq/data#what-data-types-do-you-support) (trades, order book data, quotes, etc.) via [downloadable CSV files](/downloadable-csv-files/overview) and [raw data replay API](/api/quickstart) (for Pro and Business subscription types).

Range of historical data access for "Options" data plan depends on [billing interval and subscription type](#do-subscriptions-include-access-to-historical-data-as-well).

</details>

<details>

<summary><strong>What is included in "Spot" data plan?</strong></summary>

"Spot" data plan provides access to the following spot exchanges' market data:

* [Binance Spot](/historical-data-details/binance): all spot instruments
* [Binance US](/historical-data-details/binance-us): all spot instruments
* [OKX Spot](/historical-data-details/okex): all spot instruments
* [Bybit Spot](/historical-data-details/bybit-spot): all spot instruments
* [Kraken](/historical-data-details/kraken): all spot instruments
* [Bitfinex](/historical-data-details/bitfinex): all spot instruments
* [KuCoin Spot](/historical-data-details/kucoin): all spot instruments
* [Aster Spot](/historical-data-details/aster): all spot instruments
* [MEXC Spot](/historical-data-details/mexc): all spot instruments
* [Crypto.com](/historical-data-details/crypto-com): all spot instruments
* [Bitstamp](/historical-data-details/bitstamp): all spot instruments
* [Bitget Spot](/historical-data-details/bitget): all spot instruments
* [Gate.io](/historical-data-details/gate-io): all spot instruments
* [HTX Spot](/historical-data-details/huobi): all spot instruments
* [Gemini](/historical-data-details/gemini): all spot instruments
* [WOO X](/historical-data-details/woo-x): all spot instruments
* [Upbit](/historical-data-details/upbit): all spot instruments
* [Blockchain.com](/historical-data-details/blockchain-com): all spot instruments
* [HitBTC](/historical-data-details/hitbtc): all spot instruments
* [Poloniex](/historical-data-details/poloniex): all spot instruments
* [Lighter](/historical-data-details/lighter): all spot instruments
* [Bullish](/historical-data-details/bullish): all spot instruments
* [FTX](/historical-data-details/ftx) (delisted): all spot instruments
* [FTX US](/historical-data-details/ftx-us) (delisted): all spot instruments
* [OKCoin](/historical-data-details/okcoin) (delisted): all spot instruments
* [AscendEX](/historical-data-details/ascendex) (delisted): all spot instruments
* [CoinFLEX](/historical-data-details/coinflex) (delisted): all spot instruments
* [Binance Jersey](/historical-data-details/binance-jersey) (delisted): all spot instruments
* [Binance DEX](/historical-data-details/binance-dex) (delisted): all spot instruments
* [Serum](/historical-data-details/serum) (delisted): all spot instruments
* [Star Atlas](/historical-data-details/star-atlas) (delisted): all spot instruments

"Spot" data plan allows access to [**all available data types**](/faq/data#what-data-types-do-you-support) (trades, order book data, quotes, etc.) via [downloadable CSV files](/downloadable-csv-files/overview) and [raw data replay API](/api/quickstart) (for Pro and Business subscription types).

Range of historical data access for "Spot" data plan depends on [billing interval and subscription type](#do-subscriptions-include-access-to-historical-data-as-well).

{% hint style="info" %}
[Coinbase Exchange](/historical-data-details/coinbase) and [Coinbase International](/historical-data-details/coinbase-international) market data are available only in the ["All Exchanges" data plan](#what-is-included-in-all-exchanges-data-plan).
{% endhint %}

</details>

<details>

<summary><strong>What is included in "Derivatives" data plan?</strong></summary>

"Derivatives" data plan provides access to the following derivatives exchanges' market data:

* [Binance USDS-M Futures](/historical-data-details/binance-futures): all exchange's instruments
* [Binance COIN Futures](/historical-data-details/binance-delivery): all exchange's instruments
* [Binance European Options](/historical-data-details/binance-european-options): all exchange's instruments
* [OKX Futures](/historical-data-details/okex-futures): all exchange's instruments
* [OKX Swap](/historical-data-details/okex-swap): all exchange's instruments
* [OKX Options](/historical-data-details/okex-options): all exchange's instruments
* [OKX Nitro Spreads](/historical-data-details/okex-spreads): all exchange's instruments
* [BitMEX](/historical-data-details/bitmex): all exchange's instruments
* [Deribit](/historical-data-details/deribit): all exchange's instruments
* [Bybit Derivatives](/historical-data-details/bybit): all exchange's instruments
* [Bybit Options](/historical-data-details/bybit-options): all exchange's instruments
* [Kraken Futures](/historical-data-details/cryptofacilities): all exchange's instruments
* [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives): all exchange's instruments
* [KuCoin Futures](/historical-data-details/kucoin-futures): all exchange's instruments
* [Aster Futures](/historical-data-details/aster-futures): all exchange's instruments
* [MEXC Futures](/historical-data-details/mexc-futures): all exchange's instruments
* [Crypto.com](/historical-data-details/crypto-com): all exchange's instruments
* [Bitget Futures](/historical-data-details/bitget-futures): all exchange's instruments
* [Gate.io Futures](/historical-data-details/gate-io-futures): all exchange's instruments
* [HTX Coin-M Futures](/historical-data-details/huobi-dm): all exchange's instruments
* [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap): all exchange's instruments
* [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap): all exchange's instruments
* [WOO X](/historical-data-details/woo-x): all exchange's instruments
* [Phemex](/historical-data-details/phemex): all exchange's instruments
* [Delta Exchange](/historical-data-details/delta): all exchange's instruments
* [Bitnomial](/historical-data-details/bitnomial): all exchange's instruments
* [bitFlyer](/historical-data-details/bitflyer): all exchange's instruments
* [Hyperliquid](/historical-data-details/hyperliquid): all exchange's instruments
* [Lighter](/historical-data-details/lighter): all exchange's instruments
* [Bullish](/historical-data-details/bullish): all exchange's instruments
* [dYdX v4](/historical-data-details/dydx-v4): all exchange's instruments
* [FTX](/historical-data-details/ftx) (delisted): all exchange's instruments
* [AscendEX](/historical-data-details/ascendex) (delisted): all exchange's instruments
* [CoinFLEX](/historical-data-details/coinflex) (delisted): all exchange's instruments
* [HTX Options](/historical-data-details/huobi-dm-options) (delisted): all exchange's instruments
* [dYdX](/historical-data-details/dydx) (delisted): all exchange's instruments
* [Mango](/historical-data-details/mango) (delisted): all exchange's instruments

"Derivatives" data plan allows access to [**all available data types**](/faq/data#what-data-types-do-you-support) (trades, order book data, quotes, funding, etc.) via [downloadable CSV files](/downloadable-csv-files/overview) and [raw data replay API](/api/quickstart) (for Pro and Business subscription types).

Range of historical data access for "Derivatives" data plan depends on [billing interval and subscription type](#do-subscriptions-include-access-to-historical-data-as-well).

</details>

<details>

<summary><strong>What is included in "All Exchanges" data plan?</strong></summary>

"All Exchanges" data plan provides access to market data of [**all supported exchanges**](/faq/general#which-exchanges-instruments-and-currency-pairs-are-supported) (**50+ leading spot and derivatives exchanges**, [see full list](/faq/general#which-exchanges-instruments-and-currency-pairs-are-supported)).

"All Exchanges" data plan allows access to [**all available data types**](/faq/data#what-data-types-do-you-support) (trades, order book data, quotes, funding, liquidations, etc.) for [all supported exchanges](/faq/general#which-exchanges-instruments-and-currency-pairs-are-supported) and their instruments/currency pairs via [downloadable CSV files](/downloadable-csv-files/overview) and [raw data replay API](/api/quickstart) (for Pro and Business subscription types).

Range of historical data access for "All Exchanges" data plan depends on [billing interval and subscription type](#do-subscriptions-include-access-to-historical-data-as-well).

</details>

<details>

<summary><strong>How can I change my subscription plan?</strong></summary>

[Contact us](https://tardis.dev/#contact) with the plan you'd like to switch to and we'll handle it.

</details>

<details>

<summary><strong>Can I pay through invoicing?</strong></summary>

We offer invoicing for customers paying over $6000 for data access. Simply use our [order form](https://tardis.dev/#order) and "PAY THROUGH INVOICING" button.

Alternatively [contact us](https://tardis.dev/#contact) with order details you're interested in (data plan, billing interval) and we'll send you back invoice that if paid will give you access to the data.

![Pay through invoicing order form preview](/files/IgS6OoWTLmdKD9gtK8Lg)

![Sample invoice document preview](/files/mx2mxdorBj2GPQuRQ4Wt)

</details>

<details>

<summary><strong>Can I get quotation document before making an order?</strong></summary>

Yes, please use our [order form](https://tardis.dev/#order) and "REQUEST QUOTATION" button.

Alternatively [contact us](https://tardis.dev/#contact) with order details you're interested in (data plan, billing interval) and we'll send you a quotation document.

![request quotation document order form preview](/files/IgS6OoWTLmdKD9gtK8Lg)

![Sample quotation document preview](/files/2MreoyInovyg1wfofLT1)

</details>

<details>

<summary><strong>How can I get an invoice and VAT refund?</strong></summary>

After successful order you'll receive Receipt email from [Paddle](https://paddle.com/) which is our online reseller & payment processor. Click on the button titled "View Receipt" there.

![Receipt email preview](/files/EHjMfsc7NKZUYtTAMT3L)

You will be redirected to the receipt page where you will be able to enter your address details by clicking on "Add address & VAT Number“ link.

![Receipt page preview](/files/eGP7mKXAQuoAlAeB8zvK)

If you would like to enter a VAT number select "This is a business purchase" checkbox to enter the VAT ID if forgot to enter it during the checkout. The tax amount will be refunded in max. 12 hours after it is confirmed by Paddle.

!["Edit receipt information" preview](/files/yEHOg1TWUsAdmOF1u4Bp)

#### [Save invoice as PDF](https://www.wikihow.com/Convert-a-Webpage-to-PDF)

* Right click on the screen and click 'Print...' in context menu
* Change destination to 'Save as PDF'
* Click 'Save' button to save invoice as PDF file

</details>

<details>

<summary><strong>What are your VAT details?</strong></summary>

Click on the link titled "Click here to get a full invoice with address & custom information" provided with the order confirmation email sent by Paddle to get the address and VAT ID of Paddle who process our payments. Paddle acts as a reseller and Merchant of Record so they handle VAT on our behalf.

</details>

<details>

<summary><strong>I’ve lost my invoice. How do I get a new one?</strong></summary>

You need to [contact us](https://tardis.dev/#contact) or <help@paddle.com> to request a new invoice. Please provide the email address you bought the subscription with and any extra details that might help.

</details>

<details>

<summary><strong>What is the refund policy?</strong></summary>

We do not offer refunds for initial subscription payments.

If you are on **yearly billing** and forget to [cancel](#how-can-i-cancel-my-subscription) your subscription before the renewal date, [reach out to us](https://tardis.dev/#contact) within seven days after the renewal date to discuss a refund.

If you’re on **monthly or quarterly billing**, please be sure to [cancel](#how-can-i-cancel-my-subscription) your subscription before the end date of your current plan as there are no refunds for recurring payments on monthly and quarterly billing plans.

</details>

<details>

<summary><strong>How can I cancel my subscription?</strong></summary>

To cancel your subscription, use the cancellation link from your subscription email or [contact us](https://tardis.dev/#contact) and we'll send it again.

Alternatively you can email [Paddle](https://paddle.com/) (<help@paddle.com>) which acts as our reseller and Merchant of Record including a note of the email address you used to purchase your subscription and your order number.

</details>

<details>

<summary><strong>How can I update my credit card information?</strong></summary>

In order to update your credit card information use the 'Update payment method' link we've sent you in email together with your API key or [contact us](https://tardis.dev/#contact) and we'll provide that link for you.

</details>


# Quickstart

Get started with downloading CSV datasets via Python, Node.js or cURL

CSV datasets are available via [dedicated datasets API](/downloadable-csv-files/api#datasets-api-details) that allows downloading tick level [incremental order book L2 updates](/downloadable-csv-files/data-types#incremental_book_l2), order book snapshots ([top 25](/downloadable-csv-files/data-types#book_snapshot_25) and [top 5](/downloadable-csv-files/data-types#book_snapshot_5)), [trades](/downloadable-csv-files/data-types#trades), [options chains](/downloadable-csv-files/data-types#options_chain), [quotes](/downloadable-csv-files/data-types#quotes), [book tickers](/downloadable-csv-files/data-types#book_ticker), [derivative tickers](/downloadable-csv-files/data-types#derivative_ticker) and [liquidations](/downloadable-csv-files/data-types#liquidations) data.

* For ongoing data, CSV datasets for a given day are available on the next day around 06:00 UTC. Historical datasets for the first day of each month are available to download without API key.
* CSV datasets are exported from exchanges' [real-time WebSocket feeds data](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) we collected and also provide via our [API](/api/quickstart) as historical data in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format).
* Row order in CSV files reflects the original capture order. When multiple events share the same millisecond exchange timestamp, use row position as the tie-breaker — see [event ordering FAQ](/faq/data#how-are-events-ordered-when-multiple-messages-share-the-same-timestamp).

## Download via client libraries

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

```python
# pip install tardis-dev
# requires Python >=3.9
from tardis_dev import download_datasets

download_datasets(
    exchange="deribit",
    data_types=[
        "incremental_book_L2",
        "trades",
        "quotes",
        "derivative_ticker",
        "book_snapshot_25",
        "liquidations"
    ],
    from_date="2019-11-01",
    to_date="2019-11-02",
    symbols=["BTC-PERPETUAL", "ETH-PERPETUAL"],
    api_key="YOUR API KEY (optionally)",
)
```

{% endtab %}

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

```javascript
// npm install tardis-dev
// requires Node.js v24+
import { downloadDatasets } from 'tardis-dev'

await downloadDatasets({
  exchange: 'deribit',
  dataTypes: [
    'incremental_book_L2',
    'trades',
    'quotes',
    'derivative_ticker',
    'book_snapshot_25',
    'liquidations'
  ],
  from: '2019-11-01',
  to: '2019-11-02',
  symbols: ['BTC-PERPETUAL', 'ETH-PERPETUAL'],
  apiKey: 'YOUR API KEY (optionally)'
})
```

{% endtab %}

{% tab title="cURL" %}

```bash
curl -L -o deribit_trades_2019-11-01_BTC-PERPETUAL.csv.gz https://datasets.tardis.dev/v1/deribit/trades/2019/11/01/BTC-PERPETUAL.csv.gz

```

{% endtab %}
{% endtabs %}

{% content-ref url="/pages/tVvKgm0JyGa2InwT2YKH" %}
[Data Types](/downloadable-csv-files/data-types)
{% endcontent-ref %}

{% content-ref url="/pages/qqtWvA83hsjBsfDmZ6Jg" %}
[API Reference](/downloadable-csv-files/api)
{% endcontent-ref %}

## How to download all exchange CSV datasets

The examples above download data for specific symbols. To download **all available datasets for every instrument** of a given exchange, use the exchange metadata API to iterate over all symbols automatically.

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

```python
# requires Python >=3.9
# pip install tardis-dev

from tardis_dev import download_datasets, get_exchange_details
import logging

# optionally enable debug logs
# logging.basicConfig(level=logging.DEBUG)

# change to any exchange id from https://api.tardis.dev/v1/exchanges with supportsDatasets:true
exchange = "deribit"
exchange_details = get_exchange_details(exchange)

# iterate over and download all data for every symbol
for symbol in exchange_details["datasets"]["symbols"]:
    # alternatively specify data types explicitly ['trades', 'incremental_book_L2', 'quotes'] etc
    # see available options https://docs.tardis.dev/downloadable-csv-files/data-types#data-types
    data_types = symbol["dataTypes"]
    symbol_id = symbol["id"]
    from_date = symbol["availableSince"]
    to_date = symbol["availableTo"]

    # skip grouped symbols like PERPETUALS, SPOT, FUTURES, OPTIONS, COMBOS, PREDICTIONS
    if symbol_id in ["PERPETUALS", "SPOT", "FUTURES", "OPTIONS", "COMBOS", "PREDICTIONS"]:
        continue

    print(f"Downloading {exchange} {data_types} for {symbol_id} from {from_date} to {to_date}")

    # each CSV dataset format is documented at https://docs.tardis.dev/downloadable-csv-files/data-types#data-types
    download_datasets(
        exchange=exchange,
        data_types=data_types,
        from_date=from_date,
        to_date=to_date,
        symbols=[symbol_id],
        # TODO set your API key here
        api_key="YOUR_API_KEY",
        # path where CSV data will be downloaded into
        download_dir="./datasets",
    )
```

{% endtab %}

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

```javascript
// npm install tardis-dev
// requires Node.js v24+
import { downloadDatasets, getExchangeDetails } from 'tardis-dev'

// change to any exchange id from https://api.tardis.dev/v1/exchanges with supportsDatasets:true
const exchange = 'deribit'
const exchangeDetails = await getExchangeDetails(exchange)

// iterate over and download all data for every symbol
for (const symbol of exchangeDetails.datasets.symbols) {
  // alternatively specify dataTypes explicitly ['trades', 'incremental_book_L2', 'quotes'] etc
  // see available options https://docs.tardis.dev/downloadable-csv-files/data-types#data-types
  const dataTypes = symbol.dataTypes
  const symbolId = symbol.id
  const from = symbol.availableSince
  const to = symbol.availableTo

  // skip grouped symbols like PERPETUALS, SPOT, FUTURES, OPTIONS, COMBOS, PREDICTIONS
  if (['PERPETUALS', 'SPOT', 'FUTURES', 'OPTIONS', 'COMBOS', 'PREDICTIONS'].includes(symbolId)) {
    continue
  }

  console.log(`Downloading ${exchange} ${dataTypes} for ${symbolId} from ${from} to ${to}`)

  // each CSV dataset format is documented at https://docs.tardis.dev/downloadable-csv-files/data-types#data-types
  await downloadDatasets({
    exchange,
    dataTypes,
    from,
    to,
    symbols: [symbolId],
    // TODO: set your API key here
    apiKey: 'YOUR_API_KEY',
    // path where CSV data will be downloaded into
    downloadDir: './datasets'
  })
}
```

{% endtab %}

{% tab title="cURL" %}

```bash
curl -L -o deribit_trades_2019-11-01_BTC-PERPETUAL.csv.gz https://datasets.tardis.dev/v1/deribit/trades/2019/11/01/BTC-PERPETUAL.csv.gz
```

{% endtab %}
{% endtabs %}

## Grouped symbols

In addition to standard currency pairs & instrument symbols available via the [CSV datasets API](/downloadable-csv-files/api#datasets-api-reference), each exchange has special grouped symbols depending on which market types it supports: **SPOT**, **FUTURES**, **OPTIONS**, **PERPETUALS**, **COMBOS**, and **PREDICTIONS**. When you request a grouped symbol, the downloaded file contains data for all instruments of that market type. This is especially useful for options, where specifying each symbol one by one would be tedious — using `OPTIONS` as a symbol gives data for all options available at a given time. `PREDICTIONS` is available only for `trades` datasets.

{% hint style="info" %}
See [what is the difference between futures and perpetual swaps contracts](/faq/data#what-is-the-difference-between-futures-and-perpetual-swaps-contracts).
{% endhint %}

* [incremental\_book\_L2](/downloadable-csv-files/data-types#incremental_book_l2) - available for FUTURES, OPTIONS ([Deribit](/historical-data-details/deribit), [OKX Options](/historical-data-details/okex-options), [Binance European Options](/historical-data-details/binance-european-options))
  * Examples:
    * <https://datasets.tardis.dev/v1/ftx/incremental_book_L2/2020/09/01/FUTURES.csv.gz>
    * <https://datasets.tardis.dev/v1/deribit/incremental_book_L2/2020/09/01/OPTIONS.csv.gz>
* [trades](/downloadable-csv-files/data-types#trades) - available for SPOT, FUTURES, OPTIONS, PERPETUALS, COMBOS, PREDICTIONS
  * Examples:
    * <https://datasets.tardis.dev/v1/binance/trades/2020/09/01/SPOT.csv.gz>
    * <https://datasets.tardis.dev/v1/deribit/trades/2020/09/01/FUTURES.csv.gz>
    * <https://datasets.tardis.dev/v1/okex-options/trades/2020/09/01/OPTIONS.csv.gz>
    * <https://datasets.tardis.dev/v1/ftx/trades/2020/09/01/PERPETUALS.csv.gz>
    * <https://datasets.tardis.dev/v1/deribit/trades/2023/01/01/COMBOS.csv.gz>
* [derivative\_ticker](/downloadable-csv-files/data-types#derivative_ticker) - available for FUTURES, PERPETUALS, COMBOS
  * Examples:
    * <https://datasets.tardis.dev/v1/ftx/derivative_ticker/2020/09/01/FUTURES.csv.gz>
    * <https://datasets.tardis.dev/v1/bitmex/derivative_ticker/2020/09/01/PERPETUALS.csv.gz>
    * <https://datasets.tardis.dev/v1/deribit/derivative_ticker/2023/01/01/COMBOS.csv.gz>
* [options\_chain](/downloadable-csv-files/data-types#options_chain) - available for OPTIONS
  * Examples:
    * <https://datasets.tardis.dev/v1/deribit/options_chain/2020/09/01/OPTIONS.csv.gz>
    * <https://datasets.tardis.dev/v1/okex-options/options_chain/2020/09/01/OPTIONS.csv.gz>
* [quotes](/downloadable-csv-files/data-types#quotes) - available for OPTIONS
  * Examples:
    * <https://datasets.tardis.dev/v1/deribit/quotes/2020/09/01/OPTIONS.csv.gz>
    * <https://datasets.tardis.dev/v1/okex-options/quotes/2020/09/01/OPTIONS.csv.gz>
* [liquidations](/downloadable-csv-files/data-types#liquidations) - available for FUTURES, PERPETUALS, OPTIONS
  * Examples:
    * <https://datasets.tardis.dev/v1/deribit/liquidations/2021/09/01/PERPETUALS.csv.gz>
    * <https://datasets.tardis.dev/v1/ftx/liquidations/2021/09/01/FUTURES.csv.gz>
    * <https://datasets.tardis.dev/v1/deribit/liquidations/2021/09/01/OPTIONS.csv.gz>
* [book\_snapshot\_25](/downloadable-csv-files/data-types#book_snapshot_25) - available for OPTIONS ([Deribit](/historical-data-details/deribit), [OKX Options](/historical-data-details/okex-options), [Binance European Options](/historical-data-details/binance-european-options))
  * Examples:
    * <https://datasets.tardis.dev/v1/deribit/book_snapshot_25/2025/03/01/OPTIONS.csv.gz>
* [book\_snapshot\_5](/downloadable-csv-files/data-types#book_snapshot_5) - available for OPTIONS ([Deribit](/historical-data-details/deribit), [OKX Options](/historical-data-details/okex-options), [Binance European Options](/historical-data-details/binance-european-options))
  * Examples:
    * <https://datasets.tardis.dev/v1/deribit/book_snapshot_5/2025/03/01/OPTIONS.csv.gz>
* [book\_ticker](/downloadable-csv-files/data-types#book_ticker) - available for OPTIONS ([Deribit](/historical-data-details/deribit), [OKX Options](/historical-data-details/okex-options), [Binance European Options](/historical-data-details/binance-european-options))
  * Examples:
    * <https://datasets.tardis.dev/v1/deribit/book_ticker/2025/03/01/OPTIONS.csv.gz>

Those special symbols are also listed in response to [/exchanges/:exchange](/api/http-api-reference#exchanges-exchange) API call.


# Data Types

CSV column schemas, sample rows and download links

* [incremental\_book\_L2](#incremental_book_l2)
* [book\_snapshot\_25](#book_snapshot_25)
* [book\_snapshot\_5](#book_snapshot_5)
* [trades](#trades)
* [options\_chain](#options_chain)
* [quotes](#quotes)
* [book\_ticker](#book_ticker)
* [derivative\_ticker](#derivative_ticker)
* [liquidations](#liquidations)

## CSV format details

* columns delimiter: **, (comma)**
* new line marker: **\n (LF)**
* decimal mark: **. (dot)**
* date time format: **microseconds since epoch** (<https://www.epochconverter.com/>)
* date time timezone: **UTC**

## incremental\_book\_L2

Incremental order book L2 updates collected from exchanges' [real-time WebSocket](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) order book L2 data feeds - data as deep and granular as underlying real-time data source, please see [FAQ: What is the maximum order book depth available for each supported exchange?](/faq/order-books#what-is-the-maximum-order-book-depth-available-for-each-supported-exchange) for more details.

{% hint style="info" %}
Learn in more detail [how incremental\_book\_l2 CSV dataset is built from real-time data](/faq/order-books#how-incremental_book_l2-csv-dataset-is-built-from-real-time-data).
{% endhint %}

As exchanges' real-time feeds usually publish multiple order book level updates in a single message, you can recognize that by grouping rows by the `local_timestamp` field if needed.

Files may contain non-snapshot updates before the first snapshot — skip these rows until you encounter the first `is_snapshot=true` row. These are buffered updates received before the exchange sent the initial snapshot after a connection restart.

{% hint style="info" %}
If you have any doubts about how to correctly reconstruct full order book state from the incremental\_book\_L2 CSV dataset, please [see this answer](/faq/order-books#how-can-i-reconstruct-full-order-book-state-from-incremental_book_l2-csv-dataset) or [contact us](https://tardis.dev/#contact).

In case you only need **order book data for top 25 or top 5 levels,** we provide datasets with already reconstructed snapshots for every update for those. See [book\_snapshot\_25](#book_snapshot_25) and [book\_snapshot\_5](#book_snapshot_5).
{% endhint %}

{% tabs %}
{% tab title="CSV incremental\_book\_L2  schema" %}

| column name      | description                                                                                                                                                                                                                                                                                                                                 |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| exchange         | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                                                                                                                                                                                                                   |
| symbol           | instrument symbol as provided by exchange (always uppercase)                                                                                                                                                                                                                                                                                |
| timestamp        | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback                                                                                                                                                                                             |
| local\_timestamp | message arrival timestamp in **microseconds since epoch**                                                                                                                                                                                                                                                                                   |
| is\_snapshot     | <p>possible values:<br><code>true</code> - if update was a part of initial order book snapshot<br><code>false</code> - if update <strong>was not</strong> a part of initial order book snapshot<br>If last update was not a snapshot and current one is, then existing order book state must be discarded (all existing levels removed)</p> |
| side             | <p>determines to which side of the order book update belongs to:<br><code>bid</code> - bid side of the book, buy orders<br><code>ask</code> - ask side of the book, sell orders</p>                                                                                                                                                         |
| price            | price identifying book level being updated                                                                                                                                                                                                                                                                                                  |
| amount           | updated price level amount as provided by exchange, **not a delta** - an amount of `0` indicates that the price level can be removed                                                                                                                                                                                                        |
| {% endtab %}     |                                                                                                                                                                                                                                                                                                                                             |

{% tab title="dataset preview" %}

| exchange      | symbol        | timestamp        | local\_timestamp | is\_snapshot | side | price  | amount |
| ------------- | ------------- | ---------------- | ---------------- | ------------ | ---- | ------ | ------ |
| deribit       | BTC-PERPETUAL | 1585699209920000 | 1585699209934201 | false        | ask  | 6443.5 | 38640  |
| deribit       | BTC-PERPETUAL | 1585699209947000 | 1585699209957629 | false        | bid  | 6311.5 | 0      |
| {% endtab %}  |               |                  |                  |              |      |        |        |
| {% endtabs %} |               |                  |                  |              |      |        |        |

{% embed url="<https://datasets.tardis.dev/v1/deribit/incremental_book_L2/2020/04/01/BTC-PERPETUAL.csv.gz>" %}
Deribit BTC-PERPETUAL incremental order book L2 updates for 2020-04-01
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/deribit/incremental_book_L2/2020/09/01/FUTURES.csv.gz>" %}
Deribit FUTURES instruments incremental order book L2 updates for 2020-09-01
{% endembed %}

## book\_snapshot\_25

Tick-level order book snapshots reconstructed from exchanges' [real-time WebSocket](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) order book L2 data feeds. Each row represents **top 25 levels** from each side of the limit order book and was recorded every time any of the tracked bids/asks top 25 levels changed.

{% hint style="info" %}
Book snapshots are reconstructed with crossed levels removed — if a bid price >= ask price appears in exchange data, the overlapping level is discarded. See [order book crossing FAQ](/faq/order-books#can-reconstructed-order-books-have-bid-ask-overlap) for details.
{% endhint %}

{% tabs %}
{% tab title="CSV book\_snapshot\_25 schema" %}

| column name                                                                                                                                 | description                                                                                                                                                                                            |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| exchange                                                                                                                                    | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                                                                              |
| symbol                                                                                                                                      | instrument symbol as provided by exchange (always uppercase)                                                                                                                                           |
| timestamp                                                                                                                                   | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback                                                        |
| local\_timestamp                                                                                                                            | message arrival timestamp in **microseconds since epoch**                                                                                                                                              |
| asks\[0].price, asks\[0].amount, bids\[0].price, bids\[0].amount, ..., asks\[24].price, asks\[24].amount, bids\[24].price, bids\[24].amount | top 25 levels interleaved per level: ask price, ask amount, bid price, bid amount for each level (0-24). Asks in ascending price order, bids in descending. Empty if there aren't enough price levels. |
| {% endtab %}                                                                                                                                |                                                                                                                                                                                                        |

{% tab title="dataset preview" %}

| exchange      | symbol        | timestamp        | local\_timestamp | asks\[0].price | asks\[0].amount | bids\[0].price | bids\[0].amount | asks\[1].price | asks\[1].amount | bids\[1].price | bids\[1].amount | ... |
| ------------- | ------------- | ---------------- | ---------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | --- |
| deribit       | BTC-PERPETUAL | 1599868800206000 | 1599868800253274 | 10396          | 48050           | 10395.5        | 18220           | 10396.5        | 22220           | 10395          | 16570           | ... |
| deribit       | BTC-PERPETUAL | 1599868800280000 | 1599868800310441 | 10396          | 48050           | 10395.5        | 18220           | 10396.5        | 22220           | 10395          | 16570           | ... |
| {% endtab %}  |               |                  |                  |                |                 |                |                 |                |                 |                |                 |     |
| {% endtabs %} |               |                  |                  |                |                 |                |                 |                |                 |                |                 |     |

{% embed url="<https://datasets.tardis.dev/v1/bitmex/book_snapshot_25/2020/09/01/XBTUSD.csv.gz>" %}
BitMEX XBTUSD top 25 levels order book snapshots for 2020-09-01
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/binance-futures/book_snapshot_25/2020/09/01/BTCUSDT.csv.gz>" %}
Binance USDS-M Futures BTCUSDT top 25 levels order book snapshots for 2020-09-01
{% endembed %}

## book\_snapshot\_5

Tick-level order book snapshots reconstructed from exchanges' [real-time WebSocket](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) order book L2 data feeds. Each row represents **top 5 levels** from each side of the limit order book and was recorded every time any of the tracked bids/asks top 5 levels changed.

{% hint style="info" %}
Book snapshots are reconstructed with crossed levels removed — if a bid price >= ask price appears in exchange data, the overlapping level is discarded. See [order book crossing FAQ](/faq/order-books#can-reconstructed-order-books-have-bid-ask-overlap) for details.
{% endhint %}

{% tabs %}
{% tab title="CSV book\_snapshot\_5 schema" %}

| column name                                                                                                                             | description                                                                                                                                                                                          |
| --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| exchange                                                                                                                                | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                                                                            |
| symbol                                                                                                                                  | instrument symbol as provided by exchange (always uppercase)                                                                                                                                         |
| timestamp                                                                                                                               | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback                                                      |
| local\_timestamp                                                                                                                        | message arrival timestamp in **microseconds since epoch**                                                                                                                                            |
| asks\[0].price, asks\[0].amount, bids\[0].price, bids\[0].amount, ..., asks\[4].price, asks\[4].amount, bids\[4].price, bids\[4].amount | top 5 levels interleaved per level: ask price, ask amount, bid price, bid amount for each level (0-4). Asks in ascending price order, bids in descending. Empty if there aren't enough price levels. |
| {% endtab %}                                                                                                                            |                                                                                                                                                                                                      |

{% tab title="dataset preview" %}

| exchange      | symbol | timestamp        | local\_timestamp | asks\[0].price | asks\[0].amount | bids\[0].price | bids\[0].amount | asks\[1].price | asks\[1].amount | bids\[1].price | bids\[1].amount | asks\[2].price | asks\[2].amount | bids\[2].price | bids\[2].amount | asks\[3].price | asks\[3].amount | bids\[3].price | bids\[3].amount | asks\[4].price | asks\[4].amount | bids\[4].price | bids\[4].amount |
| ------------- | ------ | ---------------- | ---------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- | -------------- | --------------- |
| bitmex        | XBTUSD | 1598918402683390 | 1598918402683390 | 11658          | 1399982         | 11657.5        | 2293327         | 11658.5        | 82328           | 11657          | 37555           | 11659          | 3001            | 11656.5        | 110647          | 11659.5        | 10843           | 11656          | 10063           | 11660          | 2522            | 11655.5        | 4039            |
| bitmex        | XBTUSD | 1598918403229829 | 1598918403229829 | 11658          | 1399982         | 11657.5        | 2293327         | 11658.5        | 82328           | 11657          | 37555           | 11659          | 3001            | 11656.5        | 110647          | 11659.5        | 10835           | 11656          | 10063           | 11660          | 2522            | 11655.5        | 4039            |
| {% endtab %}  |        |                  |                  |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |
| {% endtabs %} |        |                  |                  |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |                |                 |

{% embed url="<https://datasets.tardis.dev/v1/bitmex/book_snapshot_5/2020/09/01/XBTUSD.csv.gz>" %}
BitMEX XBTUSD top 5 levels order book snapshots for 2020-09-01
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/binance-futures/book_snapshot_5/2020/09/01/BTCUSDT.csv.gz>" %}
Binance USDS-M Futures BTCUSDT top 5 levels order book snapshots for 2020-09-01
{% endembed %}

## trades

Individual trades data collected from exchanges' [real-time WebSocket trades data feeds](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints).

{% tabs %}
{% tab title="CSV trades schema" %}

| column name      | description                                                                                                                                                                                                                       |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| exchange         | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                                                                                                         |
| symbol           | instrument symbol as provided by exchange (always uppercase)                                                                                                                                                                      |
| timestamp        | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback                                                                                   |
| local\_timestamp | message arrival timestamp in **microseconds since epoch**                                                                                                                                                                         |
| id               | trade id as provided by exchange, empty if exchange does not provide one - different exchanges provide id's as numeric values, GUID's or other strings, and some do not provide that information at all                           |
| side             | <p>liquidity taker side (aggressor), possible values:<br><code>buy</code> - liquidity taker was buying<br><code>sell</code> - liquidity taker was selling<br><code>unknown</code> - exchange did not provide that information</p> |
| price            | trade price as provided by exchange                                                                                                                                                                                               |
| amount           | trade amount as provided by exchange                                                                                                                                                                                              |
| {% endtab %}     |                                                                                                                                                                                                                                   |

{% tab title="dataset preview" %}

| exchange      | symbol | timestamp        | local\_timestamp | id     | side | price  | amount |
| ------------- | ------ | ---------------- | ---------------- | ------ | ---- | ------ | ------ |
| bitmex        | XBTUSD | 1585699202957000 | 1585699203089980 | d20... | buy  | 6425.5 | 12     |
| bitmex        | XBTUSD | 1585699202980000 | 1585699203095276 | 619... | sell | 6425   | 150    |
| {% endtab %}  |        |                  |                  |        |      |        |        |
| {% endtabs %} |        |                  |                  |        |      |        |        |

{% embed url="<https://datasets.tardis.dev/v1/bitmex/trades/2020/03/01/XBTUSD.csv.gz>" %}
Bitmex XBTUSD trades for 2020-03-01 dataset sample
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/okex-futures/trades/2020/03/01/FUTURES.csv.gz>" %}
OKX Futures FUTURES instruments trades for 2020-03-01 dataset sample
{% endembed %}

## options\_chain

Tick-level options summary info (strike prices, expiration dates, open interest, implied volatility, greeks etc.) for all active options instruments collected from exchanges' [real-time WebSocket](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) options data feeds. Options chain data is currently available for [Deribit](/historical-data-details/deribit), [OKX Options](/historical-data-details/okex-options), [Bybit Options](/historical-data-details/bybit-options), [Binance European Options](/historical-data-details/binance-european-options), [Bullish](/historical-data-details/bullish), and [HTX Options](/historical-data-details/huobi-dm-options).

{% hint style="info" %}
For `options_chain` data type only ['OPTIONS' symbol](/downloadable-csv-files/overview#grouped-symbols) is available (one file per day for all options instruments).
{% endhint %}

{% tabs %}
{% tab title="CSV options\_chain schema" %}

| column name       | description                                                                   |
| ----------------- | ----------------------------------------------------------------------------- |
| exchange          | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)     |
| symbol            | instrument symbol as provided by exchange (always uppercase)                  |
| timestamp         | ticker timestamp provided by exchange in **microseconds since epoch**         |
| local\_timestamp  | ticker message arrival timestamp in **microseconds since epoch**              |
| type              | <p>option type, possible values:<br><code>put</code><br><code>call</code></p> |
| strike\_price     | option strike price                                                           |
| expiration        | option expiration date in **microseconds since epoch**                        |
| open\_interest    | current open interest, empty if exchange does not provide one                 |
| last\_price       | price of the last trade, empty if there weren't any trades yet                |
| bid\_price        | current best bid price, empty if there aren't any bids                        |
| bid\_amount       | current best bid amount, empty if there aren't any bids                       |
| bid\_iv           | implied volatility for best bid, empty if there aren't any bids               |
| ask\_price        | current best ask price, empty if there aren't any asks                        |
| ask\_amount       | current best ask amount, empty if there aren't any asks                       |
| ask\_iv           | implied volatility for best ask, empty if there aren't any asks               |
| mark\_price       | mark price, empty if exchange does not provide one                            |
| mark\_iv          | implied volatility for mark price, empty if exchange does not provide one     |
| underlying\_index | underlying index name that option contract is based upon                      |
| underlying\_price | underlying price, empty if exchange does not provide one                      |
| delta             | delta value for the option, empty if exchange does not provide one            |
| gamma             | gamma value for the option, empty if exchange does not provide one            |
| vega              | vega value for the option, empty if exchange does not provide one             |
| theta             | theta value for the option, empty if exchange does not provide one            |
| rho               | rho value for the option, empty if exchange does not provide one              |
| {% endtab %}      |                                                                               |

{% tab title="dataset preview" %}

| exchange      | symbol            | timestamp        | local\_timestamp | type | strike\_price | expiration       | open\_interest | last\_price | bid\_price | bid\_amount | bid\_iv | ask\_price | ask\_amount | ask\_iv | mark\_price | mark\_iv | underlying\_index | underlying\_price | delta    | gamma   | vega    | theta     | rho      |
| ------------- | ----------------- | ---------------- | ---------------- | ---- | ------------- | ---------------- | -------------- | ----------- | ---------- | ----------- | ------- | ---------- | ----------- | ------- | ----------- | -------- | ----------------- | ----------------- | -------- | ------- | ------- | --------- | -------- |
| deribit       | BTC-9JUN20-9875-P | 1591574399413000 | 1591574400196008 | put  | 9875          | 1591689600000000 | 0.1            | 0.0295      | 0.0205     | 15.0        | 55.91   | 0.0235     | 15.0        | 68.94   | 0.02210436  | 62.89    | SYN.BTC-9JUN20    | 9756.36           | -0.61752 | 0.00103 | 2.24964 | -53.05655 | -0.22796 |
| deribit       | BTC-9JUN20-9875-P | 1591574404454000 | 1591574404473112 | put  | 9875          | 1591689600000000 | 0.1            | 0.0295      | 0.0205     | 15.0        | 55.91   | 0.0235     | 15.0        | 68.94   | 0.02209480  | 62.86    | SYN.BTC-9JUN20    | 9756.37           | -0.61757 | 0.00103 | 2.24954 | -53.02754 | -0.22798 |
| {% endtab %}  |                   |                  |                  |      |               |                  |                |             |            |             |         |            |             |         |             |          |                   |                   |          |         |         |           |          |
| {% endtabs %} |                   |                  |                  |      |               |                  |                |             |            |             |         |            |             |         |             |          |                   |                   |          |         |         |           |          |

{% embed url="<https://datasets.tardis.dev/v1/deribit/options_chain/2020/03/01/OPTIONS.csv.gz>" %}
Deribit options chain for 2020-03-01
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/okex-options/options_chain/2020/03/01/OPTIONS.csv.gz>" %}
OKX options chain for 2020-03-01
{% endembed %}

## quotes

Top of the book (best bid/ask) data reconstructed from exchanges' [real-time WebSocket](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) order book L2 data feeds, with best bid/ask recorded every time the top of the book changes.

We on purpose choose this solution over native exchanges real-time quotes feeds as those vary a lot between exchanges, can be throttled, some are absent at all, often are delayed and published in batches in comparison to more granular L2 updates which are the basis for our quotes dataset.

{% tabs %}
{% tab title="CSV quotes schema" %}

| column name      | description                                                                                                                                     |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| exchange         | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                       |
| symbol           | instrument symbol as provided by exchange (always uppercase)                                                                                    |
| timestamp        | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback |
| local\_timestamp | message arrival timestamp in **microseconds since epoch**                                                                                       |
| ask\_amount      | best ask amount as provided by exchange, empty if there aren't any asks                                                                         |
| ask\_price       | best ask price as provided by exchange, empty if there aren't any asks                                                                          |
| bid\_price       | best bid price as provided by exchange, empty if there aren't any bids                                                                          |
| bid\_amount      | best bid amount as provided by exchange, empty if there aren't any bids                                                                         |
| {% endtab %}     |                                                                                                                                                 |

{% tab title="dataset preview" %}

| exchange      | symbol  | timestamp        | local\_timestamp | ask\_amount | ask\_price | bid\_price | bid\_amount |
| ------------- | ------- | ---------------- | ---------------- | ----------- | ---------- | ---------- | ----------- |
| huobi-dm-swap | BTC-USD | 1585699201147000 | 1585699201270777 | 86          | 6423       | 6422.9     | 112         |
| huobi-dm-swap | BTC-USD | 1585699201175000 | 1585699201292111 | 86          | 6423       | 6422.9     | 114         |
| {% endtab %}  |         |                  |                  |             |            |            |             |
| {% endtabs %} |         |                  |                  |             |            |            |             |

{% embed url="<https://datasets.tardis.dev/v1/huobi-dm-swap/quotes/2020/05/01/BTC-USD.csv.gz>" %}
HTX Coin-M Perpetual BTC-USD quotes for 2020-05-01
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/deribit/quotes/2020/05/01/OPTIONS.csv.gz>" %}
Deribit OPTIONS instruments quotes for 2020-05-01
{% endembed %}

## book\_ticker

Top of the book (best bid/ask) data collected directly from exchanges' [real-time WebSocket](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) best bid/offer channels (e.g., Binance `bookTicker`, Bybit `orderbook.1`). Unlike [quotes](#quotes) which are derived from L2 order book data, `book_ticker` is sourced from the native exchange-provided WebSocket best bid/offer feed.

[See details](/faq/data#which-exchanges-support-book_ticker-data-type) which exchanges support it and since when.

{% tabs %}
{% tab title="CSV book\_ticker schema" %}

| column name      | description                                                                                                                                     |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| exchange         | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                       |
| symbol           | instrument symbol as provided by exchange (always uppercase)                                                                                    |
| timestamp        | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback |
| local\_timestamp | message arrival timestamp in **microseconds since epoch**                                                                                       |
| ask\_amount      | best ask amount, empty if there aren't any asks                                                                                                 |
| ask\_price       | best ask price, empty if there aren't any asks                                                                                                  |
| bid\_price       | best bid price, empty if there aren't any bids                                                                                                  |
| bid\_amount      | best bid amount, empty if there aren't any bids                                                                                                 |
| {% endtab %}     |                                                                                                                                                 |

{% tab title="dataset preview" %}

| exchange      | symbol  | timestamp        | local\_timestamp | ask\_amount | ask\_price | bid\_price | bid\_amount |
| ------------- | ------- | ---------------- | ---------------- | ----------- | ---------- | ---------- | ----------- |
| binance       | BTCUSDT | 1704067200002131 | 1704067200002131 | 2.79269     | 42283.59   | 42283.58   | 9.07348     |
| binance       | BTCUSDT | 1704067200009508 | 1704067200009508 | 2.79064     | 42283.59   | 42283.58   | 9.07348     |
| {% endtab %}  |         |                  |                  |             |            |            |             |
| {% endtabs %} |         |                  |                  |             |            |            |             |

{% embed url="<https://datasets.tardis.dev/v1/binance/book_ticker/2024/01/01/BTCUSDT.csv.gz>" %}
Binance BTCUSDT book ticker for 2024-01-01
{% endembed %}

## derivative\_ticker

Derivative instrument ticker info (open interest, funding, mark price, index price) collected from exchanges' [real-time WebSocket](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) instruments & tickers data feeds.

Anytime any of the tracked values has changed data was added to final dataset.

Funding fields describe upcoming funding events relative to the message timestamp. `funding_timestamp` is the next funding event time: the immediately upcoming event, not a previously settled funding time. `funding_rate` is the rate for that next event and can change until the event occurs. `predicted_funding_rate`, when present, estimates the following funding event.

{% tabs %}
{% tab title="CSV derivative\_ticker schema" %}

| column name              | description                                                                                                                                                                                                                           |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| exchange                 | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                                                                                                             |
| symbol                   | instrument symbol as provided by exchange (always uppercase)                                                                                                                                                                          |
| timestamp                | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback                                                                                       |
| local\_timestamp         | message arrival timestamp in **microseconds since epoch**                                                                                                                                                                             |
| funding\_timestamp       | timestamp of the next funding event in **microseconds since epoch**, empty if exchange does not provide one                                                                                                                           |
| funding\_rate            | funding rate for the next funding event — this value can fluctuate until the event occurs; the final value just before `funding_timestamp`, when provided, is the one applied by the exchange. Empty if exchange does not provide one |
| predicted\_funding\_rate | estimated funding rate for the following funding event after the next one, empty if exchange does not provide one                                                                                                                     |
| open\_interest           | current open interest, empty if exchange does not provide one                                                                                                                                                                         |
| last\_price              | last instrument price, empty if exchange does not provide one                                                                                                                                                                         |
| index\_price             | index price of the instrument, empty if exchange does not provide one                                                                                                                                                                 |
| mark\_price              | mark price of the instrument, empty if exchange does not provide one                                                                                                                                                                  |
| {% endtab %}             |                                                                                                                                                                                                                                       |

{% tab title="dataset preview" %}

| exchange      | symbol | timestamp        | local\_timestamp | funding\_timestamp | funding\_rate | predicted\_funding\_rate | open\_interest | last\_price | index\_price | mark\_price |
| ------------- | ------ | ---------------- | ---------------- | ------------------ | ------------- | ------------------------ | -------------- | ----------- | ------------ | ----------- |
| bitmex        | ETHUSD | 1585699199651000 | 1585699202577291 | 1585713600000000   | 0.0001        | 0.001654                 | 45921455       | 133.25      | 133.14       | 133.15      |
| bitmex        | ETHUSD | 1585699200000000 | 1585699204834359 | 1585713600000000   | 0.0001        | 0.001654                 | 45921455       | 133.25      | 133.12       | 133.13      |
| {% endtab %}  |        |                  |                  |                    |               |                          |                |             |              |             |
| {% endtabs %} |        |                  |                  |                    |               |                          |                |             |              |             |

{% embed url="<https://datasets.tardis.dev/v1/bitmex/derivative_ticker/2019/04/01/ETHUSD.csv.gz>" %}
BitMEX ETHUSD derivative ticker for 2019-04-01
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/ftx/derivative_ticker/2020/06/01/PERPETUALS.csv.gz>" %}
FTX PERPETUALS instruments derivative ticker for 2020-06-01
{% endembed %}

## liquidations

Liquidations data collected from exchanges' [real-time WebSocket data feeds](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints) where available.

[See details](/faq/data#which-exchanges-support-liquidations-data-type) which exchanges support it and since when.

{% tabs %}
{% tab title="CSV liquidations schema" %}

| column name      | description                                                                                                                                                                                                           |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| exchange         | exchange id, one of <https://api.tardis.dev/v1/exchanges> (`[].id` field)                                                                                                                                             |
| symbol           | instrument symbol as provided by exchange (always uppercase)                                                                                                                                                          |
| timestamp        | timestamp provided by exchange in **microseconds since epoch** - if exchange does not provide one `local_timestamp` value is used as a fallback                                                                       |
| local\_timestamp | message arrival timestamp in **microseconds since epoch**                                                                                                                                                             |
| id               | liquidation id as provided by exchange, empty if exchange does not provide one - different exchanges provide id's as numeric values, GUID's or other strings, and some do not provide that information at all         |
| side             | <p>liquidation side, possible values:<br><code>buy</code> - short position was liquidated<br><code>sell</code> - long position was liquidated<br><code>unknown</code> - exchange did not provide that information</p> |
| price            | liquidation price as provided by exchange                                                                                                                                                                             |
| amount           | liquidation amount as provided by exchange                                                                                                                                                                            |
| {% endtab %}     |                                                                                                                                                                                                                       |

{% tab title="dataset preview" %}

| exchange        | symbol  | timestamp        | local\_timestamp | id | side | price    | amount |
| --------------- | ------- | ---------------- | ---------------- | -- | ---- | -------- | ------ |
| binance-futures | BTCUSDT | 1632009737493000 | 1632009737505152 |    | sell | 48283.81 | 0.01   |
| binance-futures | BTCUSDT | 1632009802385000 | 1632009802398690 |    | buy  | 48339.11 | 0.132  |
| {% endtab %}    |         |                  |                  |    |      |          |        |
| {% endtabs %}   |         |                  |                  |    |      |          |        |

{% embed url="<https://datasets.tardis.dev/v1/ftx/liquidations/2021/09/01/PERPETUALS.csv.gz>" %}
FTX perpetual futures liquidations for 2021-09-01
{% endembed %}

{% embed url="<https://datasets.tardis.dev/v1/bitmex/liquidations/2021/09/01/XBTUSD.csv.gz>" %}
BitMEX XBTUSD liquidations for 2021-09-01
{% endembed %}


# API Reference

Endpoints, path parameters, authentication and sample requests

## Datasets API details

The Datasets API serves gzip-compressed CSV files by day, exchange, data type and symbol.

* all downloadable datasets are gzip-compressed
* historical market data is available as one file per day, split by exchange, [data type](/downloadable-csv-files/data-types) and symbol
* data for a given day is available on the next day around 06:00 UTC; use the [`/exchanges/:exchange`](/api/http-api-reference#exchanges-exchange) API endpoint and `datasets.exportedUntil` to check exact export status
* datasets are ordered and split into daily files by [`local_timestamp`](/faq/data#how-are-market-data-messages-timestamped)
* an empty gzip file is returned when no data is available for a given day, symbol and data type, for example during exchange downtime or for very low volume markets
* if `timestamp` equals `local_timestamp`, the exchange did not provide a timestamp for the message, for example BitMEX order book updates
* a CSV cell is empty when the exchange does not provide that value, for example a missing trade ID
* datasets are exported from Tardis.dev's collected [raw WebSocket data](/faq/data#why-data-source-matters-websocket-feeds-vs-rest-endpoints), not exchange REST endpoints. The same raw data is available in exchange-native format via the [HTTP API](/api/http-api-reference)
* disconnect events are not included in CSV datasets — they are available via the [raw HTTP API](/api/http-api-reference) (as empty lines) and via [normalized replay](https://docs.tardis.dev/downloadable-csv-files/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) with `withDisconnectMessages` enabled
* dataset download responses for Pro and Business subscriptions (premium network) include an `x-md5` header, but for large files uploaded in chunks this value may not match a full-file MD5 checksum — use file size and gzip decompression success as primary integrity checks
* CSV datasets for a given day are typically available by 06:00 UTC the next day. To check the exact export status for an exchange, use the [`/exchanges/:exchange`](/api/http-api-reference#exchanges-exchange) API endpoint and poll the `datasets.exportedUntil` field — do not rely on wall-clock time alone
* See ["Data FAQ"](/faq/data) regarding [potential order book overlaps](/faq/order-books#can-reconstructed-order-books-have-bid-ask-overlap), [non-monotonically increasing exchange timestamps](/faq/data#can-timestamps-be-non-monotonic-within-a-channel), [duplicated trade data](/faq/data#are-exchanges-publishing-duplicated-trades-data-messages), and more

## Download via client libraries

{% hint style="info" %}
Historical datasets for the first day of each month are available to download without API key.
{% endhint %}

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

```python
# pip install tardis-dev
# requires Python >=3.9
from tardis_dev import download_datasets, get_exchange_details
import logging
import re

# comment out to disable debug logs
logging.basicConfig(level=logging.DEBUG)

# function used by default if not provided via options
def default_file_name(exchange, data_type, date, symbol, format):
    sanitized_symbol = re.sub(r'[:\\/?*<>|"]', "-", symbol)
    return f"{exchange}_{data_type}_{date.strftime('%Y-%m-%d')}_{sanitized_symbol}.{format}.gz"


# customized get filename function - saves data in nested directory structure
def file_name_nested(exchange, data_type, date, symbol, format):
    sanitized_symbol = re.sub(r'[:\\/?*<>|"]', "-", symbol)
    return f"{exchange}/{data_type}/{date.strftime('%Y-%m-%d')}_{sanitized_symbol}.{format}.gz"


# returns data available at https://api.tardis.dev/v1/exchanges/deribit
deribit_details = get_exchange_details("deribit")
# print(deribit_details)

download_datasets(
    # one of https://api.tardis.dev/v1/exchanges with supportsDatasets:true - use 'id' value
    exchange="deribit",
    # accepted data types - 'datasets.symbols[].dataTypes' field in https://api.tardis.dev/v1/exchanges/deribit,
    # or get those values from 'deribit_details["datasets"]["symbols"][i]["dataTypes"]' above
    data_types=["incremental_book_L2", "trades", "quotes", "derivative_ticker", "book_snapshot_25", "book_snapshot_5", "liquidations"],
    # change date ranges as needed to fetch full month or year for example
    from_date="2019-11-01",
    # to date is non inclusive
    to_date="2019-11-02",
    # accepted values: 'datasets.symbols[].id' field in https://api.tardis.dev/v1/exchanges/deribit
    symbols=["BTC-PERPETUAL", "ETH-PERPETUAL",],
    # (optional) your API key to get access to non sample data as well
    api_key="YOUR API KEY",
    # (optional) path where data will be downloaded into, default dir is './datasets'
    # download_dir="./datasets",
    # (optional) - one can customize downloaded file name/path (flat dir structure, or nested etc) - by default function 'default_file_name' is used
    # get_filename=default_file_name,
    # (optional) file_name_nested will download data to nested directory structure (split by exchange and data type)
    # get_filename=file_name_nested,
)
```

{% hint style="info" %}
If you're running into `RuntimeError: download_datasets() cannot be called from a running event loop`, use `download_datasets_async()` instead.
{% endhint %}
{% endtab %}

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

```javascript
// npm install tardis-dev
// requires Node.js v24+

// remove it to disable debug logs
process.env.DEBUG = 'tardis-dev*'

import { downloadDatasets, getExchangeDetails } from 'tardis-dev'

// returns data available at https://api.tardis.dev/v1/exchanges/deribit
const deribitDetails = await getExchangeDetails('deribit')

// console.log(deribitDetails.datasets)

await downloadDatasets({
  exchange: 'deribit', // one of https://api.tardis.dev/v1/exchanges with supportsDatasets:true - use 'id' value
  dataTypes: ['incremental_book_L2', 'trades', 'quotes', 'derivative_ticker', 'book_snapshot_25', 'book_snapshot_5', 'liquidations'], // accepted data types - 'datasets.symbols[].dataTypes' field in https://api.tardis.dev/v1/exchanges/deribit, or get those values from 'deribitDetails.datasets.symbols[].dataTypes' object above
  from: '2019-11-01', // change date ranges as needed to fetch full month or year for example
  to: '2019-11-02', // to date is non inclusive
  symbols: ['BTC-PERPETUAL', 'ETH-PERPETUAL'], // accepted values: 'datasets.symbols[].id' field in https://api.tardis.dev/v1/exchanges/deribit, or `deribitDetails.datasets.symbols[].id` from object above

  apiKey: 'YOUR_API_KEY', // (optional) your API key to get access to non sample data as well
  // downloadDir:'./datasets', // (optional) path where data will be downloaded into, default dir is './datasets'

  // getFilename: getFilenameDefault, // (optional) - one can customize downloaded file name/path (flat dir structure, or nested etc) - by default function 'getFilenameDefault' is used
  // getFilename: getFilenameCustom // (optional) getFilenameCustom will download data to nested directory structure (split by exchange and data type)
})

// function used by default if not provided via options
function sanitizeForFilename(value) {
  return value.replace(/[:\\/?*<>|"]/g, '-')
}

function getFilenameDefault({ exchange, dataType, format, date, symbol }) {
  return `${exchange}_${dataType}_${date.toISOString().split('T')[0]}_${sanitizeForFilename(symbol)}.${format}.gz`
}

// customized get filename function - saves data in nested directory structure
function getFilenameCustom({ exchange, dataType, format, date, symbol }) {
  return `${exchange}/${dataType}/${date.toISOString().split('T')[0]}_${sanitizeForFilename(symbol)}.${format}.gz`
}
```

{% endtab %}
{% endtabs %}

## Datasets API reference

<mark style="color:blue;">`GET`</mark> `https://datasets.tardis.dev/v1/:exchange/:dataType/:year/:month/:day/:symbol.csv.gz`

Returns gzip compressed CSV dataset for given exchange, data type, date (year, month, day) and symbol.

#### Path Parameters

| Name     | Type   | Description                                                                                                                |
| -------- | ------ | -------------------------------------------------------------------------------------------------------------------------- |
| exchange | string | one of <https://api.tardis.dev/v1/exchanges> (field `id`, only exchanges with "supportsDatasets":true)                     |
| dataType | string | one of `datasets.symbols[].dataTypes` values from <https://api.tardis.dev/v1/exchanges/:exchange> API response             |
| year     | string | year in format `YYYY` (four-digit year)                                                                                    |
| month    | string | month in format `MM` (two-digit month of the year)                                                                         |
| day      | string | day in format `DD` (two-digit day of the month)                                                                            |
| symbol   | string | one of `datasets.symbols[].id` values from <https://api.tardis.dev/v1/exchanges/:exchange> API response, see details below |

#### Headers

| Name          | Type   | Description                                                                                                                                                                                                        |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Authorization | string | <p>For authenticated requests provide Authorization header with value: '<code>Bearer YOUR\_API\_KEY</code>'.<br>Without API key historical datasets for the first day of each month are available to download.</p> |

{% tabs %}
{% tab title="200 gzip compressed CSV dataset" %}

```
```

{% endtab %}
{% endtabs %}

* `symbol` values for the datasets API are CSV dataset symbols, not raw replay symbols. Use `datasets.symbols[].id` from `/exchanges/:exchange` or `datasetId` from the Instruments Metadata API when present. If an instrument has no `datasetId`, the symbol has not appeared in exported dataset metadata yet. Dataset symbols are uppercase and have `/` and `:` replaced with `-`; they can still contain non-ASCII or reserved URL characters, so URL-encode the symbol path segment when constructing URLs manually. Official clients do this automatically.
* list of allowed symbols for each exchange can be requested via [/exchanges/:exchange](/api/http-api-reference#exchanges-exchange) API call, e.g., <https://api.tardis.dev/v1/exchanges/deribit> - `datasets.symbols[].id` field

#### Sample requests

{% embed url="<https://datasets.tardis.dev/v1/deribit/trades/2019/11/01/BTC-PERPETUAL.csv.gz>" %}

{% embed url="<https://datasets.tardis.dev/v1/deribit/trades/2019/11/01/OPTIONS.csv.gz>" %}

{% embed url="<https://datasets.tardis.dev/v1/bitmex/incremental_book_L2/2020/04/01/XBTUSD.csv.gz>" %}

{% embed url="<https://datasets.tardis.dev/v1/deribit/options_chain/2019/08/01/OPTIONS.csv.gz>" %}

{% embed url="<https://datasets.tardis.dev/v1/deribit/book_snapshot_25/2020/08/01/BTC-PERPETUAL.csv.gz>" %}

{% embed url="<https://datasets.tardis.dev/v1/deribit/quotes/2019/08/01/OPTIONS.csv.gz>" %}


# Quickstart

Python, Node.js, HTTP API and tardis-machine — choose the right access method

![](/files/-M2YHQIWeen4ilstSXH-)

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="image"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Python Client</strong></td><td><code>tardis-dev</code> package for historical replay, CSV dataset downloads and exchange metadata.</td><td><a href="/files/fwKsQX4uIbv2wUIH9n71">/files/fwKsQX4uIbv2wUIH9n71</a></td><td><a href="/pages/6bEFe9Ft9ydP9Y6G2duh">/pages/6bEFe9Ft9ydP9Y6G2duh</a></td></tr><tr><td><strong>Node.js Client</strong></td><td>Historical replay, real-time streaming, data normalization and order book reconstruction.</td><td><a href="/files/J0R201zWBPSO2z7NTAxA">/files/J0R201zWBPSO2z7NTAxA</a></td><td><a href="/pages/leQNz2TtJHmfiyqrhBtJ">/pages/leQNz2TtJHmfiyqrhBtJ</a></td></tr><tr><td><strong>Tardis Machine</strong></td><td>Locally runnable server with HTTP and WebSocket APIs — replay and real-time streaming with built-in caching.</td><td><a href="/files/5SFK0FRJpMyUh0mfihfo">/files/5SFK0FRJpMyUh0mfihfo</a></td><td><a href="/pages/LcZWZM0iiWGvamgYTat0">/pages/LcZWZM0iiWGvamgYTat0</a></td></tr><tr><td><strong>HTTP API</strong></td><td>Raw historical market data feeds in minute-by-minute NDJSON slices in exchange-native format.</td><td><a href="/files/SNILkT6y38y38KTdFqGk">/files/SNILkT6y38y38KTdFqGk</a></td><td><a href="/pages/-LrIXbMvpl-ph6O72lHH">/pages/-LrIXbMvpl-ph6O72lHH</a></td></tr></tbody></table>

{% hint style="info" %}
**C++, Java, Rust, C#, Go and R** — use [HTTP API](/api/http-api-reference) directly, connect to [tardis-machine](/tardis-machine/quickstart) HTTP/WebSocket endpoints, or [download CSV datasets](/downloadable-csv-files/overview). [Contact us](https://tardis.dev/#contact) if you need help with integration.
{% endhint %}

{% hint style="info" %}
See [downloadable CSV files docs](/downloadable-csv-files/overview) if you'd like to access historical CSV datasets with normalized data.
{% endhint %}


# Instruments Metadata API

Tick sizes, contract multipliers, base/quote currencies and expiration dates

Use the Instruments Metadata API to discover exchange-native symbol IDs and instrument details for replay, streaming, and CSV dataset workflows. It is most useful when you know the market shape you need, such as active BTC/USDT linear perpetuals or Deribit BTC options available during a historical replay window, but do not want to hardcode every exchange's symbol format.

Instrument fields such as symbol IDs, trading status, currencies, tick sizes, listing time, expiry and underlying asset class are sourced from exchange metadata APIs and normalized by Tardis where needed. `availableSince`, `availableTo` and `datasetId` are Tardis-side availability fields: when a symbol has appeared in exported metadata they reflect exported symbol state, while newly discovered active instruments can appear before replay or CSV dataset availability has caught up.

{% hint style="info" %}
Most Instruments Metadata API requests require an active [pro or business](/faq/billing-and-subscriptions#what-are-the-differences-between-subscription-types) subscription. BitMEX metadata is available without an API key for quick testing.
{% endhint %}

## Authorization

Provide the `Authorization` header with your API key:

```http
Authorization: Bearer YOUR_API_KEY
```

## Get one instrument

Returns one instrument for the provided exchange and symbol.

Use the `id` returned by the list endpoint as the symbol path segment. URL-encode the symbol when constructing URLs manually, especially for symbols that contain `/`, `:` or other reserved characters. The lookup is case-insensitive for the canonical symbol ID, while the response returns the exchange API symbol casing.

### Endpoint URL

<https://api.tardis.dev/v1/instruments/:exchange/:symbol_id>

### Example URLs

* <https://api.tardis.dev/v1/instruments/bitmex/XBTUSD>
* <https://api.tardis.dev/v1/instruments/okex-swap/BTC-USDT-SWAP>

### Response Format

{% hint style="info" %}
`changes` is complete only for `contractMultiplier` updates that we track from exchange announcements. Other changed fields are included on a best-effort basis and may not cover every historical change.
{% endhint %}

```typescript
{
	id: string // exchange-native symbol id, returned in exchange API casing
	datasetId?: string // CSV dataset symbol id; present after the symbol appears in exported dataset metadata
	exchange: string // exchange id
	baseCurrency: string // normalized, so for example bitmex XBTUSD has base currency set to BTC not XBT
	quoteCurrency: string // normalized, so for example bitfinex BTCUST has quote currency set to USDT, not UST
	type: InstrumentType
	contractType?: ContractType // only for derivatives, detailed contract type
	active: boolean // exchange-reported current trading status
	availableSince: string // Tardis metadata availability day; may differ from exchange listing time and dataset availability
	availableTo?: string // last UTC Tardis availability boundary, when known
	listing?: string // exchange listing timestamp in ISO format, if known
	expiry?: string // in ISO format, only for futures and options
	expirationType?: 'daily' | 'weekly' | 'next_week' | 'quarter' | 'next_quarter' // expiration schedule type
	underlyingIndex?: string // the underlying index for derivatives
	underlyingType?: UnderlyingType // underlying asset class; omitted for options and predictions
	priceIncrement: number // price tick size, price precision can be calculated from it
	amountIncrement: number // amount tick size, amount/size precision can be calculated from it
	minTradeAmount: number // min order size
	minNotional?: number // minimum order notional value, when separately exposed by the exchange
	makerFee: number // consider it as illustrative only, as it depends in practice on account traded volume levels, different categories, VIP levels, owning exchange currency etc
	takerFee: number // consider it as illustrative only, as it depends in practice on account traded volume levels, different categories, VIP levels, owning exchange currency etc
	inverse?: boolean // only for derivatives
	contractMultiplier?: number // only for derivatives
	quanto?: boolean // set to true for quanto instruments, otherwise undefined
	settlementCurrency?: string // settlement currency, only for quanto instruments as it has different base/quote currency
	strikePrice?: number // strike price, only for options
	optionType?: 'call' | 'put' // option type, only for options
	marginMode?: 'isolated' | 'cross' // margin mode
	margin?: boolean // whether margin trading is supported (spot)
	aliasFor?: string // if this instrument is an alias for another

	changes?: {
		until: string // date in ISO format
		priceIncrement?: number
		amountIncrement?: number
		contractMultiplier?: number
		minTradeAmount?: number
		minNotional?: number
		makerFee?: number
		takerFee?: number
		quanto?: boolean
		inverse?: boolean
		settlementCurrency?: string
		underlyingIndex?: string
		underlyingType?: UnderlyingType
		contractType?: ContractType
		expiry?: string
		quoteCurrency?: string
		type?: string
	}[]
}

// where InstrumentType is one of:
type InstrumentType =
	| "spot" | "perpetual" | "future" | "option" | "combo" | "prediction"

// where ContractType is one of:
type ContractType =
	| "move" | "linear_future" | "inverse_future" | "quanto_future"
	| "linear_perpetual" | "inverse_perpetual" | "quanto_perpetual"
	| "put_option" | "call_option" | "turbo_put_option" | "turbo_call_option"
	| "spread" | "interest_rate_swap" | "repo" | "index"
	| "linear_xperp" | "inverse_xperp"

// where UnderlyingType is one of:
type UnderlyingType =
	| "native" | "equity" | "commodity" | "fixed_income"
	| "fx" | "index" | "pre_market"
```

{% hint style="info" %}
`underlyingType` is returned for active/current instruments that have an exchange-sourced underlying asset class. Crypto-native instruments default to `native`; exchange-sourced non-native classifications such as `equity`, `commodity`, `fx`, `index`, `fixed_income`, and `pre_market` are returned when available. Older historical or delisted instruments may not have `underlyingType`. Options omit `underlyingType` to keep large options metadata responses compact. Prediction instruments omit `underlyingType`.

`minNotional` is returned only when the exchange exposes a minimum order value or notional separately from minimum order quantity.
{% endhint %}

{% hint style="info" %}
**`changes` field semantics:**

* The `changes` array is sorted chronologically by `until` (ascending). Each entry records field values that were valid **before** the `until` date — i.e., the values changed at `until`.
* Only `contractMultiplier` changes are guaranteed to be accurate and complete (monitored from exchange announcements). Other field changes, including `priceIncrement`, `amountIncrement`, `underlyingType` and `expiry`, are tracked on a best-effort basis.
* Changes are filtered to the instrument's `availableSince`—`availableTo` range.
  {% endhint %}

{% hint style="info" %}
**Lifecycle field semantics:**

* `active` — reflects the exchange-reported current trading status. It does not guarantee that Tardis already has replay data, CSV datasets, or non-empty data for every channel and date.
* `availableSince` — the Tardis metadata availability day, not necessarily the exact exchange listing time. When the symbol has appeared in exported metadata, this reflects the first exported UTC day we know for the symbol. For newly discovered instruments that have not appeared in exported metadata yet, it can be metadata-only/provisional. Use `listing` for the exchange listing timestamp when available.
* `datasetId` — the CSV dataset symbol ID. It is omitted until the symbol appears in exported dataset metadata. Use its presence, or `/exchanges/:exchange` `datasets.symbols[]`, to identify symbols for direct CSV downloads. It does not guarantee that every data type or date has a non-empty CSV file.
* `availableTo` — the UTC boundary where the instrument stops being available in Tardis metadata or exported symbol state, such as after expiry or delisting. It is absent for instruments that are still available and may lag behind the actual exchange delisting.
* `expiry` — current exchange-provided contract expiry for futures and options. It is not the same as `availableTo`; when a changed value was observed, the previous value may be available in `changes[].expiry`.
* Some exchanges reuse symbol IDs or maintain alias/legacy symbols alongside active ones. Both may appear in metadata results — use `active` to distinguish currently tradable instruments.
  {% endhint %}

### Sample Response

```javascript
{
  "id": "XBTUSD",
  "datasetId": "XBTUSD",
  "exchange": "bitmex",
  "baseCurrency": "BTC",
  "quoteCurrency": "USD",
  "type": "perpetual",
  "active": true,
  "availableSince": "2019-03-30T00:00:00.000Z",
  "priceIncrement": 0.5,
  "amountIncrement": 1,
  "minTradeAmount": 1,
  "makerFee": -0.00025,
  "takerFee": 0.00075,
  "inverse": true,
  "contractType": "inverse_perpetual",
  "contractMultiplier": 1
}
```

## List and filter instruments

Returns instruments for one exchange, optionally narrowed by a URL-encoded JSON `filter` query parameter.

Use this endpoint to find symbols for replay, streaming, and historical availability checks. Broad unfiltered responses can be large for options-heavy exchanges, so prefer filters when you know the market you need.

### Endpoint URL

[https://api.tardis.dev/v1/instruments/:exchange?filter={filter\_payload}](https://api.tardis.dev/v1/instruments/:exchange?filter=%7Bfilter_payload%7D)

### Example URLs

* <https://api.tardis.dev/v1/instruments/bitmex>
* [https://api.tardis.dev/v1/instruments/okex-futures?filter={"baseCurrency":"BTC","active":true}](https://api.tardis.dev/v1/instruments/okex-futures?filter=%7B%22baseCurrency%22:%22BTC%22,%22active%22:true%7D)
* [https://api.tardis.dev/v1/instruments/bitmex?filter={"baseCurrency":"BTC","quoteCurrency":\["USD","USDT"\],"type":"perpetual"}](https://api.tardis.dev/v1/instruments/bitmex?filter=%7B%22baseCurrency%22:%22BTC%22,%22quoteCurrency%22:%5B%22USD%22,%22USDT%22%5D,%22type%22:%22perpetual%22%7D)
* [https://api.tardis.dev/v1/instruments/binance-futures?filter={"underlyingType":"commodity","type":"perpetual","active":true}](https://api.tardis.dev/v1/instruments/binance-futures?filter=%7B%22underlyingType%22:%22commodity%22,%22type%22:%22perpetual%22,%22active%22:true%7D)
* [https://api.tardis.dev/v1/instruments/deribit?filter={"baseCurrency":"BTC","type":"option","availableSince":"2024-01-01","availableTo":"2024-01-02"}](https://api.tardis.dev/v1/instruments/deribit?filter=%7B%22baseCurrency%22:%22BTC%22,%22type%22:%22option%22,%22availableSince%22:%222024-01-01%22,%22availableTo%22:%222024-01-02%22%7D)

### Optional Filter Object

Provide `filter` as a JSON object. When used in a query string, it must be URL-encoded.

```typescript
{
	baseCurrency: string | string[] | undefined // normalized base currency, e.g. BTC
	quoteCurrency: string | string[] | undefined // normalized quote currency, e.g. USDT
	type: InstrumentType | InstrumentType[] | undefined
	contractType: ContractType | ContractType[] | undefined
	underlyingType: UnderlyingType | UnderlyingType[] | undefined
	active: boolean | undefined // true for currently tradable instruments, false for inactive instruments
	availableSince: string | undefined // UTC collection day; include instruments available at or after this day
	availableTo: string | undefined // UTC collection day boundary; with availableSince, include instruments whose availability overlaps the interval
}
```

{% hint style="info" %}
**Availability filters:**

* `availableSince` alone returns instruments whose Tardis availability reaches this UTC day or any later day.
* `availableTo` alone returns instruments available on that UTC day.
* `availableSince` and `availableTo` together return instruments whose Tardis availability overlaps the requested UTC-day interval. Use this for historical replay windows. The interval end is exclusive.
* The returned `availableTo` field is still the instrument's collection end date. It is not a simple "ended before" filter.
* When you need confirmed raw replay symbols or CSV dataset symbols, check [Exchange details](/api/http-api-reference#exchanges-exchange): use `availableSymbols` for raw replay and `datasets.symbols` for CSV downloads.
  {% endhint %}

### Filter Limits

* Each array filter accepts up to 50 values.
* String filter values must be between 1 and 150 characters.
* `type`, `contractType`, and `underlyingType` must use the allowed enum values documented above.
* The full request URL must be 12000 characters or shorter.

### Sample Request in JavaScript

```javascript
const filter = {
  baseCurrency: 'BTC',
  quoteCurrency: ['USD', 'USDT'],
  type: 'perpetual'
}

const headers = {
  Authorization: 'Bearer YOUR_API_KEY'
}

const url = new URL('https://api.tardis.dev/v1/instruments/bitmex')
url.searchParams.set('filter', JSON.stringify(filter))

const response = await fetch(url, { headers })
const instruments = await response.json()
```

### Response Format

Array of instruments objects as described for single instrument endpoint

## Client helpers for symbol discovery

Client helpers find exchange-specific instrument symbol IDs from normalized market criteria, so you do not have to hardcode each exchange's symbol format. They use the Instruments Metadata API to return the correct `id` for each requested exchange, ready to pass to replay, streaming, or raw data feeds.

Returned `id` symbols are exchange-provided IDs and are not normalized by the clients. Returned `datasetId` symbols are CSV dataset IDs for instruments whose symbols appear in exported dataset metadata; official clients URL-encode them when downloading datasets. If you construct dataset URLs manually, URL-encode the symbol path segment.

{% tabs %}
{% tab title="Node.js" %}
Find active BTC/USDT linear perpetuals across exchanges with different native symbol formats.

```javascript
import { findInstrumentSymbols, init } from 'tardis-dev'

init({ apiKey: 'YOUR_API_KEY' })

const symbolsByExchange = await findInstrumentSymbols(['bitmex', 'binance-futures', 'okex-swap', 'bybit'], {
  baseCurrency: 'BTC',
  quoteCurrency: 'USDT',
  contractType: 'linear_perpetual',
  active: true
})

console.log(symbolsByExchange)
// [
//   { exchange: 'bitmex', symbols: ['XBTUSDT'] },
//   { exchange: 'binance-futures', symbols: ['btcusdt'] },
//   { exchange: 'okex-swap', symbols: ['BTC-USDT-SWAP'] },
//   { exchange: 'bybit', symbols: ['BTCUSDT'] }
// ]
```

Find active Tesla equity instruments by filtering on `underlyingType`.

```javascript
const teslaEquitySymbols = await findInstrumentSymbols(
  ['binance-futures', 'okex-swap', 'coinbase-international', 'bybit', 'bitget-futures'],
  {
    baseCurrency: 'TSLA',
    underlyingType: 'equity',
    active: true
  }
)

console.log(teslaEquitySymbols)
// [
//   { exchange: 'binance-futures', symbols: ['tslausdt'] },
//   { exchange: 'okex-swap', symbols: ['TSLA-USDT-SWAP'] },
//   { exchange: 'coinbase-international', symbols: ['TSLA-PERP'] },
//   { exchange: 'bybit', symbols: ['TSLAUSDT'] },
//   { exchange: 'bitget-futures', symbols: ['TSLAUSDT'] }
// ]
```

Use the `datasetId` selector only when you need symbols for direct CSV dataset file downloads. Instruments without `datasetId` are omitted from selector results.

```javascript
const csvSymbolsByExchange = await findInstrumentSymbols(
  ['bitmex', 'binance-futures', 'okex-swap', 'bybit'],
  {
    baseCurrency: 'BTC',
    quoteCurrency: 'USDT',
    contractType: 'linear_perpetual',
    active: true
  },
  'datasetId'
)
```

{% endtab %}

{% tab title="Python" %}
Find active BTC/USDT linear perpetuals across exchanges with different native symbol formats.

```python
from tardis_dev import find_instrument_symbols

symbols_by_exchange = find_instrument_symbols(
    ["bitmex", "binance-futures", "okex-swap", "bybit"],
    {
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "linear_perpetual",
        "active": True,
    },
    api_key="YOUR_API_KEY",
)

print(symbols_by_exchange)
# [
#   {"exchange": "bitmex", "symbols": ["XBTUSDT"]},
#   {"exchange": "binance-futures", "symbols": ["btcusdt"]},
#   {"exchange": "okex-swap", "symbols": ["BTC-USDT-SWAP"]},
#   {"exchange": "bybit", "symbols": ["BTCUSDT"]},
# ]
```

Find active Tesla equity instruments by filtering on `underlyingType`.

```python
tesla_equity_symbols = find_instrument_symbols(
    ["binance-futures", "okex-swap", "coinbase-international", "bybit", "bitget-futures"],
    {
        "baseCurrency": "TSLA",
        "underlyingType": "equity",
        "active": True,
    },
    api_key="YOUR_API_KEY",
)

print(tesla_equity_symbols)
# [
#   {"exchange": "binance-futures", "symbols": ["tslausdt"]},
#   {"exchange": "okex-swap", "symbols": ["TSLA-USDT-SWAP"]},
#   {"exchange": "coinbase-international", "symbols": ["TSLA-PERP"]},
#   {"exchange": "bybit", "symbols": ["TSLAUSDT"]},
#   {"exchange": "bitget-futures", "symbols": ["TSLAUSDT"]},
# ]
```

Use `selector="datasetId"` only when you need symbols for direct CSV dataset file downloads. Instruments without `datasetId` are omitted from selector results.

```python
from tardis_dev import find_instrument_symbols_async

csv_symbols_by_exchange = await find_instrument_symbols_async(
    ["bitmex", "binance-futures", "okex-swap", "bybit"],
    {
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "linear_perpetual",
        "active": True,
    },
    selector="datasetId",
    api_key="YOUR_API_KEY",
)
```

{% endtab %}
{% endtabs %}


# HTTP API Reference

Historical market data feeds, exchange metadata and more

{% hint style="info" %}
Base API Endpoint: **<https://api.tardis.dev/v1>**
{% endhint %}

## /data-feeds/:exchange

<mark style="color:blue;">`GET`</mark> `https://api.tardis.dev/v1/data-feeds/:exchange`

Returns historical market data for the requested exchange as newline-delimited JSON (NDJSON). Each line starts with the local timestamp in ISO 8601 format, followed by one exchange-native JSON message.

Empty lines mark disconnect events that occurred during data collection.

Requests without a `compression` query parameter must include an `Accept-Encoding` header that allows compressed responses.

By default, `/data-feeds` returns `gzip`. To get Zstandard, set `compression=zstd` and use a client that accepts and decodes `content-encoding: zstd`. `Accept-Encoding: zstd` alone is not enough because Cloudflare normalizes that header before it reaches the Worker.

By default, each request returns one minute of historical market data starting at `from` plus the minute `offset`. Filtered requests can set `sliceSize` from `1` to `10` to return consecutive minutes in one request.

Parallel requests to this endpoint are supported. Using more than \~60 parallel requests does not improve throughput. Use HTTP/1.1; in our testing HTTP/2 was noticeably slower for this endpoint.

Official client libraries are built on top of this endpoint and handle date ranges, caching, compression and normalized data formats.

#### Path Parameters

| Name                                       | Type   | Description                                               |
| ------------------------------------------ | ------ | --------------------------------------------------------- |
| exchange<mark style="color:red;">\*</mark> | string | one of <https://api.tardis.dev/v1/exchanges> (field `id`) |

#### Query Parameters

| Name                                   | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| from<mark style="color:red;">\*</mark> | string | requested UTC start date of historical market data feed (e.g.: `2019-04-05` or `2019-04-05T01:02:00.000Z`)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| offset                                 | number | Minute offset that, together with `from`, specifies the first minute of historical data returned. For example, `from=2019-04-05`, `offset=2` and default `sliceSize=1` returns data between `2019-04-05T00:02:00.000Z` and `2019-04-05T00:03:00.000Z`. With `sliceSize` greater than `1`, the response starts at the same offset and covers consecutive minutes. Minute boundaries are based on `localTimestamp` (when we received the message), not exchange event timestamps. An empty response for a given offset is normal and means no data was recorded during that minute.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| filters                                | string | <p>URL-encoded JSON string in <code>{channel:string, symbols?: string\[]}\[]</code> format with optional historical market data filters, e.g.: <code>\[{"channel":"trade", "symbols":\["XBTUSD"]}]</code></p><p>To request all active symbols for a channel, omit <code>symbols</code> or pass an empty <code>symbols</code> array. Use this when you need the whole channel instead of sending one request per symbol.</p><p>If you need selected symbols, put them in one <code>symbols</code> array. One filter can include up to 50 symbols.</p><p>Symbols are case-sensitive and must match the format returned by the <code>/exchanges/:exchange</code> API. For example, Binance uses lowercase symbols (<code>btcusdt</code>), not uppercase.</p><p>To get the list of allowed channels and symbols for each exchange, use the <code><https://api.tardis.dev/v1/exchanges/:exchange></code> API endpoint documented below.</p><p>Subscriptions with limited scope (e.g., perpetuals data plan) must provide explicit <code>symbols</code> in filters. Omitting <code>symbols</code> on a limited-scope plan will return an entitlement error.</p> |
| sliceSize                              | number | <p>Number of consecutive minutes returned by one request. Valid values are whole integers from <code>1</code> to <code>10</code>. Default is <code>1</code>.</p><p>Values greater than <code>1</code> require the <code>filters</code> query parameter.</p><p><code>sliceSize</code> reduces <code>/data-feeds</code> request count when replaying consecutive minutes with the same filters.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| compression                            | string | Optional response compression override for `/data-feeds`. Allowed values are `gzip`, `zstd` and `zstd-multiframe`. Prefer `zstd-multiframe` for Zstandard-capable clients; use `zstd` only when the decoder cannot consume concatenated frames.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

#### Headers

| Name            | Type   | Description                                                                                                                                                                         |
| --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization   | string | For authenticated requests, provide the Authorization header with value `Bearer YOUR_API_KEY`. Without API key historical data feeds for the first day of each month are available. |
| Accept-Encoding | string | Required unless `compression` is set. Use `gzip` for default responses. To request Zstandard, set `compression=zstd`; `Accept-Encoding: zstd` alone is not enough.                  |

{% tabs %}
{% tab title="200: OK " %}
Each line contains local timestamp (ISO 8601) and JSON message in exchange native data format. Compression is indicated by the `content-encoding` response header and can be `zstd` or `gzip`.

The `x-slice-size` response header contains the slice size used for this response. The `x-suggested-slice-size` response header contains a recommended `sliceSize` for later requests with the same exchange, filters and compression. Official Node.js and Python clients do this automatically.

`compression=zstd-multiframe` is more efficient and usually returns faster because it avoids server-side recompression. The response uses `content-encoding: zstd` and contains one independent Zstandard frame per minute, including one frame when `sliceSize=1`. Clients must decode every concatenated frame; the official clients handle this automatically. Plain `compression=zstd` remains available for decoders that support only a single Zstandard stream.

```javascript
2019-04-01T00:00:34.8345516Z {"table":"trade","action":"insert","data":[{"timestamp":"2019-04-01T00:00:34.815Z","symbol":"ETHUSD","side":"Sell","size":7000,"price":141.2,"tickDirection":"ZeroMinusTick","trdMatchID":"baa369de-cb3b-b18f-685e-0ffdec00358c","grossValue":98840000,"homeNotional":28.654468050268125,"foreignNotional":4046.010888697859}]}
2019-04-01T00:00:34.8346465Z {"table":"orderBookL2","action":"update","data":[{"symbol":"ETHUSD","id":29699997176,"side":"Buy","size":65350}]}
2019-04-01T00:00:34.8395743Z {"table":"orderBookL2","action":"update","data":[{"symbol":"BCHM19","id":32999999571,"side":"Sell","size":333},{"symbol":"BCHM19","id":32999999572,"side":"Sell","size":576},{"symbol":"BCHM19","id":32999999573,"side":"Sell","size":353}]}
2019-04-01T00:00:34.8567501Z {"table":"trade","action":"insert","data":[{"timestamp":"2019-04-01T00:00:34.830Z","symbol":"XBTUSD","side":"Buy","size":182,"price":4089,"tickDirection":"ZeroPlusTick","trdMatchID":"fa93bd9b-e1b6-d38d-f4d4-65337a766e34","grossValue":4450992,"homeNotional":0.04450992,"foreignNotional":182}]}
2019-04-01T00:00:34.8567741Z {"table":"orderBookL2","action":"update","data":[{"symbol":"XBTUSD","id":8799591100,"side":"Sell","size":351568}]}
2019-04-01T00:00:34.8567783Z {"table":"orderBookL2","action":"update","data":[{"symbol":"ETHUSD","id":29699997176,"side":"Buy","size":55349}]}
2019-04-01T00:00:34.8567812Z {"table":"orderBookL2","action":"update","data":[{"symbol":"ETHUSD","id":29699997167,"side":"Sell","size":430305}]}
2019-04-01T00:00:34.8567847Z {"table":"orderBookL2","action":"insert","data":[{"symbol":"EOSM19","id":33199989652,"side":"Buy","size":216,"price":0.0010348}]}
2019-04-01T00:00:34.8605618Z {"table":"orderBookL2","action":"update","data":[{"symbol":"XBTUSD","id":8799591850,"side":"Buy","size":154511}]}
2019-04-01T00:00:34.8605944Z {"table":"orderBookL2","action":"update","data":[{"symbol":"TRXM19","id":33299999258,"side":"Sell","size":1493}]}
2019-04-01T00:00:34.8617223Z {"table":"orderBookL2","action":"update","data":[{"symbol":"ADAM19","id":33099998260,"side":"Buy","size":224039}]}
```

{% endtab %}

{% tab title="400: Bad Request " %}
Invalid request parameters. This includes `sliceSize` values outside `1` to `10`, non-integer `sliceSize` values, and `sliceSize` greater than `1` without `filters`.

Example response headers:

```http
HTTP/1.1 400 Bad Request
content-type: application/json
```

Example response body:

```json
{
  "code": 300,
  "message": "Invalid 'sliceSize' query string param value: '11'. Please provide a whole integer from 1 to 10."
}
```

{% endtab %}

{% tab title="429: Too Many Requests " %}
Too many requests. Retry later. A 429 response for filtered `/data-feeds` requests may include `x-suggested-slice-size`; use that value as `sliceSize` on later requests with the same exchange, filters and compression.

Example response headers:

```http
HTTP/1.1 429 Too Many Requests
content-type: application/json
x-suggested-slice-size: 5
```

Example response body:

```json
{
  "code": 30,
  "message": "Too many requests. Retry later. Use x-suggested-slice-size as sliceSize on later filtered /data-feeds requests with the same exchange, filters and compression."
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Lines in the response are ordered by capture time. When multiple events share the same millisecond exchange timestamp, use line order as the tie-breaker — see [event ordering FAQ](/faq/data#how-are-events-ordered-when-multiple-messages-share-the-same-timestamp).
{% endhint %}

{% hint style="info" %}
Not sure [what is the channel field?](/faq/data#what-is-the-channel-field-used-in-the-http-api-and-client-libs-replay-functions)
{% endhint %}

{% hint style="info" %}
See [downloadable CSV files documentation](/downloadable-csv-files/overview) and related [datasets API](/downloadable-csv-files/api#datasets-api-reference) if you'd like to access historical tick-level trades, order book snapshots, incremental order book L2 updates, options chains, quotes, derivative tickers and liquidations datasets in daily intervals split by exchange, data type and symbol. It may be faster and more native to your toolkit to access historical data this way.
{% endhint %}

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

```python
import json
import requests


def get_data_feeds():
    filters = [
        {"channel": "trade", "symbols": ["btcusdt"]},
        {"channel": "depth", "symbols": ["btcusdt"]},
    ]
    qs_params = {"from": "2024-03-01", "offset": 3, "filters": json.dumps(filters)}

    headers = {"Authorization": "Bearer YOUR_API_KEY"}

    url = "https://api.tardis.dev/v1/data-feeds/binance"

    response = requests.get(url, headers=headers, params=qs_params, stream=True)

    for line in response.iter_lines():
        # empty lines in response are being used as markers
        # for disconnect events that occurred when collecting the data
        if len(line) <= 1:
            continue

        parts = line.decode("utf-8").split(" ")
        local_timestamp = parts[0]
        message = json.loads(parts[1])
        # local_timestamp string marks message arrival timestamp
        # message is a message dict as provided by exchange real-time stream
        print(local_timestamp, message)


get_data_feeds()
```

{% hint style="info" %}
The [Python client](/python-client/quickstart) adds local caching and date-range replay on top of this endpoint, so you can request longer periods while the client handles raw data replay requests.
{% endhint %}
{% endtab %}

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

```javascript
import split2 from 'split2'
import { Readable } from 'node:stream'

const serialize = (options) => encodeURIComponent(JSON.stringify(options))

const filters = serialize([
  {
    channel: 'trade',
    symbols: ['btcusdt']
  },
  {
    channel: 'depth',
    symbols: ['btcusdt']
  }
])

const baseUrl = 'https://api.tardis.dev/v1/data-feeds/binance'
const url = `${baseUrl}?from=2024-03-01&offset=3&filters=${filters}`

const response = await fetch(url)
const lines = Readable.fromWeb(response.body).pipe(split2())

for await (const line of lines) {
  // empty lines in response are being used as markers
  // for disconnect events that occurred when collecting the data
  if (line.length === 0) {
    continue
  }

  const parts = line.split(' ')
  const localTimestamp = parts[0]
  const message = JSON.parse(parts[1])
  // localTimestamp string marks message arrival timestamp
  // message is a message dict as provided by exchange real-time stream
  console.log(localTimestamp, message)
}
```

{% hint style="info" %}
The [Node.js client](/node-client/quickstart) adds local caching, date-range replay, and normalized data helpers on top of this endpoint, so you can request longer periods while the client handles raw data replay requests.
{% endhint %}
{% endtab %}

{% tab title="cURL" %}

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance?from=2024-03-01&filters=[{"channel":"trade","symbols":["btcusdt"]}]&offset=3'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance?from=2024-03-01&filters=[{%22channel%22:%22trade%22,%22symbols%22:[%22btcusdt%22]}]&offset=3>" %}
Click to see API response in the browser
{% endembed %}
{% endtab %}
{% endtabs %}

#### Sample requests

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitmex?from=2019-04-01&offset=2>" %}
Full BitMEX data feed from 2019-04-01T00:02:00.000Z to 2019-04-01T00:03:00.000Z
{% endembed %}

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitmex?from=2019-05-01&filters=[{%22channel%22:%22trade%22}>]" %}
BitMEX trades for all instruments from 2019-05-01T00:00:00.000Z to 2019-05-01T00:01:00.000Z
{% endembed %}

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitmex?from=2019-06-01&filters=[{%22channel%22:%22trade%22,%20%22symbols%22:%20[%22XBTUSD%22]}>]" %}
BitMEX trades for XBTUSD from 2019-06-01T00:00:00.000Z to 2019-06-01T00:01:00.000Z
{% endembed %}

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitmex?from=2019-06-01&filters=[{%22channel%22:%22trade%22,%20%22symbols%22:%20[%22XBTUSD%22]}]&sliceSize=5>" %}
BitMEX trades for XBTUSD from 2019-06-01T00:00:00.000Z to 2019-06-01T00:05:00.000Z (`sliceSize=5`)
{% endembed %}

{% embed url="<https://api.tardis.dev/v1/data-feeds/deribit?from=2019-06-01&offset=10>" %}
Full Deribit data feed from 2019-06-01T00:10:00.000Z to 2019-06-01T00:11:00.000Z
{% endembed %}

## /exchanges

<mark style="color:blue;">`GET`</mark> `https://api.tardis.dev/v1/exchanges`

Gets the list of all supported exchanges that historical market data is available for.

{% tabs %}
{% tab title="200 Response contains JSON array of supported exchanges with basic details for each" %}
Example response shortened for readability. Use the live endpoint for the current full exchange list.

```javascript
[
  {
    "id": "bitmex",
    "name": "BitMEX",
    "enabled": true,
    "supportsDatasets": true,
    "availableSince": "2019-03-30T00:00:00.000Z",
    "availableChannels": ["trade", "orderBookL2", "quote", "liquidation", "instrument", "..."]
  },
  {
    "id": "deribit",
    "name": "Deribit",
    "enabled": true,
    "supportsDatasets": true,
    "availableSince": "2019-03-30T00:00:00.000Z",
    "availableChannels": ["trades", "book", "ticker", "deribit_price_index", "..."]
  },
  ...
]
```

{% endtab %}
{% endtabs %}

#### Sample request

{% embed url="<https://api.tardis.dev/v1/exchanges>" %}
List of all supported exchanges that historical market data is available for
{% endembed %}

## /exchanges/:exchange

<mark style="color:blue;">`GET`</mark> `https://api.tardis.dev/v1/exchanges/:exchange`

Gets the exchanges details: available symbols, availability dates, available channels, CSV datasets info, incidents etc.

#### Path Parameters

| Name                                       | Type   | Description                                               |
| ------------------------------------------ | ------ | --------------------------------------------------------- |
| exchange<mark style="color:red;">\*</mark> | string | one of <https://api.tardis.dev/v1/exchanges> (field `id`) |

{% tabs %}
{% tab title="200 Response contains JSON object with exchange details - available symbols, available channels, CSV datasets info, incidents etc." %}

```javascript
{
  "id": "bitmex",
  "name": "BitMEX",
  "enabled": true,
  "availableSince": "2019-03-30T00:00:00.000Z",
  "availableChannels": [
    "trade",
    "orderBookL2",
    "quote",
    "liquidation",
    "instrument",
    "connected",
    "announcement",
    "chat",
    "publicNotifications",
    "settlement",
    "funding",
    "insurance",
    "orderBookL2_25",
    "orderBook10",
    "quoteBin1m",
    "quoteBin5m",
    "quoteBin1h",
    "quoteBin1d",
    "tradeBin1m",
    "tradeBin5m",
    "tradeBin1h",
    "tradeBin1d"
  ],
  "availableSymbols": [
    {
      "id": "XBTUSD",
      "type": "perpetual",
      "availableSince": "2019-03-30T00:00:00.000Z"
    },
    {
      "id": "XBTUSDT",
      "type": "perpetual",
      "availableSince": "2021-11-10T00:00:00.000Z"
    },
    {
      "id": "ETHUSD",
      "type": "perpetual",
      "availableSince": "2019-03-30T00:00:00.000Z"
    },
    {
      "id": "ETHUSDT",
      "type": "perpetual",
      "availableSince": "2021-11-10T00:00:00.000Z"
    },
    ...
  ],
  "incidentReports": [],
  "channelDetails": [
    {
      "name": "trade",
      "description": "Public trade executions stream",
      "frequency": "real-time",
      "frequencySource": "exchange-docs",
      "exchangeDocsUrl": "https://www.bitmex.com/app/wsAPI",
      "sourceFor": ["trade"],
      "availableSince": "2019-03-30T00:00:00.000Z"
    },
    {
      "name": "orderBookL2",
      "description": "Order book snapshots and deltas by price level",
      "frequency": "real-time",
      "frequencySource": "exchange-docs",
      "exchangeDocsUrl": "https://www.bitmex.com/app/wsAPI",
      "sourceFor": ["book_change"],
      "availableSince": "2019-03-30T00:00:00.000Z"
    },
    {
      "name": "quote",
      "description": "Best bid and ask quote updates",
      "frequency": "real-time",
      "frequencySource": "exchange-docs",
      "exchangeDocsUrl": "https://www.bitmex.com/app/wsAPI",
      "sourceFor": ["book_ticker"],
      "availableSince": "2019-03-30T00:00:00.000Z"
    },
    {
      "name": "liquidation",
      "description": "Liquidation events stream",
      "frequency": "real-time",
      "frequencySource": "exchange-docs",
      "exchangeDocsUrl": "https://www.bitmex.com/app/wsAPI",
      "sourceFor": ["liquidation"],
      "availableSince": "2019-03-30T00:00:00.000Z"
    },
    {
      "name": "instrument",
      "description": "Instrument state snapshots and deltas with bidPrice/askPrice/midPrice on 5s timer",
      "frequency": "5s",
      "frequencySource": "exchange-docs",
      "exchangeDocsUrl": "https://www.bitmex.com/app/wsAPI",
      "sourceFor": ["derivative_ticker"],
      "availableSince": "2019-03-30T00:00:00.000Z"
    }
  ],
  "apiDocsUrl": "https://www.bitmex.com/app/wsAPI",
  "dataCollectionDetails": {
    "recorderDataCenter": {
      "host": "GCP",
      "regionId": "asia-northeast1",
      "location": "Tokyo, Asia Pacific"
    },
    "wssConnection": {
      "url": "wss://direct.bitmex.com:443/realtimePublic"
    },
    "exchangeDataCenter": {
      "host": "AWS",
      "regionId": "ap-northeast-1",
      "location": "Tokyo, Asia Pacific"
    }
  },
  "datasets": {
    "formats": ["csv"],
    "exportedFrom": "2019-03-30T00:00:00.000Z",
    "exportedUntil": "2026-03-15T00:00:00.000Z",
    "symbols": [
      {
        "id": "XBTUSD",
        "type": "perpetual",
        "availableSince": "2019-03-30T00:00:00.000Z",
        "dataTypes": ["trades", "incremental_book_L2", "quotes", "derivative_ticker", "book_snapshot_25", "liquidations"]
      },
      ...
    ]
  }
}
```

{% endtab %}
{% endtabs %}

`channelDetails[].changes` is optional. When present, each entry describes previous user-visible metadata for the same public channel up to `until`; omitted fields are unchanged from the current channel detail. Typical changed fields are `apiVersion`, `frequency`, `sourceFor`, `description`, `additionalInfo`, and `generated`.

#### Sample request

{% embed url="<https://api.tardis.dev/v1/exchanges/bitmex>" %}
BitMEX exchange details
{% endembed %}

## /api-key-info

<mark style="color:blue;">`GET`</mark> `https://api.tardis.dev/v1/api-key-info`

Given `API_KEY` provided in request header provides information about what historical data (exchanges, date ranges, symbols) is available for given `API_KEY`.

#### Headers

| Name                                            | Type   | Description                                              |
| ----------------------------------------------- | ------ | -------------------------------------------------------- |
| Authorization<mark style="color:red;">\*</mark> | string | Authorization header with value: `'Bearer YOUR_API_KEY'` |

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

```javascript
[
  {
    "exchange": "bitmex",
    "accessType": "pro",
    "from": "2019-03-30T00:00:00.000Z",
    "to": "2050-12-02T00:00:00.000Z",
    "symbols": [],
    "dataPlan": "unlimited"
  },
  {
    "exchange": "deribit",
    "accessType": "one-off-purchase",
    "from": "2019-03-30T00:00:00.000Z",
    "to": "2050-12-02T00:00:00.000Z",
    "symbols": [],
    "dataPlan": "unlimited"
  }
]
```

{% endtab %}
{% endtabs %}


# API Rate Limits

Account-level API request and data transfer limits

API request and data transfer limits apply per account, based on the active subscription.

Historical data transfer is included; we do not charge separately per GB or TB. Limits keep API access fair and reliable and may change as usage patterns and available capacity change.

## Request Limits

| Active subscription type       | Requests/minute |
| ------------------------------ | --------------- |
| Solo / Academic / Professional | 3,000           |
| Business                       | 9,000           |

* Request limits count authenticated HTTP requests to the [raw data replay API](/api/http-api-reference#data-feeds-exchange).
* [Official clients](/api/quickstart) and [Tardis Machine](/tardis-machine/quickstart) call this API in parallel during historical replay, so several replay sessions running at the same time can hit request limits quickly.

## Data Transfer Limits

Data transfer limits count compressed data sent by [CSV dataset downloads](/downloadable-csv-files/api) and [raw data replay API](/api/http-api-reference#data-feeds-exchange) responses.

They depend on the active subscription type and billing interval:

| Billing interval | Solo / Academic / Professional | Business |
| ---------------- | ------------------------------ | -------- |
| Monthly          | 20 TB                          | 60 TB    |
| Quarterly        | 60 TB                          | 180 TB   |
| Yearly           | 240 TB                         | 720 TB   |

Quarterly and yearly limits are available from the start of the billing interval and reset on renewal. This helps with larger initial historical backfills.

## API Key Usage

* Solo, Academic and Professional subscriptions include one active API key.
* Business subscriptions include up to 10 active API keys for multiple team members, servers or locations.

Each key can be used from one source IP address at a time. All API keys on the account share the same request and transfer limits.

## Reduce Data Transfer

* Use `zstd` compression for [raw data replay](/api/http-api-reference#data-feeds-exchange). Latest official [Node.js](/node-client/replaying-historical-data) and [Python](/python-client/replaying-historical-data) clients request `zstd` by default. For direct HTTP calls, set [`compression=zstd`](/api/http-api-reference#data-feeds-exchange) in the query string.
* Keep the official client cache enabled when replaying the same historical data repeatedly.
* Use [`filters`](/api/http-api-reference#data-feeds-exchange) to request only the channels and symbols needed for the current replay.

## Reduce Replay Requests

Treat the API as an on-demand historical data source. Fetch what you need now, then fetch more later instead of mirroring the full archive upfront.

* Use the latest [official clients](/api/quickstart) or [Tardis Machine](/tardis-machine/quickstart) for filtered replay. They apply the recommended `sliceSize` automatically, so one raw data replay request can return up to 10 consecutive minutes and reduce API request count.
* For direct [raw data replay API](/api/http-api-reference#data-feeds-exchange) calls with filters, use the `x-suggested-slice-size` response header as the next `sliceSize` for the same exchange, filters and compression.
* For the same exchange and time range, request multiple channels in the same replay call by putting them in one `filters` array.
* If your account can access all symbols for a channel, request that channel once by omitting `symbols` or passing `symbols: []`.
* If you need selected symbols, put them in one filter for the same exchange, channel and time range instead of one request per symbol. One filter can include up to 50 symbols.


# Quickstart

Install, configure and get started with the tardis-dev npm package

Node.js `tardis-dev` library provides access to tick-level historical and real-time cryptocurrency market data both in [exchange-native and normalized formats](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format). Instead of callbacks, it uses [async iteration (for await ...of)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of), which works well for [switching between real-time streaming and historical replay](/node-client/normalization#seamless-switching-between-real-time-streaming-and-historical-market-data-replay) and [computing derived data locally](/node-client/normalization#computing-derived-data-locally).

## Features

* [historical](/historical-data-details/overview) tick-level [market data replay](/node-client/replaying-historical-data) backed by Tardis.dev [HTTP API](/api/http-api-reference#data-feeds-exchange) — includes full order book depth snapshots plus incremental updates, trades, historical open interest, funding, index, mark prices, liquidations and more
* consolidated [real-time data streaming API](/node-client/streaming-real-time-data) connecting directly to exchanges' public WebSocket APIs
* support for both [exchange-native](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) and [normalized market data](/node-client/normalization) formats (unified format for accessing market data across all supported exchanges — normalized trades, order book and ticker data)
* [seamless switching between real-time streaming and historical market data replay](/node-client/normalization#seamless-switching-between-real-time-streaming-and-historical-market-data-replay) thanks to [`async iterables`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) providing unified way of consuming data messages
* transparent historical local data caching (cached data is stored on disk in compressed format and decompressed on demand when reading the data)
* support for top cryptocurrency exchanges: [BitMEX](/historical-data-details/bitmex), [Deribit](/historical-data-details/deribit), [Binance Spot](/historical-data-details/binance), [Binance USDS-M Futures](/historical-data-details/binance-futures), [OKX Spot](/historical-data-details/okex), [HTX Spot](/historical-data-details/huobi), [bitFlyer](/historical-data-details/bitflyer), [Bitstamp](/historical-data-details/bitstamp), [Coinbase Exchange](/historical-data-details/coinbase), [Kraken Futures (Crypto Facilities)](/historical-data-details/cryptofacilities), [Gemini](/historical-data-details/gemini), [Kraken](/historical-data-details/kraken), [Bitfinex](/historical-data-details/bitfinex), [Bybit Derivatives](/historical-data-details/bybit) and more
* automatic closed connections and stale connections reconnection logic for real-time streams
* [combining multiple exchanges feeds into single one](/node-client/normalization#combining-data-streams) via [`combine`](/node-client/normalization#combining-data-streams) helper function — synchronized historical market data replay and consolidated real-time data streaming from multiple exchanges
* [computing derived data locally](/node-client/normalization#computing-derived-data-locally) like order book imbalance, customizable trade bars, book snapshots and more via [`compute`](/node-client/normalization#computing-derived-data-locally) helper function and `computables`, e.g., volume based bars, top 20 levels order book snapshots taken every 10 ms etc
* [full limit order book reconstruction](/node-client/normalization#limit-order-book-reconstruction) both for real-time and historical data via `OrderBook` object
* fast and lightweight architecture — low memory footprint and no heavy in-memory buffering
* [extensible mapping logic](/node-client/normalization#modifying-built-in-and-adding-custom-normalizers) that allows adjusting normalized formats for specific needs
* built-in TypeScript support
* [Open Source](https://github.com/tardis-dev/tardis-node)

{% embed url="<https://github.com/tardis-dev/tardis-node?1>" %}
Tardis-dev GitHub repository
{% endembed %}

## Installation

Requires Node.js v24.19+ installed.

```bash
npm install tardis-dev --save
```

{% hint style="info" %}
Node.js examples on this page use ES modules and top-level await. Save snippets as `.mjs` or set `"type": "module"` in your `package.json`.
{% endhint %}

## Historical Replay

{% tabs %}
{% tab title="Exchange-native" %}

```javascript
import { replay } from 'tardis-dev'

const messages = replay({
  exchange: 'binance',
  filters: [
    { channel: 'trade', symbols: ['btcusdt'] },
    { channel: 'depth', symbols: ['btcusdt'] }
  ],
  from: '2024-03-01',
  to: '2024-03-02'
})

for await (const { localTimestamp, message } of messages) {
  console.log(localTimestamp, message)
}
```

{% endtab %}

{% tab title="Normalized" %}

```javascript
import { replayNormalized, normalizeTrades, normalizeBookChanges } from 'tardis-dev'

const messages = replayNormalized(
  {
    exchange: 'binance',
    symbols: ['btcusdt'],
    from: '2024-03-01',
    to: '2024-03-02'
  },
  normalizeTrades,
  normalizeBookChanges
)

for await (const message of messages) {
  console.log(message)
}
```

{% endtab %}
{% endtabs %}

{% content-ref url="/pages/gkHZyu4v8WrMNBBiqduR" %}
[Replaying Historical Data](/node-client/replaying-historical-data)
{% endcontent-ref %}

## Real-Time Streaming

{% tabs %}
{% tab title="Exchange-native" %}

```javascript
import { stream } from 'tardis-dev'

const messages = stream({
  exchange: 'binance',
  filters: [
    { channel: 'trade', symbols: ['btcusdt'] },
    { channel: 'depth', symbols: ['btcusdt'] }
  ]
})

for await (const { localTimestamp, message } of messages) {
  console.log(localTimestamp, message)
}
```

{% endtab %}

{% tab title="Normalized" %}

```javascript
import { streamNormalized, normalizeTrades, normalizeBookChanges } from 'tardis-dev'

const messages = streamNormalized(
  {
    exchange: 'binance',
    symbols: ['btcusdt']
  },
  normalizeTrades,
  normalizeBookChanges
)

for await (const message of messages) {
  console.log(message)
}
```

{% endtab %}
{% endtabs %}

{% content-ref url="/pages/NugzOsZ9SfKsMBMmecqk" %}
[Streaming Real-Time Data](/node-client/streaming-real-time-data)
{% endcontent-ref %}

## Debugging and logging

`tardis-dev` lib uses [debug](https://github.com/visionmedia/debug) package for verbose logging and debugging purposes that can be enabled via `DEBUG` environment variable set to `tardis-dev*`.

## ES Modules and TypeScript

Examples in this page use standard ES module imports and top-level await:

```typescript
import { replay, stream } from 'tardis-dev'

const messages = replay({ exchange: 'binance', from: '2024-03-01', to: '2024-03-02' })

for await (const { localTimestamp, message } of messages) {
  console.log(localTimestamp, message)
}
```

This works in modern Node.js and gives you first class TypeScript typings.

## Historical market data helpers

### `init(options)`

{% hint style="info" %}
This function doesn't affect real-time streaming functionality in any way, it's useful only for historical data replay.
{% endhint %}

When working with market data via [`replay`](/node-client/replaying-historical-data#replay-options) and [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers), by default only the first day of each month of historical data is available for replay, and locally cached historical data is stored in the default location on disk (OS temp dir).

Use `init` to set an `apiKey`, custom `cacheDir`, and preferred compression for historical replay requests. `apiKey` can also be provided directly via [`replay`](/node-client/replaying-historical-data#replay-options) and [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) options; that overrides anything set via `init`.

```javascript
import { init } from 'tardis-dev'

init({
  apiKey: 'YOUR API KEY',
  cacheDir: 'CUSTOM CACHE DIR PATH',
  dataFeedCompression: 'gzip'
})
```

#### init options

| name                    | type                          | default                    | description                                                                                                                                                    |
| ----------------------- | ----------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **apiKey**              | string (optional)             | undefined                  | API key for Tardis.dev[ HTTP API](/api/http-api-reference#data-feeds-exchange) - if not provided only first day of each month of historical data is accessible |
| **cacheDir**            | string                        | \<os.tmpdir>/.tardis-cache | path to local dir that will be used as cache location - if not provided default `temp` dir for given OS will be used                                           |
| **dataFeedCompression** | `'zstd' \| 'gzip'` (optional) | `'zstd'`                   | preferred compression for historical replay requests; set to `'gzip'` when you need the client to request gzip-compressed slices                               |

### `getExchangeDetails(exchange)`

Given exchange id provides exchange details (available symbols, availability dates, available channels, pricing info etc) provided by [exchanges/:exchange](/api/http-api-reference#exchanges-exchange) API endpoint.

```javascript
import { getExchangeDetails } from 'tardis-dev'

const binanceExchangeDetails = await getExchangeDetails('binance')
console.log(binanceExchangeDetails.id)
```

#### type of response returned by awaiting on `getExchangeDetails`

```typescript
{
  id: string
  name: string
  enabled: boolean
  delisted?: boolean
  availableSince: string
  availableTo?: string

  availableChannels: string[]

  availableSymbols: {
    id: string
    type: 'spot' | 'future' | 'perpetual' | 'option' | 'combo' | 'prediction'
    availableSince: string
    availableTo?: string
    name?: string
  }[]

  incidentReports: {
    from: string
    to: string
    status: 'resolved' | 'wontfix' | 'unresolved'
    details: string
  }[]

  channelDetails: {
    name: string
    description: string
    frequency: string
    frequencySource: string
    exchangeDocsUrl?: string
    sourceFor?: string[]
    availableSince: string
    availableTo?: string
    apiVersion?: string
    additionalInfo?: string
    generated?: true
    changes?: {
      until: string
      frequency?: string
      sourceFor?: string[]
      apiVersion?: string
      description?: string
      additionalInfo?: string
      generated?: true
    }[]
  }[]

  apiDocsUrl?: string

  dataCollectionDetails?: {
    recorderDataCenter: {
      host: string
      regionId: string
      location: string
    }
    recorderDataCenterChanges?: {
      until: string
      dataCenter: { host: string; regionId: string; location: string }
    }[]
    wssConnection?: {
      url: string
      apiVersion?: string
      proxiedViaCloudflare?: boolean
    }
    wssConnectionChanges?: {
      until: string
      url?: string
      apiVersion?: string
      proxiedViaCloudflare?: boolean
    }[]
    exchangeDataCenter?: {
      host: string
      regionId: string
      location: string
    }
    exchangeDataCenterChanges?: {
      until: string
      dataCenter: { host: string; regionId: string; location: string }
    }[]
  }

  datasets: {
    formats: ['csv']
    exportedFrom: string
    exportedUntil: string
    stats: {
      trades: number
      bookChanges: number
    }
    symbols: {
      id: string
      type: 'spot' | 'future' | 'perpetual' | 'option' | 'combo' | 'prediction'
      availableSince: string
      availableTo?: string
      dataTypes: DatasetType[]
    }[]
  }
}

// where DatasetType is one of:
type DatasetType =
  | 'trades'
  | 'incremental_book_L2'
  | 'quotes'
  | 'derivative_ticker'
  | 'options_chain'
  | 'book_snapshot_25'
  | 'book_snapshot_5'
  | 'liquidations'
  | 'book_ticker'
```

### `getApiKeyAccessInfo(apiKey?)`

Given `apiKey` provided as optional parameter or provided in [`init`](#init-options) function provides information about the account's historical data access: exchanges, access type, data plan, date ranges, and symbol restrictions.

```javascript
import { getApiKeyAccessInfo } from 'tardis-dev'

const details = await getApiKeyAccessInfo('YOUR_API_KEY')
console.log(details)
```

#### type of response returned by awaiting on `getApiKeyAccessInfo()`

```typescript
{
  exchange: string
  accessType: string
  from: string
  to: string
  symbols: string[]
  dataPlan: string
}[]
```

### `clearCache()`

Clears local data cache dir.

```javascript
import { clearCache } from 'tardis-dev'

await clearCache()
```

### `downloadDatasets(options)`

Downloads CSV datasets for specified exchange, data types, symbols and date range. Handles day-by-day downloads, retries and skipping already-downloaded files automatically.

```javascript
import { downloadDatasets } from 'tardis-dev'

await downloadDatasets({
  exchange: 'binance',
  dataTypes: ['trades', 'incremental_book_L2'],
  from: '2024-03-01',
  to: '2024-03-02',
  symbols: ['BTCUSDT'],
  apiKey: 'YOUR_API_KEY'
})
```

{% content-ref url="/pages/qqtWvA83hsjBsfDmZ6Jg#download-via-client-libraries" %}
[API Reference](/downloadable-csv-files/api#download-via-client-libraries)
{% endcontent-ref %}

### `getInstrumentInfo(exchange, symbol)`

Returns instrument metadata (tick sizes, contract multipliers, base/quote currencies) for a given exchange and symbol.

```javascript
import { getInstrumentInfo, init } from 'tardis-dev'

init({ apiKey: 'YOUR_API_KEY' }) // set API key globally for instrument info requests

const info = await getInstrumentInfo('binance', 'btcusdt')
console.log(info)
```

You can also pass an instrument metadata filter, or an array of exchanges, when you need full metadata records.

### `findInstrumentSymbols(exchanges, filter, selector?)`

Use this helper when you know the market you want but not each exchange's symbol format. It queries the [Instruments Metadata API](/api/instruments-metadata-api) with normalized criteria and returns the correct exchange-specific `id` for each requested exchange, ready to pass to replay, streaming, or raw data feeds.

```javascript
import { findInstrumentSymbols, init } from 'tardis-dev'

init({ apiKey: 'YOUR_API_KEY' })

const symbolsByExchange = await findInstrumentSymbols(['bitmex', 'binance-futures', 'okex-swap', 'bybit'], {
  baseCurrency: 'BTC',
  quoteCurrency: 'USDT',
  contractType: 'linear_perpetual',
  active: true
})

console.log(symbolsByExchange)
// [
//   { exchange: 'bitmex', symbols: ['XBTUSDT'] },
//   { exchange: 'binance-futures', symbols: ['btcusdt'] },
//   { exchange: 'okex-swap', symbols: ['BTC-USDT-SWAP'] },
//   { exchange: 'bybit', symbols: ['BTCUSDT'] }
// ]
```

The optional `selector` defaults to `id`. Pass `datasetId` only when you need symbols for direct CSV dataset file downloads:

```javascript
const csvSymbolsByExchange = await findInstrumentSymbols(
  ['bitmex', 'binance-futures', 'okex-swap', 'bybit'],
  {
    baseCurrency: 'BTC',
    quoteCurrency: 'USDT',
    contractType: 'linear_perpetual',
    active: true
  },
  'datasetId'
)
```

Returned `id` symbols are exchange-provided IDs and are not normalized by the client. Returned `datasetId` symbols are CSV dataset IDs for instruments whose symbols appear in exported dataset metadata; `downloadDatasets()` URL-encodes them when constructing dataset URLs.


# Replaying Historical Data

Replaying historical market data in exchange-native and normalized formats

{% hint style="info" %}
See [historical data details](/historical-data-details/overview) page to get detailed information about historical market data available for each exchange.
{% endhint %}

## `replay(options)`

Replays historical market data messages for given replay options in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format). Historical market data is fetched efficiently (in parallel) from the [Tardis.dev HTTP API](/api/http-api-reference#data-feeds-exchange) and cached locally. Returns [`async iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of).

Replay requests use `zstd` compression by default. To force `gzip`, set `init({ dataFeedCompression: 'gzip' })` before calling `replay()` or `replayNormalized()`.

{% hint style="info" %}
For filtered historical replay, the client automatically uses the [recommended `sliceSize`](/api/http-api-reference#data-feeds-exchange) to reduce `/data-feeds` request count.
{% endhint %}

```javascript
import { replay } from 'tardis-dev'

const messages = replay({
  exchange: 'binance',
  filters: [
    { channel: 'trade', symbols: ['btcusdt'] },
    { channel: 'depth', symbols: ['btcusdt'] }
  ],
  from: '2024-03-01',
  to: '2024-03-02'
})

for await (const { localTimestamp, message } of messages) {
  console.log(localTimestamp, message)
}
```

{% hint style="info" %}
[stream(options)](/node-client/streaming-real-time-data#stream-options) is the real-time counterpart of `replay` function, returning real-time market data in the same format.
{% endhint %}

When `symbols` array is empty or omitted in filters, data for all active symbols for that channel is returned. Use that form when you need the whole channel instead of starting one replay per symbol. If you need selected symbols, pass them together in one `symbols` array for the channel.

#### replay options

| name                            | type                                     | default   | description                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------- | ---------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **exchange**                    | string                                   | -         | requested exchange id - one of [allowed values](https://github.com/tardis-dev/tardis-node/blob/master/src/consts.ts#L1)                                                                                                                                                                                                                                               |
| **filters**                     | {channel:string, symbols?: string\[]}\[] | \[]       | optional filters of requested historical data feed - use [`getExchangeDetails`](/node-client/quickstart#historical-market-data-helpers) function from [Getting Started](/node-client/quickstart#historical-market-data-helpers) to get allowed channels and symbols ids for requested exchange                                                                        |
| **from**                        | string                                   | -         | replay period start date (UTC) in a format recognized by the [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse), e.g., `2019-04-01`                                                                                                                                                                          |
| **to**                          | string                                   | -         | replay period end date (UTC) in a format recognized by the [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse), e.g., `2019-04-02`                                                                                                                                                                            |
| **skipDecoding**                | boolean (optional)                       | undefined | when set to `true` returns messages as buffers instead of decoding them to objects                                                                                                                                                                                                                                                                                    |
| **withDisconnects**             | boolean (optional)                       | undefined | when set to `true` returns message with value `undefined` for events when connection that was recording the historical data got disconnected                                                                                                                                                                                                                          |
| **apiKey**                      | string (optional)                        | undefined | API key for Tardis.dev[ HTTP API](/api/http-api-reference#data-feeds-exchange) - if not provided only first day of each month of historical data is accessible. It can also be set via [`init`](/node-client/quickstart#historical-market-data-helpers) function from [Getting Started](/node-client/quickstart#historical-market-data-helpers) for all replay calls. |
| **autoCleanup**                 | boolean (optional)                       | undefined | when set to `true`, automatically removes cached data from disk after it has been processed — useful for large backfills where disk space is a concern. Not safe for concurrent replay — see warning below.                                                                                                                                                           |
| **waitWhenDataNotYetAvailable** | boolean or number (optional)             | undefined | when set to `true`, waits for data that is not yet available using a 30-minute offset. When set to a number, specifies the offset in minutes (minimum effective value is 6 minutes)                                                                                                                                                                                   |
| **withMicroseconds**            | boolean (optional)                       | undefined | when set to `true`, `localTimestamp` is returned with microsecond precision instead of millisecond                                                                                                                                                                                                                                                                    |

{% hint style="warning" %}
The client can fetch replay data with up to 60 concurrent `/data-feeds` HTTP requests per replay job. Long date ranges, many channel/symbol filters and multiple concurrent replay processes can quickly exceed [API rate limits](/api/rate-limits), causing request failures.
{% endhint %}

{% hint style="warning" %}
**`autoCleanup` concurrency**: avoid using `autoCleanup` with concurrent replay — the cache path is keyed by exchange, a hash of the filters, and the calendar day, so any concurrent jobs sharing those three components will conflict (even with non-overlapping time windows within the same day) and cause file-not-found errors. Clean the cache manually after all jobs complete instead.
{% endhint %}

#### type of messages provided by `replay` iterator ([`for await ...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of))

```typescript
type Message =
  | {
      localTimestamp: Date // local timestamp when message has been received
      message: any // message in exchange-native data format
    }
    // when skipDecoding is set to true
  | {
      localTimestamp: Buffer
      message: Buffer
    }

// when withDisconnects is set to true whole message can be undefined (disconnect)
Message | undefined
```

#### sample message

```javascript
{
  localTimestamp: 2024-03-01T00:00:00.001Z,
  message: {
    stream: 'btcusdt@trade',
    data: {
      e: 'trade',
      E: 1709251199998,
      s: 'BTCUSDT',
      t: 3445374963,
      p: '61130.98000000',
      q: '0.00145000',
      b: 25230662315,
      a: 25230662808,
      T: 1709251199998,
      m: true,
      M: true
    }
  }
}
```

## `replayNormalized(options, ...normalizers)`

Replays historical market data messages for given replay options and **normalizes messages** using normalizers provided as [rest arguments](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). Historical market data is fetched efficiently (in parallel) from the [Tardis.dev HTTP API](/api/http-api-reference#data-feeds-exchange) and cached locally. Returns [`async iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of).

```javascript
import { replayNormalized, normalizeTrades, normalizeBookChanges } from 'tardis-dev'

const messages = replayNormalized(
  {
    exchange: 'binance',
    symbols: ['btcusdt'],
    from: '2024-03-01',
    to: '2024-03-02'
  },
  normalizeTrades,
  normalizeBookChanges
)

for await (const message of messages) {
  console.log(message)
}
```

{% hint style="info" %}
[streamNormalized(options, ...normalizers)](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers) is the real-time counterpart of `replayNormalized` function, returning real-time market data in the same format.
{% endhint %}

#### replay normalized options

| name                            | type                         | default   | description                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------- | ---------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **exchange**                    | string                       | -         | requested exchange id - one of [allowed values](https://github.com/tardis-dev/tardis-node/blob/master/src/consts.ts#L1)                                                                                                                                                                                                                                                           |
| **symbols**                     | string\[] (optional)         | undefined | optional symbols for requested data feed - use [`getExchangeDetails`](/node-client/quickstart#historical-market-data-helpers) function from [Getting Started](/node-client/quickstart#historical-market-data-helpers) to get allowed symbols ids for requested exchange                                                                                                           |
| **from**                        | string                       | -         | replay period start date (UTC) in a format recognized by the [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse), e.g., `2019-04-01`                                                                                                                                                                                      |
| **to**                          | string                       | -         | replay period end date (UTC) in a format recognized by the [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) e.g., `2019-04-02`                                                                                                                                                                                         |
| **withDisconnectMessages**      | boolean (optional)           | undefined | when set to `true` returns [`disconnect`](/node-client/normalization#disconnect-message) messages for events when connection that was recording the historical data got disconnected                                                                                                                                                                                              |
| **apiKey**                      | string (optional)            | undefined | API key for Tardis.dev[ HTTP API](/api/http-api-reference#data-feeds-exchange) - if not provided only first day of each month of historical data is accessible. It can also be set via [`init`](/node-client/quickstart#historical-market-data-helpers) function from [Getting Started](/node-client/quickstart#historical-market-data-helpers) for all `replayNormalized` calls. |
| **autoCleanup**                 | boolean (optional)           | undefined | when set to `true`, automatically removes cached data from disk after it has been processed — useful for large backfills where disk space is a concern. Not safe for concurrent replay — see [replay options](#replay-options) warning.                                                                                                                                           |
| **waitWhenDataNotYetAvailable** | boolean or number (optional) | undefined | when set to `true`, waits for data that is not yet available using a 30-minute offset. When set to a number, specifies the offset in minutes (minimum effective value is 6 minutes)                                                                                                                                                                                               |

#### Built-in normalizers

`replayNormalized` function accepts any number of [normalizers](/node-client/normalization) [as rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) that map from [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) to normalized data format. `tardis-dev` ships with [built in ones that normalize trades, order book and derivative ticker data](/node-client/normalization) but also allows [adding custom](/node-client/normalization#modifying-built-in-and-adding-custom-normalizers) ones.

#### types of messages provided by `replayNormalized` iterator ([`for await ...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of))

Message types and formats depend on specific normalizers provided to `replayNormalized` function and are documented in detail in [Normalization](/node-client/normalization).

#### sample message

Sample message produced by [`normalizeTrades`](/node-client/normalization#normalizetrades)

```javascript
{
  type: 'trade',
  symbol: 'BTCUSDT',
  exchange: 'binance',
  id: '3445374963',
  price: 61130.98,
  amount: 0.00145,
  side: 'sell',
  timestamp: 2024-02-29T23:59:59.998Z,
  localTimestamp: 2024-03-01T00:00:00.001Z
}
```


# Streaming Real-Time Data

Streaming real-time market data from exchanges' WebSocket feeds

Real-time market data streaming connecting directly to exchanges' WebSocket APIs with automatic reconnection.

## `stream(options)`

Streams real-time market data messages for given stream options in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format). It connects directly to exchanges WebSocket APIs and transparently restarts closed, broken or stale connections (open connections without data being sent for specified amount of time). Returns [`async iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of).

```javascript
import { stream } from 'tardis-dev'

const messages = stream({
  exchange: 'binance',
  filters: [
    { channel: 'trade', symbols: ['btcusdt'] },
    { channel: 'depth', symbols: ['btcusdt'] }
  ]
})

for await (const { localTimestamp, message } of messages) {
  console.log(localTimestamp, message)
}
```

{% hint style="info" %}
[replay(options)](/node-client/replaying-historical-data#replay-options) is the historical market data counterpart of `stream` function, returning historical market data in the same format.
{% endhint %}

#### stream options

| name                  | type                                     | default   | description                                                                                                                                                                                                                                                                          |
| --------------------- | ---------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **exchange**          | string                                   | -         | requested exchange id - one of [allowed values](https://github.com/tardis-dev/tardis-node/blob/master/src/consts.ts#L1)                                                                                                                                                              |
| **filters**           | {channel:string, symbols?: string\[]}\[] | \[]       | optional filters of requested real-time data feed - use [`getExchangeDetails`](/node-client/quickstart#historical-market-data-helpers) from [Getting Started](/node-client/quickstart#historical-market-data-helpers) to get allowed channels and symbols ids for requested exchange |
| **withDisconnects**   | boolean (optional)                       | undefined | when set to `true` returns message with value `undefined` for real-time stream disconnect events                                                                                                                                                                                     |
| **timeoutIntervalMS** | number                                   | 10000     | specifies time in milliseconds after which connection is restarted if no message has been received from the exchange                                                                                                                                                                 |
| **onError**           | function (optional)                      | undefined | Optional callback `(err) => void` invoked when real-time WebSocket connection error occurs, useful for custom error logging etc.                                                                                                                                                     |

#### type of messages provided by `stream` iterator ([`for await ...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of))

```typescript
type Message = {
  localTimestamp: Date // local timestamp when message has been received
  message: any // message in exchange-native data format
}

// when withDisconnects is set to true whole message can be undefined
Message | undefined
```

#### sample message

```javascript
{
  localTimestamp: 2024-03-01T00:00:00.001Z,
  message: {
    stream: 'btcusdt@trade',
    data: {
      e: 'trade',
      E: 1709251199998,
      s: 'BTCUSDT',
      t: 3445374963,
      p: '61130.98000000',
      q: '0.00145000',
      b: 25230662315,
      a: 25230662808,
      T: 1709251199998,
      m: true,
      M: true
    }
  }
}
```

## `streamNormalized(options, ...normalizers)`

Streams real-time market data messages for given stream options and **normalizes messages** using provided normalizers provided as [rest arguments](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). It connects directly to exchanges WebSocket APIs and transparently restarts closed, broken or stale connections (open connections without data being sent for specified amount of time). Returns [`async iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of).

```javascript
import { streamNormalized, normalizeTrades, normalizeBookChanges } from 'tardis-dev'

const messages = streamNormalized(
  {
    exchange: 'binance',
    symbols: ['btcusdt']
  },
  normalizeTrades,
  normalizeBookChanges
)

for await (const message of messages) {
  console.log(message)
}
```

{% hint style="info" %}
[replayNormalized(options, ...normalizers)](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) is the historical counterpart of `streamNormalized` function, returning historical market data in the same format.
{% endhint %}

#### stream normalized options

| name                       | type                 | default   | description                                                                                                                                 |
| -------------------------- | -------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **exchange**               | string               | -         | requested exchange id - one of [allowed values](https://github.com/tardis-dev/tardis-node/blob/master/src/consts.ts#L1)                     |
| **symbols**                | string\[] (optional) | undefined | instruments symbols for requested data feed                                                                                                 |
| **withDisconnectMessages** | boolean (optional)   | undefined | when set to `true` returns [`disconnect`](/node-client/normalization#disconnect-message) messages for real-time stream disconnect events    |
| **timeoutIntervalMS**      | number               | 10000     | specifies time in milliseconds after which connection is restarted if no message has been received from the exchange                        |
| **onError**                | function (optional)  | undefined | Optional callback `(err) => void` invoked when real-time WebSocket connection or mapping error occurs, useful for custom error logging etc. |

{% hint style="info" %}
For sparse instruments (e.g., illiquid options or niche currency pairs), increase `timeoutIntervalMS` (e.g., `60000`) to prevent unnecessary connection restarts when no messages arrive for extended periods. This is especially important for computed data types like `trade_bar` on low-volume symbols.
{% endhint %}

#### Built-in normalizers

`streamNormalized` function can accept any number of custom normalizers as [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) that map from [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) to normalized data format. `tardis-dev` ships with [built in ones that normalize trades, order book and derivative ticker data](/node-client/normalization) but also allows [adding custom ones](/node-client/normalization#modifying-built-in-and-adding-custom-normalizers).

#### types of messages provided by `streamNormalized` iterator ([`for await ...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of))

Message types and formats depend on specific normalizers provided to `streamNormalized` function and are documented in detail in [Normalization](/node-client/normalization).

#### sample message

Sample message produced by [`normalizeTrades`](/node-client/normalization#normalizetrades)

```javascript
{
  type: 'trade',
  symbol: 'BTCUSDT',
  exchange: 'binance',
  id: '3445374963',
  price: 61130.98,
  amount: 0.00145,
  side: 'sell',
  timestamp: 2024-02-29T23:59:59.998Z,
  localTimestamp: 2024-03-01T00:00:00.001Z
}
```


# Normalization

Normalizers, order book reconstruction, combine and compute

Data normalization allows consuming market data feeds from various exchanges in consistent format.

`tardis-dev` has following built-in normalizers that can be provided to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers) functions:

* [`normalizeTrades`](#normalizetrades) - provides normalized `trade` data
* [`normalizeBookChanges`](#normalizebookchanges) - provides normalized [`book_change`](#normalizebookchanges) data
* [`normalizeDerivativeTickers`](#normalizederivativetickers) - provides normalized funding, index and mark price data
* [`normalizeBookTickers`](#normalizebooktickers) - provides normalized [`book_ticker`](#normalizebooktickers) (best bid/ask) data from exchange-native BBO feeds
* [`normalizeLiquidations`](#normalizeliquidations) - provides normalized `liquidation` data
* [`normalizeOptionsSummary`](#normalizeoptionssummary) - provides normalized `option_summary` data (greeks, IV, bid/ask for options)

If you're interested in how exactly data is mapped from [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) to normalized one, please follow code in [`tardis-dev` GitHub repository](https://github.com/tardis-dev/tardis-node/tree/master/src/mappers) for each exchange and if you determined that mapping should be done differently please read "[modifying built-in and adding custom normalizers](#modifying-built-in-and-adding-custom-normalizers)" section.

```javascript
import { streamNormalized, normalizeTrades, normalizeBookChanges, normalizeDerivativeTickers } from 'tardis-dev'

// or replayNormalized to replay normalized historical data
const messages = streamNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT']
  },
  normalizeTrades,
  normalizeBookChanges,
  normalizeDerivativeTickers
)

for await (const message of messages) {
  if (message.type === 'book_change') {
    // process normalized book change
  }
  if (message.type === 'trade') {
    // process normalized trade
  }
  if (message.type === 'derivative_ticker') {
    // process normalized derivative_ticker
  }
}
```

### `normalizeTrades`

When passed as an arg to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers), it provides normalized `trade` data for all supported exchanges.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  type: 'trade',
  symbol: 'BTCUSDT',
  exchange: 'binance',
  id: '3445374963',
  price: 61130.98,
  amount: 0.00145,
  side: 'sell',
  timestamp: 2024-02-29T23:59:59.998Z,
  localTimestamp: 2024-03-01T00:00:00.001Z
}
```

{% endtab %}

{% tab title="type definition" %}

```typescript
{
  type: 'trade'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  id: string | undefined // trade id if provided by exchange
  price: number // trade price as provided by exchange
  amount: number // trade amount as provided by exchange
  side: 'buy' | 'sell' | 'unknown' // liquidity taker side (aggressor)
  timestamp: Date // trade timestamp provided by exchange
  localTimestamp: Date // message arrival timestamp
}
```

{% endtab %}
{% endtabs %}

### `normalizeBookChanges`

When passed as an arg to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers), it provides normalized `book_change` data for all supported exchanges.

Provides initial [L2 (market by price)](/faq/order-books#what-l2-order-book-data-can-be-used-for) order book snapshots (`isSnapshot=true`) plus incremental updates for each order book change. Please note that `amount` is the updated amount at that price level, not a delta. An `amount` of `0` indicates the price level can be removed.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  type: 'book_change',
  symbol: 'BTCUSDT',
  exchange: 'binance',
  isSnapshot: false,
  bids: [{ price: 61141.09, amount: 2.02515 }],
  asks: [{ price: 61141.1, amount: 4.09368 }],
  timestamp: 2024-03-01T00:00:01.489Z,
  localTimestamp: 2024-03-01T00:00:01.491Z
}
```

{% endtab %}

{% tab title="type definition" %}

```typescript
{
  type: 'book_change'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  isSnapshot: boolean // if true marks initial order book snapshot
  bids: { price: number; amount: number }[] // updated bids price-amount levels
  asks: { price: number; amount: number }[] // updated asks price-amount levels
  timestamp: Date // order book update timestamp if provided by exchange,
                  // otherwise equals to localTimestamp
  localTimestamp: Date // message arrival timestamp
}
```

{% endtab %}
{% endtabs %}

When processing `book_change` updates: an `amount` of `0` means remove that price level. If you receive a removal for a price level not in your local book, ignore it. Snapshot levels may include zero-amount entries — these should also be treated as absent levels.

### `normalizeBookTickers`

When passed as an arg to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers), it provides normalized `book_ticker` data — top of the book (best bid/ask) data from exchanges' native best bid/offer channels (e.g., Binance `bookTicker`, Bybit `orderbook.1`). Unlike `quote`, which is derived from L2 order book data via [`computeBookSnapshots`](#computebooksnapshots-options), `book_ticker` is sourced from the native exchange-provided WebSocket best bid/offer feed.

Because it is a standalone feed, `book_ticker` replay can start from any point in time, whereas `quote` requires starting from 00:00 UTC (when the initial L2 order book snapshot is provided).

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  type: 'book_ticker',
  symbol: 'BTCUSDT',
  exchange: 'binance-futures',
  askPrice: 63125.5,
  askAmount: 2.5,
  bidPrice: 63125.4,
  bidAmount: 1.8,
  timestamp: 2024-01-15T10:30:00.123Z,
  localTimestamp: 2024-01-15T10:30:00.234Z
}
```

{% endtab %}

{% tab title="type definition" %}

```typescript
{
  type: 'book_ticker'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  askPrice: number | undefined // best ask price, undefined if there aren't any asks
  askAmount: number | undefined // best ask amount, undefined if there aren't any asks
  bidPrice: number | undefined // best bid price, undefined if there aren't any bids
  bidAmount: number | undefined // best bid amount, undefined if there aren't any bids
  timestamp: Date // message timestamp provided by exchange
  localTimestamp: Date // message arrival timestamp
}
```

{% endtab %}
{% endtabs %}

### `normalizeDerivativeTickers`

When passed as an arg to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers), it provides normalized `derivative_ticker` data for supported exchanges that trade derivative instruments.

Funding fields describe upcoming funding events relative to the message timestamp. `fundingTimestamp` is the next funding event time: the immediately upcoming event, not a previously settled funding time. `fundingRate` is the rate for that next event and can change until the event occurs. `predictedFundingRate`, when present, estimates the following funding event.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  type: 'derivative_ticker',
  symbol: 'BTCUSDT',
  exchange: 'binance-futures',
  lastPrice: 61131.0,
  openInterest: 1458236000,
  fundingRate: 0.0001,
  fundingTimestamp: 2024-03-01T08:00:00.000Z,
  predictedFundingRate: 0.00009,
  indexPrice: 61130.9,
  markPrice: 61131.1,
  timestamp: 2024-03-01T00:00:00.250Z,
  localTimestamp: 2024-03-01T00:00:00.251Z
}
```

{% endtab %}

{% tab title="type definition" %}

```typescript
{
  type: 'derivative_ticker'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  lastPrice: number | undefined // last instrument price if provided by exchange
  openInterest: number | undefined // last open interest if provided by exchange
  fundingRate: number | undefined // funding rate for the next funding event if provided by exchange
  indexPrice: number | undefined // last index price if provided by exchange
  markPrice: number | undefined // last mark price if provided by exchange
  fundingTimestamp: Date | undefined // next funding event timestamp if provided by exchange
  predictedFundingRate: number | undefined // estimated funding rate for the following funding event if provided by exchange
  timestamp: Date // message timestamp provided by exchange
  localTimestamp: Date // message arrival timestamp
}
```

{% endtab %}
{% endtabs %}

### `normalizeLiquidations`

When passed as an arg to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers), it provides normalized `liquidation` data for exchanges that publish liquidation events. See [which exchanges support liquidations](/faq/data#which-exchanges-support-liquidations-data-type).

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  type: 'liquidation',
  symbol: 'BTCUSDT',
  exchange: 'binance-futures',
  id: '2045830192',
  price: 61110.5,
  amount: 0.25,
  side: 'sell',
  timestamp: 2024-03-01T00:05:12.123Z,
  localTimestamp: 2024-03-01T00:05:12.124Z
}
```

{% endtab %}

{% tab title="type definition" %}

```typescript
{
  type: 'liquidation'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  id: string | undefined // liquidation id if provided by exchange
  price: number // liquidation price
  amount: number // liquidation amount
  side: 'buy' | 'sell' | 'unknown' // liquidation side: buy means short liquidation, sell means long liquidation
  timestamp: Date // message timestamp provided by exchange; some exchanges do not provide a separate liquidation timestamp, in which case this equals localTimestamp
  localTimestamp: Date // message arrival timestamp
}
```

{% endtab %}
{% endtabs %}

### `normalizeOptionsSummary`

When passed as an arg to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers), it provides normalized `option_summary` data for exchanges that provide options data (e.g., Deribit, OKX Options, Binance European Options). Includes greeks, implied volatility, and best bid/ask.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  type: 'option_summary',
  symbol: 'BTC-28JUN24-70000-C',
  exchange: 'deribit',
  optionType: 'call',
  strikePrice: 70000,
  expirationDate: 2024-06-28T08:00:00.000Z,
  bestBidPrice: 0.035,
  bestBidAmount: 5,
  bestBidIV: 0.55,
  bestAskPrice: 0.04,
  bestAskAmount: 10,
  bestAskIV: 0.58,
  lastPrice: 0.0375,
  openInterest: 150,
  markPrice: 0.0372,
  markIV: 0.565,
  delta: 0.25,
  gamma: 0.00002,
  vega: 45.5,
  theta: -15.2,
  rho: 0.05,
  underlyingPrice: 63500,
  underlyingIndex: 'BTC-USD',
  timestamp: 2024-01-15T10:30:00.123Z,
  localTimestamp: 2024-01-15T10:30:00.234Z
}
```

{% endtab %}

{% tab title="type definition" %}

```typescript
{
  type: 'option_summary'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  optionType: 'put' | 'call' // option type
  strikePrice: number // strike price
  expirationDate: Date // option expiration date
  bestBidPrice: number | undefined // best bid price
  bestBidAmount: number | undefined // best bid amount
  bestBidIV: number | undefined // best bid implied volatility
  bestAskPrice: number | undefined // best ask price
  bestAskAmount: number | undefined // best ask amount
  bestAskIV: number | undefined // best ask implied volatility
  lastPrice: number | undefined // last trade price
  openInterest: number | undefined // open interest
  markPrice: number | undefined // mark price
  markIV: number | undefined // mark implied volatility
  delta: number | undefined // delta greek
  gamma: number | undefined // gamma greek
  vega: number | undefined // vega greek
  theta: number | undefined // theta greek
  rho: number | undefined // rho greek
  underlyingPrice: number | undefined // underlying asset price
  underlyingIndex: string // underlying index name
  timestamp: Date // message timestamp provided by exchange
  localTimestamp: Date // message arrival timestamp
}
```

{% endtab %}
{% endtabs %}

### `disconnect` message

When [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) or [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers) have the `withDisconnectMessages` flag set to `true` and a disconnect event occurs (e.g., WebSocket connection close), a `disconnect` message is returned.

{% tabs %}
{% tab title="sample message" %}

```typescript
{
  type: 'disconnect',
  exchange: 'binance',
  localTimestamp: 2024-03-01T00:00:00.001Z
}
```

{% endtab %}

{% tab title="type definition" %}

```typescript
{
  type: 'disconnect'
  exchange: string // exchange id
  localTimestamp: Date // timestamp when disconnect occurred
  symbols: string[] | undefined
}
```

{% endtab %}
{% endtabs %}

### Modifying built-in and adding custom normalizers

In `tardis-dev` data normalization is implemented via `normalize` factory functions provided to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) and [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers) functions. This design gives lots of flexibility by allowing replacing, extending and modifying built-in normalizers or adding new ones for new normalized data types without the need of forking the whole library.

Any normalize function provided to [`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) and [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers) functions needs to have following signature:

```
(exchange: string, localTimestamp: Date) => Mapper
```

`Exchange` is the exchange id for which a mapper object must be returned, `localTimestamp` is the date for which the mapper is created (recreated after each disconnection). In most cases `localTimestamp` is not necessary for anything, but in certain cases like for example exchange API change it can be used to switch to different mapping logic like using new data channel that wasn't available until certain date.

Returned `Mapper` object has following signature:

```typescript
{
  canHandle: (message: any) => boolean

  map(message: any, localTimestamp: Date): IterableIterator<Data> | undefined

  getFilters: (symbols?: string[]) => {channel: string, symbols?: string[]}[]
}
```

On every disconnection event, normalize factory functions are called again to provide new `Mapper` objects with clean state if required (stateful mapping needs to persist metadata such as price level IDs and reset for each new connection). If a mapper object is stateful, it is required to always return a new clean state object from the normalize factory function or reset its state in one way or another.

Normalized data returned by [`iterable iterator`](https://developer.mozilla.org/pl/docs/Web/JavaScript/Guide/Iterators_and_Generators) of `Mapper.map` method is expected to have a shape that has at least fields as described in [normalized data type section](#normalized-data-type) below to play well with other `tardis-dev` functions like [`combine`](#combining-data-streams) or [`compute`](#computing-derived-data-locally).

#### normalized data type

```typescript
{
  type: string
  symbol: string
  exchange: string
  timestamp: Date
  localTimestamp: Date
  name? : string | undefined
}
```

#### Adding custom `normalizeLiquidations` normalizer

Example implementation of a custom `normalizeLiquidations` function that normalizes liquidations data for `deribit` exchange. Implementations for other exchanges are left as an exercise for the reader.

**type of messages provided by `normalizeLiquidations`**

```typescript
{
  type: 'liquidation'
  symbol: string
  exchange: string
  side: 'buy' | 'sell'
  amount: number
  price: number
  timestamp: Date
  localTimestamp: Date
}
```

implementation of `deribitLiquidations` mapper and `normalizeLiquidations`

```javascript
// object that maps from deribit trades real-time channel to our custom
// liquidations messages if determines that trade was caused by liquidation

const deribitLiquidationsMapper = {

  // function that given message in deribit native format
  // https://docs.deribit.com/v2/#trades-instrument_name-interval
  // determines if such message can be mapped/normalized
  canHandle(message) {
    const params = message.params
    const channel = params !== undefined ? params.channel : undefined
    if (channel === undefined) {
      return false
    }
    return (
      channel.startsWith('trades') &&
      params.data.some(trade => trade.liquidation !== undefined)
    )
  },

  // given symbols returns filters that are provided
  // as filters to replay & stream functions options
  // in our case we're interested in trades deribit channel
  // but it could be multiple channels in certain scenarions as well
  getFilters(symbols) {
    return [
      {
        channel: 'trades',
        symbols
      }
    ]
  },

  // map message that was determined that is can be handled via canHandle
  // to normalized liquidation message
  *map(message, localTimestamp) {
    for (const deribitLiquidationTrade of message.params.data) {
      if (deribitLiquidationTrade.liquidation === undefined) {
        continue
      }

      yield {
        type: 'liquidation',
        symbol: deribitLiquidationTrade.instrument_name,
        exchange: 'deribit',
        price: deribitLiquidationTrade.price,
        amount: deribitLiquidationTrade.amount,
        side: deribitLiquidationTrade.direction,
        timestamp: new Date(deribitLiquidationTrade.timestamp),
        localTimestamp: localTimestamp
      }
    }
  }
}

// provides factory function that given exchange returns mapper for it
// if such mapper if implemented
// in our case deribitLiquidationsMapper is stateless so we can return the same
// instance every time

const normalizeLiquidations = (exchange, localTimestamp) => {
  if (exchange === 'deribit') {
    return deribitLiquidationsMapper
  }
  throw new Error(`normalizeLiquidations: ${exchange} not supported`)
}
```

**`normalizeLiquidations` usage example**

We could as well provide the same `normalizeLiquidations` function to [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers) function or use it together it with other normalizers (`normalizeTrades` etc.).

```javascript
import { replayNormalized } from 'tardis-dev'

const liquidations = replayNormalized(
  {
    exchange: 'deribit',
    symbols: ['BTC-PERPETUAL'],
    from: '2024-03-01',
    to: '2024-03-02'
  },
  normalizeLiquidations
)

for await (const liquidation of liquidations) {
  console.log(liquidation)
}
```

#### Changing `normalizeTrades` for Binance exchange

Let's assume that default normalization of Binance exchange trades data doesn't fit our use case and we need to use [`@aggTrade`](https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#aggregate-trade-streams) stream as a source of trade data instead of the default [`@trade`](https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#trade-streams) stream.

```javascript
// add custom binance trades mapper that used @aggTrade stream as source of
// normalized trades
const customBinanceTradesMapper = {
  canHandle(message) {
    return message.stream && message.stream.endsWith('@aggTrade')
  },

  getFilters(symbols) {
    if (symbols !== undefined) {
      symbols = symbols.map(s => s.toLocaleLowerCase())
    }
    // binance api expects all symbols to be lower cased
    return [
      {
        channel: 'aggTrade',
        symbols
      }
    ]
  },

  *map(message, localTimestamp) {
    const binanceAggTrade = message.data

    yield {
      type: 'trade',
      symbol: binanceAggTrade.s,
      exchange: 'binance',
      id: String(binanceAggTrade.a),
      price: Number(binanceAggTrade.p),
      amount: Number(binanceAggTrade.q),
      side: binanceAggTrade.m ? 'sell' : 'buy',
      timestamp: new Date(binanceAggTrade.T),
      localTimestamp: localTimestamp
    }
  }
}

// add new normalize function that only for binance exchange
// uses custom trades mapper and defaults to default normalizeTrades
// for other exchanges

const normalizeTradesWithBinancePatch = (exchange, localTimestamp) => {
  if (exchange === 'binance') {
    return customBinanceTradesMapper
  }
  return normalizeTrades(exchange, localTimestamp)
}
```

**`normalizeTradesWithBinancePatch` usage example**

```javascript
import { streamNormalized } from 'tardis-dev'

const messages = streamNormalized(
  {
    exchange: 'binance',
    symbols: ['btcusdt']
  },
  normalizeTradesWithBinancePatch
)

for await (const message of messages) {
  console.log(message)
}
```

## Limit order book reconstruction

`tardis-dev` exports `OrderBook` class that, when instantiated, can process normalized [`book_change`](#normalizebookchanges) messages with order book snapshots and incremental updates and allows maintaining full local order book (level 2 - aggregated market-by-price) state both for real-time data and for reconstructing historical order book state at any past point in time. It waits for the first `book_change` message that is a snapshot (`isSnapshot = true`) and then applies subsequent updates to it. A single `orderBook` object can maintain order book state only for a single symbol/instrument. It uses a [Red-Black tree](https://github.com/vadimg/js_bintrees) data structure under the hood to efficiently maintain its local state in sorted order.

{% tabs %}
{% tab title="historical order book reconstruction" %}

```javascript
import { replayNormalized, normalizeBookChanges, OrderBook } from 'tardis-dev'

const books = {
  BTCUSDT: new OrderBook(),
  ETHUSDT: new OrderBook()
}

const messages = replayNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT', 'ETHUSDT'],
    from: '2024-03-01',
    to: '2024-03-02'
  },
  normalizeBookChanges
)

for await (const message of messages) {
  const orderBook = books[message.symbol]
  if (message.type === 'book_change') {
    orderBook.update(message)
  }
  const timestamp = message.localTimestamp.toISOString()
  // print best bid/ask for every exchange tick
  console.log(timestamp, orderBook.bestAsk(), orderBook.bestBid())
}
```

{% endtab %}

{% tab title="maintaining order book for real-time stream" %}

```javascript
import { streamNormalized, normalizeBookChanges, OrderBook } from 'tardis-dev'

const books = {
  BTCUSDT: new OrderBook(),
  ETHUSDT: new OrderBook()
}

const messages = streamNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT', 'ETHUSDT']
  },
  normalizeBookChanges
)

for await (const message of messages) {
  const orderBook = books[message.symbol]
  if (message.type === 'book_change') {
    orderBook.update(message)
  }
  const timestamp = message.localTimestamp.toISOString()
  // print best bid/ask for every exchange tick
  console.log(timestamp, orderBook.bestAsk(), orderBook.bestBid())
}
```

{% endtab %}
{% endtabs %}

#### OrderBook constructor options

`new OrderBook()` accepts an optional options object:

| name                        | type                | default   | description                                                                                                                                                     |
| --------------------------- | ------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`removeCrossedLevels`**   | boolean (optional)  | undefined | when set to `true`, automatically detects and removes crossed levels (where best bid >= best ask) that can occur when exchanges fail to publish delete messages |
| **`onCrossedLevelRemoved`** | function (optional) | undefined | optional callback `(bookChange, bestBidBefore, bestBidAfter, bestAskBefore, bestAskAfter) => void` invoked whenever a crossed level is removed                  |

### `orderBook.update(bookChange)`

Processes normalized [`book_change`](#normalizebookchanges) messages to update its internal local state that maintains ordered bids and asks sets. It ignores any non-snapshot `book_change` messages before an initial snapshot is received. It should be called for every `book_change` message received for the symbol for which you'd like to reconstruct the order book.

```javascript
orderBook.update({
  type: 'book_change',
  symbol: 'BTCUSDT',
  exchange: 'binance-futures',
  isSnapshot: false,
  bids: [],
  asks: [{ price: 7985, amount: 283318 }],
  timestamp: new Date(),
  localTimestamp: new Date()
})
```

### `orderBook.bestBid()`

Returns [book price level object](#book-price-level-type) for highest bid order (best bid) in order book or `undefined` if book doesn't have any bids (not initialized yet with initial snapshot).

```javascript
const { price, amount } = orderBook.bestBid()
```

### `orderBook.bestAsk()`

Returns [book price level object](#book-price-level-type) for lowest ask order (best ask) in order book or `undefined` if book doesn't have any asks (not initialized yet with initial snapshot).

```javascript
const { price, amount } = orderBook.bestAsk()
```

### `orderBook.asks()`

Returns [iterable iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) of [book price level](#book-price-level-type) objects for all **asks** available ordered from the lowest to highest ask.

```typescript
for (const ask of orderBook.asks()) {
    // process asks levels one by one from lowest to highest without
    // creating in memory array for all levels
}

const orderedAsksArray = Array.from(orderBook.asks())
```

### `orderBook.bids()`

Returns [iterable iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) of [book price level](#book-price-level-type) objects for all **bids** available ordered from highest to lowest bid.

```typescript
for (const bid of orderBook.bids()) {
    // process bid levels one by one from highest to lowest without
    // creating in memory array for all levels
}

const orderedBidsArray = Array.from(orderBook.bids())
```

#### book price level type

```typescript
{
  price: number
  amount: number
}
```

## Utility functions

### `filter(asyncIterable, fn)`

Filters an async iterable, returning only messages that match the predicate function.

```javascript
import { replayNormalized, normalizeTrades, filter } from 'tardis-dev'

const messages = replayNormalized(
  { exchange: 'binance', from: '2024-03-01', to: '2024-03-02', symbols: ['btcusdt'] },
  normalizeTrades
)
const largeTrades = filter(messages, (trade) => trade.amount >= 10000)

for await (const trade of largeTrades) {
  console.log(trade)
}
```

### `uniqueTradesOnly(options?)`

Returns a predicate function for use with [`filter()`](#filter-asynciterable-fn) that removes duplicate trades (same trade ID) and optionally skips stale trades.

**Options**

| Name                        | Type                     | Default | Description                                                                                 |
| --------------------------- | ------------------------ | ------- | ------------------------------------------------------------------------------------------- |
| `maxWindow`                 | `number`                 | `500`   | Maximum number of trade IDs to track per symbol for deduplication                           |
| `skipStaleOlderThanSeconds` | `number`                 | —       | If set, skips trades where `localTimestamp - timestamp` exceeds this threshold (in seconds) |
| `onDuplicateFound`          | `(trade: Trade) => void` | —       | Optional callback invoked when a duplicate or stale trade is detected                       |

```javascript
import { replayNormalized, normalizeTrades, filter, uniqueTradesOnly } from 'tardis-dev'

const messages = replayNormalized(
  { exchange: 'binance', from: '2024-03-01', to: '2024-03-02', symbols: ['btcusdt'] },
  normalizeTrades
)
const uniqueTrades = filter(messages, uniqueTradesOnly())

for await (const trade of uniqueTrades) {
  console.log(trade)
}
```

**With options**

```javascript
const uniqueTrades = filter(messages, uniqueTradesOnly({
  maxWindow: 1000,
  skipStaleOlderThanSeconds: 30,
  onDuplicateFound: (trade) => console.warn('Duplicate trade:', trade.id)
}))
```

## Combining data streams

### `combine(...iterators)`

[`Combine`](#combining-data-streams) function given multiple `async iterators` combines them into single one. That allows synchronized historical market data replay and consolidated streaming of real-time data for multiple exchanges via single [`for await ...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) loop.

Accepts `async iterables` of [normalized messages](/node-client/normalization) as [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) and combines them returning single `async iteratable`.

For historical data replay it combines input `async iterables` messages by sorting them by `localTimestamp` in ascending order, this allows synchronized/ordered market data replay for multiple exchanges.

For real-time market data streaming it combines input `async iterables` messages in FIFO order by writing them into a shared Node.js object-mode stream (`PassThrough`) as they arrive.

{% tabs %}
{% tab title="combining historical market data from multiple exchanges" %}

```javascript
import { replayNormalized, normalizeTrades, combine } from 'tardis-dev'

const binanceMessages = replayNormalized(
  {
    exchange: 'binance',
    symbols: ['btcusdt'],
    from: '2024-03-01',
    to: '2024-03-02'
  },
  normalizeTrades
)

const binanceFuturesMessages = replayNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT'],
    from: '2024-03-01',
    to: '2024-03-02'
  },
  normalizeTrades
)

const combinedStream = combine(binanceMessages, binanceFuturesMessages)

// order at which messages have historically arrived is preserved
for await (const message of combinedStream) {
  if (message.exchange === 'binance-futures') {
    // process binance futures trades
    console.log(message)
  }

  if (message.exchange === 'binance') {
    // process binance spot trades
    console.log(message)
  }
}
```

{% endtab %}

{% tab title="combining real-time stream of market data from multiple exchanges" %}

```javascript
import { streamNormalized, normalizeTrades, combine } from 'tardis-dev'

const binanceMessages = streamNormalized(
  {
    exchange: 'binance',
    symbols: ['btcusdt']
  },
  normalizeTrades
)

const binanceFuturesMessages = streamNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT']
  },
  normalizeTrades
)

const combinedStream = combine(binanceMessages, binanceFuturesMessages)

// messages are provided in FIFO order as they arrive
for await (const message of combinedStream) {
  if (message.exchange === 'binance-futures') {
    // process binance futures trades
    console.log(message)
  }

  if (message.exchange === 'binance') {
    // process binance spot trades
    console.log(message)
  }
}
```

{% endtab %}
{% endtabs %}

## Computing derived data locally

### `compute(iterator, ...computables)`

[`Compute`](#computing-derived-data-locally) function allows computing various derived data locally via so called [`computables`](#adding-custom-computable) like:

* [`computeTradeBars`](#computetradebars-options) - computes various trade bars (OHLC, volume based bars, tick based bars) based on [normalized trade](#normalizetrades) data
* [`computeBookSnapshots`](#computebooksnapshots-options) - computes various order book snapshots based on normalized [order book data](#normalizebookchanges)

If you're interested in adding custom [`computables`](#adding-custom-computable) like for example order book imbalance, volume imbalance, open interest or funding rate based bars please read ["adding custom computable"](#adding-custom-computable) section.

[`Compute`](#computing-derived-data-locally) function accepts an `async iterable` producing [normalized messages](/node-client/normalization) together with [`computables`](#adding-custom-computable) as [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters), and returns an `async iterable` with normalized messages produced by the provided iterable plus all computed messages based on provided [`computable`](#adding-custom-computable) functions. It computes and produces separate normalized computed messages for each symbol and exchange combination. When a [`disconnect message`](#disconnect-message) is returned by the provided `async iterable`, it discards existing pending computables and starts computing them from scratch.

```javascript
import { streamNormalized, normalizeTrades, normalizeBookChanges, compute, computeTradeBars, computeBookSnapshots } from 'tardis-dev'

const binanceFuturesMessages = streamNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT']
  },
  normalizeTrades,
  normalizeBookChanges
)

const messagesWithComputedTypes = compute(
  binanceFuturesMessages,
  // 10 seconds time bars
  computeTradeBars({ kind: 'time', interval: 10 * 1000 }),
  // top 20 levels 50 millisecond order book snapshots
  computeBookSnapshots({ depth: 20, interval: 50 }),
  // volume based trade bar - 1 million vol buckets
  computeTradeBars({ kind: 'volume', interval: 1000 * 1000 })
)

for await (const message of messagesWithComputedTypes) {
  if (message.type === 'book_snapshot' || message.type === 'trade_bar') {
    console.log(message)
  }
}
```

### `computeTradeBars(options)`

When provided to [`compute`](#computing-derived-data-locally) function, it computes normalized [`trade_bar`](#type-of-message-provided-by-computetradebars) messages based on [normalized trade](#normalizetrades) data.

```javascript
import { computeTradeBars } from 'tardis-dev'

computeTradeBars({ kind: 'volume', interval: 1000 })
```

#### compute trade bars options

| name         | type                              | default   | description                                                                                                                                                                                                                                                 |
| ------------ | --------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **kind**     | `'time'`, `'volume'`, or `'tick'` | -         | determines the way trades within a bar will be aggregated. `time` creates classic OHLC candles aggregated by time. `volume` creates volume-based trade bars aggregated by the sum of trades `amount`. `tick` creates trade bars aggregated by trades count. |
| **interval** | number                            | -         | determines interval to aggregate by - for time based bars it's number of milliseconds, for volume based bars it's accumulated volume, for tick it's count of trades                                                                                         |
| **name**     | string (optional)                 | undefined | optional custom name of `trade_bar`, if not specified computed name will be provided based on kind and interval options                                                                                                                                     |

#### type of message provided by `computeTradeBars`

```typescript
{
  type: 'trade_bar'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  name: string // name with format trade_bar_{interval}{suffix}
  interval: number // requested trade bar interval
  kind: 'time' | 'volume' | 'tick' // trade bar kind
  open: number // open price
  high: number // high price
  low: number // low price
  close: number // close price
  volume: number // total volume traded in given interval
  buyVolume: number // buy volume traded in given interval
  sellVolume: number // sell volume traded in given interval
  trades: number // trades count in given interval
  vwap: number // volume weighted average price
  openTimestamp: Date // timestamp of first trade for given bar
  closeTimestamp: Date // timestamp of last trade for given bar
  timestamp: Date // end of interval period timestamp
  localTimestamp: Date // message arrival timestamp
                       // that triggered given bar computation
}
```

#### sample normalized `trade_bar` message

```javascript
{
  type: 'trade_bar',
  symbol: 'BTCUSDT',
  exchange: 'binance-futures',
  name: 'trade_bar_10000ms',
  interval: 10000,
  kind: 'time',
  open: 61130.98,
  high: 61142.3,
  low: 61129.75,
  close: 61138.12,
  volume: 12.845,
  buyVolume: 7.421,
  sellVolume: 5.424,
  trades: 18,
  vwap: 61135.84,
  openTimestamp: 2024-03-01T00:00:00.112Z,
  closeTimestamp: 2024-03-01T00:00:09.881Z,
  localTimestamp: 2024-03-01T00:00:10.004Z,
  timestamp: 2024-03-01T00:00:10.000Z,
}
```

### `computeBookSnapshots(options)`

When provided to [`compute`](#computing-derived-data-locally) function, computes normalized [`book_snapshot`](#type-of-message-provided-by-computebooksnapshots) messages based on normalized [order book data](#normalizebookchanges). It produces new snapshots only if there is an actual change in order book state for requested `depth`.

```javascript
import { computeBookSnapshots } from 'tardis-dev'

computeBookSnapshots({ depth: 20, interval: 50 })
```

#### compute book snapshots options

| name                      | type                | default   | description                                                                                                                                                                                                                             |
| ------------------------- | ------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **depth**                 | number              | -         | number of closest bids and asks levels to provide snapshot for                                                                                                                                                                          |
| **interval**              | number              | -         | snapshot interval in milliseconds, if `0` is provided it computes snapshots real-time any time there is a change in order book state for requested `depth`                                                                              |
| **name**                  | string (optional)   | undefined | optional custom name of `book_snapshot`, if not specified computed name will be provided based on depth and interval options                                                                                                            |
| **grouping**              | number (optional)   | undefined | when provided, aggregates order book price levels into groups of the specified price increment (e.g., `10` groups all levels within each $10 range into a single level). Bids are floored and asks are ceiled to the grouping boundary. |
| **removeCrossedLevels**   | boolean (optional)  | undefined | when set to `true`, automatically detects and removes crossed levels (where best bid >= best ask) that can occur when exchanges fail to publish delete messages                                                                         |
| **onCrossedLevelRemoved** | function (optional) | undefined | optional callback `(bookChange, bestBidBefore, bestBidAfter, bestAskBefore, bestAskAfter) => void` invoked whenever a crossed level is removed                                                                                          |

#### type of message provided by `computeBookSnapshots`

```typescript
{
  type: 'book_snapshot'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  name: string // name with format book_snapshot_{depth}_{interval}{time_unit}
  depth: number // requested number of levels (top bids/asks)
  interval: number // requested snapshot interval in milliseconds
  bids: { price: number | undefined; amount: number | undefined }[] // top "depth" bids price-amount levels
  asks: { price: number | undefined; amount: number | undefined }[] // top "depth" asks price-amount levels
  grouping: number | undefined // price grouping increment, if grouping was requested
  timestamp: Date // snapshot timestamp based on last book_change message
                  // processed timestamp adjusted to snapshot interval
  localTimestamp: Date // message arrival timestamp
                       // that triggered snapshot
}
```

#### sample normalized `book_snapshot` message

```javascript
{
  type: 'book_snapshot',
  symbol: 'BTCUSDT',
  exchange: 'binance-futures',
  name: 'book_snapshot_2_50ms',
  depth: 2,
  interval: 50,
  bids: [
    { price: 61141.09, amount: 2.02515 },
    { price: 61141.08, amount: 0.55321 }
  ],
  asks: [
    { price: 61141.1, amount: 4.09368 },
    { price: 61141.11, amount: 1.20457 }
  ],
  timestamp: 2024-03-01T00:00:01.450Z,
  localTimestamp: 2024-03-01T00:00:01.491Z
}
```

### Adding custom `computable`

Any `computables` provided to [`compute function`](#computing-derived-data-locally) need to be factory functions with following signature:

```
() => Computable
```

where returned `Computable` object has following signature:

```typescript
{
  sourceDataTypes: string[]
  compute(message: NormalizedData): IterableIterator<NormalizedData>
}
```

`Computable.compute` returned iterator is expected to provide objects that at least have fields as described in [normalized data type section](#normalized-data-type) to play well with other `tardis-dev` functions like [`combine`](#combining-data-streams).

#### `computeOrderBookImbalanceRatio()`

Example implementation of custom `computeOrderBookImbalanceRatio` function that as a source data type uses book snapshots and based on it computes ratio of asks amounts (sell orders) to bids amounts (buy orders) for given [`book_snapshot`](#computebooksnapshots-options) depth. It may be used to determine relative buy or sell pressure.

**type of messages produced by** `computeOrderBookImbalanceRatio`

```typescript
{
  type: 'book_imbalance'
  symbol: string
  exchange: string
  asksToBidsRatio: number
  timestamp: Date
  localTimestamp: Date
}
```

#### implementation of `BookImbalanceRatioComputable` `computable` and `computeOrderBookImbalanceRatio` factory function.

```javascript
class BookImbalanceRatioComputable {
  constructor() {
    this.sourceDataTypes = ['book_snapshot']
  }

  *compute(bookSnapshot) {
    let bidsAmount = 0
    let asksAmount = 0

    for (let i = 0; i < bookSnapshot.depth; i++) {
      bidsAmount += bookSnapshot.bids[i].amount
      asksAmount += bookSnapshot.asks[i].amount
    }

    const asksToBidsRatio = asksAmount / bidsAmount
    yield {
      type: 'book_imbalance',
      symbol: bookSnapshot.symbol,
      exchange: bookSnapshot.exchange,
      asksToBidsRatio,
      timestamp: bookSnapshot.timestamp,
      localTimestamp: bookSnapshot.localTimestamp
    }
  }
}

const computeOrderBookImbalanceRatio = () => new BookImbalanceRatioComputable()
```

#### `computeOrderBookImbalanceRatio` **usage example**

Given implementation above we can compute book imbalance ratio for Binance Futures real-time `BTCUSDT` message stream. For this example we compute top 5 levels, 2 second book snapshots as a source to our custom computable. We need to have `async iterable` that produces book snapshots as a source to our book imbalance computable, hence two invocations of `compute.`

```javascript
import { streamNormalized, normalizeBookChanges, compute, computeBookSnapshots } from 'tardis-dev'

const binanceFuturesMessages = streamNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT']
  },
  normalizeBookChanges
)

const messagesWithBookSnapshots = compute(
  binanceFuturesMessages,
  computeBookSnapshots({ depth: 5, interval: 2 * 1000 })
)

const messagesWithComputedData = compute(
  messagesWithBookSnapshots,
  computeOrderBookImbalanceRatio
)

for await (const message of messagesWithComputedData) {
  if (message.type === 'book_imbalance') {
    console.log(message)
  }
}
```

## Examples

### Real-time spread across multiple exchanges

Example showing how to display real-time spread and best bid/ask info across multiple exchanges at once. It can be easily adapted to do the same for historical data ([`replayNormalized`](https://docs.tardis.dev/node-client/pages/gkHZyu4v8WrMNBBiqduR#replaynormalized-options-...normalizers) instead of [`streamNormalized`](https://docs.tardis.dev/node-client/pages/NugzOsZ9SfKsMBMmecqk#streamnormalized-options-...normalizers)).

```javascript
import { streamNormalized, normalizeBookChanges, combine, compute, computeBookSnapshots } from 'tardis-dev'

const exchangesToStream = [
  { exchange: 'binance', symbols: ['btcusdt'] },
  { exchange: 'binance-futures', symbols: ['BTCUSDT'] },
  { exchange: 'bybit', symbols: ['BTCUSDT'] }
]

// for each specified exchange call streamNormalized for it
// so we have multiple real-time streams for all specified exchanges
const realTimeStreams = exchangesToStream.map(e => {
  return streamNormalized(e, normalizeBookChanges)
})

// combine all real-time message streams into one
const messages = combine(...realTimeStreams)

// create book snapshots with depth1 that are produced
// every time best bid/ask info is changed
// effectively computing real-time quotes
const realTimeQuoteComputable = computeBookSnapshots({
  depth: 1,
  interval: 0,
  name: 'realtime_quote'
})

// compute real-time quotes for combines real-time messages
const messagesWithQuotes = compute(messages, realTimeQuoteComputable)

const spreads = {}

// print spreads info every 100ms
setInterval(() => {
  console.clear()
  console.log(spreads)
}, 100)

// update spreads info real-time
for await (const message of messagesWithQuotes) {
  if (message.type === 'book_snapshot') {
    spreads[message.exchange] = {
      spread: message.asks[0].price - message.bids[0].price,
      bestBid: message.bids[0],
      bestAsk: message.asks[0]
    }
  }
}
```

### Replay large historical trades across multiple exchanges

Example showing replaying large historical trades across multiple exchanges as those happened.

```javascript
import { replayNormalized, normalizeTrades, combine } from 'tardis-dev'

const from = '2024-03-01'
const to = '2024-03-02'
const exchanges = [
  { exchange: 'binance', symbols: ['btcusdt'] },
  { exchange: 'binance-futures', symbols: ['BTCUSDT'] },
  { exchange: 'bybit', symbols: ['BTCUSDT'] }
]

const historicalTrades = exchanges.map(exchange => {
  return replayNormalized({ from, to, ...exchange }, normalizeTrades)
})

const LARGE_TRADE_THRESHOLD = 100 * 1000 // 100k  contracts

for await (const trade of combine(...historicalTrades)) {
  if (trade.amount >= LARGE_TRADE_THRESHOLD) {
    console.log(trade.exchange, trade)
  }
}
```

### Seamless switching between real-time streaming and historical market data replay

Example showing a simple pattern of providing an `async iterable` of market data messages to a function that can process them whether it is real-time or historical market data. That effectively enables having the same data pipeline for backtesting and live trading.

```javascript
import { replayNormalized, streamNormalized, normalizeTrades, compute, computeTradeBars } from 'tardis-dev'

const historicalMessages = replayNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT'],
    from: '2024-03-01',
    to: '2024-03-02'
  },
  normalizeTrades
)

const realTimeMessages = streamNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT']
  },
  normalizeTrades
)

async function produceVolumeBasedTradeBars(messages) {
  const withVolumeTradeBars = compute(
    messages,
    computeTradeBars({
      kind: 'volume',
      interval: 100 * 1000 // aggregate by 100k contracts volume
    })
  )

  for await (const message of withVolumeTradeBars) {
    if (message.type === 'trade_bar') {
      console.log(message.name, message)
    }
  }
}

produceVolumeBasedTradeBars(historicalMessages)

// or for real time data
//  await produceVolumeBasedTradeBars(realTimeMessages)
```

### Real-time funding rate and open interest across multiple exchanges

Example showing how to quickly display real-time funding rate and open interest info across multiple exchanges at once.

```javascript
import { streamNormalized, normalizeDerivativeTickers, combine } from 'tardis-dev'

const exchangesToStream = [
  { exchange: 'binance-futures', symbols: ['BTCUSDT'] },
  { exchange: 'bybit', symbols: ['BTCUSDT'] },
  { exchange: 'okex-swap', symbols: ['BTC-USD-SWAP'] },
  { exchange: 'deribit', symbols: ['BTC-PERPETUAL'] },
  { exchange: 'bitfinex-derivatives', symbols: ['BTCF0:USTF0'] }
]

const realTimeStreams = exchangesToStream.map(e => {
  return streamNormalized(e, normalizeDerivativeTickers)
})

// combine all real-time message streams into one
const messages = combine(...realTimeStreams)

const funding = {}

// print funding info every 100ms
setInterval(() => {
  console.clear()
  console.log(new Date().toISOString(), funding)
}, 100)

// update funding info real-time
for await (const message of messages) {
  if (message.type === 'derivative_ticker') {
    funding[message.exchange] = {
      symbol: message.symbol,
      fundingRate: message.fundingRate,
      lastPrice: message.lastPrice,
      openInterest: message.openInterest,
      markPrice: message.markPrice
    }
  }
}
```

### Saving historical funding, index and open interest data to CSV file

Example showing how to write Deribit exchange historical funding, index and open interest data into CSV.

```javascript
import { replayNormalized, normalizeDerivativeTickers } from 'tardis-dev'
import fs from 'fs'
import csv from 'fast-csv'
import { once } from 'events'
const fileStream = fs.createWriteStream('./deribit_funding.csv')
const csvStream = csv.format({ headers: true })
csvStream.pipe(fileStream)

const messages = replayNormalized(
  {
    exchange: 'deribit',
    from: '2024-03-01',
    to: '2024-03-02',
    symbols: ['BTC-PERPETUAL']
  },
  normalizeDerivativeTickers
)

for await (const message of messages) {
  if (message.type === 'derivative_ticker') {
    const ok = csvStream.write({
      fundingRate: message.fundingRate,
      lastPrice: message.lastPrice,
      openInterest: message.openInterest,
      indexPrice: message.indexPrice,
      timestamp: message.timestamp.toISOString()
    })

    if (!ok) {
      await once(csvStream, 'drain')
    }
  }
}
```

### Computing simple moving average of volume based trade bars

Example showing implementation of `SimpleMovingAverageComputable` that calculates average of trade bar closes prices for specified rolling window in incremental way. It uses `CircularBuffer` under the hood.

```javascript
class CircularBuffer {
  constructor(_bufferSize) {
    this._bufferSize = _bufferSize
    this._buffer = []
    this._index = 0
  }
  append(value) {
    const isFull = this._buffer.length === this._bufferSize
    let poppedValue
    if (isFull) {
      poppedValue = this._buffer[this._index]
    }
    this._buffer[this._index] = value
    this._index = (this._index + 1) % this._bufferSize
    return poppedValue
  }
  *items() {
    for (let i = 0; i < this._buffer.length; i++) {
      const index = (this._index + i) % this._buffer.length
      yield this._buffer[index]
    }
  }
  get count() {
    return this._buffer.length
  }
}

class SimpleMovingAverageComputable {
  constructor({ periods }) {
    this.sourceDataTypes = ['trade_bar']
    this._average = 0
    this._circularBuffer = new CircularBuffer(periods)
  }

  *compute(tradeBar) {
    const result = this._circularBuffer.append(tradeBar.close)
    const poppedVal = result !== undefined ? result : this._average
    const increment = (tradeBar.close - poppedVal) / this._circularBuffer.count
    this._average = this._average + increment

    yield {
      type: 'sma',
      symbol: tradeBar.symbol,
      exchange: tradeBar.exchange,
      name: `sma_${tradeBar.name}`,
      average: this._average,
      interval: tradeBar.interval,
      kind: tradeBar.kind,
      timestamp: tradeBar.timestamp,
      localTimestamp: tradeBar.localTimestamp
    }
  }
}

const computeSimpleMovingAverages = options => () =>
  new SimpleMovingAverageComputable(options)
```

#### Usage

```javascript
import { streamNormalized, normalizeTrades, compute, computeTradeBars } from 'tardis-dev'

const messages = streamNormalized(
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT']
  },
  normalizeTrades
)

const withTradeBars = compute(
  messages,
  computeTradeBars({
    kind: 'volume',
    interval: 1000
  })
)
const withSimpleMovingAverage = compute(
  withTradeBars,
  computeSimpleMovingAverages({ periods: 5 })
)

for await (const message of withSimpleMovingAverage) {
  if (message.type === 'sma') {
    console.log(message)
  }
}
```

## Environment variables (advanced)

The following environment variables configure streaming and network behavior. `HTTP_PROXY` applies to both real-time streaming and historical data downloads. Exchange credentials and WebSocket URL overrides apply only to real-time streaming.

#### Network

| Name                     | Description                                                                                                                                              |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`HTTP_PROXY`**         | HTTP/HTTPS proxy URL for all outgoing requests                                                                                                           |
| **`WSS_URL_<EXCHANGE>`** | Override the default WebSocket URL for a specific exchange. Exchange name is uppercased with dashes replaced by underscores (e.g., `WSS_URL_BINANCE_US`) |

#### Exchange credentials

Required for exchanges that need authentication to access real-time WebSocket feeds.

| Name                                        | Description                                                                                |
| ------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **`OKX_API_KEY`**                           | OKX API key — required for restricted real-time channels such as `books-l2-tbt` (VIP-only) |
| **`OKX_API_SECRET_KEY`**                    | OKX API secret key                                                                         |
| **`OKX_API_PASSPHRASE`**                    | OKX API passphrase                                                                         |
| **`OKX_API_VIP_5`**                         | Set to `true` if OKX account has VIP 5+ tier — enables access to `books-l2-tbt` channel    |
| **`OKX_API_COLO`**                          | Set to `true` if using OKX colocation — enables access to `books-l2-tbt` channel           |
| **`DERIBIT_API_CLIENT_ID`**                 | Deribit API client ID — required for authenticated real-time channels                      |
| **`DERIBIT_API_CLIENT_SECRET`**             | Deribit API client secret                                                                  |
| **`COINBASE_API_KEY`**                      | Coinbase API key — required for authenticated WebSocket feeds                              |
| **`COINBASE_API_SECRET`**                   | Coinbase API secret                                                                        |
| **`COINBASE_API_PASSPHRASE`**               | Coinbase API passphrase                                                                    |
| **`COINBASE_INTERNATIONAL_API_KEY`**        | Coinbase International API key                                                             |
| **`COINBASE_INTERNATIONAL_API_SECRET`**     | Coinbase International API secret                                                          |
| **`COINBASE_INTERNATIONAL_API_PASSPHRASE`** | Coinbase International API passphrase                                                      |

#### Binance rate limit tuning

Control rate limiting for Binance depth snapshot requests and `openInterest` REST polling during real-time streaming. Variable names use the exchange name uppercased with dashes replaced by underscores (e.g., `BINANCE_FUTURES_REQUEST_WEIGHT_LIMIT`).

| Name                                               | Default  | Applies to     | Description                                                           |
| -------------------------------------------------- | -------- | -------------- | --------------------------------------------------------------------- |
| **`<EXCHANGE>_REQUEST_WEIGHT_LIMIT`**              | from API | depth + OI     | Override the request weight limit per minute                          |
| **`<EXCHANGE>_MIN_AVAILABLE_WEIGHT_BUFFER`**       | auto     | depth + OI     | Minimum request weight buffer before throttling kicks in              |
| **`<EXCHANGE>_CONCURRENCY_LIMIT`**                 | `4`      | depth          | Number of concurrent depth snapshot requests                          |
| **`<EXCHANGE>_SNAPSHOTS_DELAY_MS`**                | none     | depth          | Delay in ms between individual depth snapshot requests                |
| **`<EXCHANGE>_OPEN_INTEREST_POLLING_INTERVAL_MS`** | `5000`   | `openInterest` | Minimum polling interval in ms for generated `openInterest` snapshots |


# Quickstart

Install via Docker or npm and run your first replay

![](/files/-M2YHurMxtHTW9ak0V9I)

[Tardis-machine](https://github.com/tardis-dev/tardis-machine) is a locally runnable server with built-in data caching that uses Tardis.dev [HTTP API](/api/http-api-reference) under the hood. It provides both tick-level historical and consolidated real-time cryptocurrency market data via its HTTP and WebSocket APIs and is available via [npm](#npm) and [Docker](#docker).

## Features

* efficient data replay API endpoints returning historical market data for whole time periods (in contrast to Tardis.dev [HTTP API](/api/http-api-reference) where single call returns data for single minute time period)
* [exchange-native market data APIs](/tardis-machine/replaying-historical-data#exchange-native-market-data-apis)
  * tick-by-tick historical market data replay in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format)
  * [HTTP](/tardis-machine/replaying-historical-data#http-get-replay-options-options) and [WebSocket](/tardis-machine/replaying-historical-data#websocket-ws-replay-exchange-exchange-and-from-fromdate-and-to-todate) endpoints
  * [WebSocket API](/tardis-machine/replaying-historical-data#websocket-ws-replay-exchange-exchange-and-from-fromdate-and-to-todate) providing historical market data replay from any given past point in time with the same data format and 'subscribe' logic as real-time exchanges' APIs - in many cases **existing exchanges' WebSocket clients can be used to connect to this endpoint**
* [normalized market data APIs](/tardis-machine/replaying-historical-data#normalized-market-data-apis)
  * consistent format for accessing market data across multiple exchanges
  * [HTTP](/tardis-machine/replaying-historical-data#http-get-replay-normalized-options-options) and [WebSocket](/tardis-machine/replaying-historical-data#websocket-ws-replay-normalized-options-options) endpoints
  * synchronized [historical market data replay across multiple exchanges](/tardis-machine/replaying-historical-data#http-get-replay-normalized-options-options)
  * [consolidated real-time data streaming](/tardis-machine/streaming-real-time-data) connecting directly to exchanges' WebSocket APIs
  * customizable [order book snapshots](/tardis-machine/data-types#book_snapshot_-number_of_levels-_-snapshot_interval-time_unit) and [trade bars](/tardis-machine/data-types#trade_bar_-aggregation_interval-suffix) data types
* [seamless switching between real-time data streaming and historical data replay](/tardis-machine/replaying-historical-data#normalized-market-data-apis)
* transparent historical local data caching (cached data is stored on disk in compressed format and decompressed on demand when reading the data)
* support for top cryptocurrency exchanges: [BitMEX](/historical-data-details/bitmex), [Deribit](/historical-data-details/deribit), [Binance Spot](/historical-data-details/binance), [Binance USDS-M Futures](/historical-data-details/binance-futures), [OKX Spot](/historical-data-details/okex), [HTX Spot](/historical-data-details/huobi), [bitFlyer](/historical-data-details/bitflyer), [Bitstamp](/historical-data-details/bitstamp), [Coinbase Exchange](/historical-data-details/coinbase), [Kraken Futures (Crypto Facilities)](/historical-data-details/cryptofacilities), [Gemini](/historical-data-details/gemini), [Kraken](/historical-data-details/kraken), [Bitfinex](/historical-data-details/bitfinex), [Bybit Derivatives](/historical-data-details/bybit) and more
* [Open Source](https://github.com/tardis-dev/tardis-machine)

{% embed url="<https://github.com/tardis-dev/tardis-machine>" %}
Tardis-machine GitHub repository
{% endembed %}

{% hint style="info" %}
Real-time streaming via tardis-machine is available only in [normalized format](/tardis-machine/streaming-real-time-data). Exchange-native (raw) real-time data is not provided. If you need raw real-time feeds, connect directly to exchange WebSocket APIs.
{% endhint %}

## Installation

### **Docker**

Pull and run latest version of [`tardisdev/tardis-machine` image](https://hub.docker.com/r/tardisdev/tardis-machine):

```bash
### running without persistent local cache
docker run -p 8000:8000 -p 8001:8001 -e "TM_API_KEY=YOUR_API_KEY" -d tardisdev/tardis-machine
```

Tardis Machine HTTP endpoints will be available on port `8000` and WebSocket endpoints on port `8001`. Replace `YOUR_API_KEY` with your API key.

The command above does not use persistent volumes for local caching (each Docker restart will result in losing local data cache). To use `./host-cache-dir` as a persistent volume ([bind mount](https://docs.docker.com/storage/bind-mounts/)) cache directory, run:

```bash
docker run -v ./host-cache-dir:/.cache -p 8000:8000 -p 8001:8001 -e "TM_API_KEY=YOUR_API_KEY" -d tardisdev/tardis-machine
```

Docker bind mounts can be slower or harder to configure on some systems, especially Windows. You can run without a volume, but the local cache is lost on container restart.

#### Config environment variables

You can set the following environment variables to configure tardis-machine server:

| name                  | default   | description                                                                                                                                                                     |
| --------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **TM\_API\_KEY**      |           | API key for [Tardis.dev](https://tardis.dev/) HTTP API - if not provided only first day of each month of historical data is accessible                                          |
| **TM\_PORT**          | `8000`    | HTTP port on which server will be running, **WebSocket port is always this value + 1** (`8001` with port set to `8000`)                                                         |
| **PORT**              |           | if set, overrides the configured port from `TM_PORT` or `--port`; useful on platforms that inject `PORT` automatically                                                          |
| **TM\_CACHE\_DIR**    | `/.cache` | path to local dir that will be used as cache location                                                                                                                           |
| **TM\_CLUSTER\_MODE** | `false`   | will launch [cluster of Node.js processes](https://nodejs.org/api/cluster.html) to handle the incoming requests if set to `true`, by default server runs in single process mode |
| **TM\_DEBUG**         | `false`   | server will print verbose debug logs to stdout if set to `true`                                                                                                                 |
| **TM\_CLEAR\_CACHE**  | `false`   | server will clear local cache dir on startup if set to `true`                                                                                                                   |

{% hint style="info" %}
The local cache grows without limit by default. For large backfills this can consume significant disk space. Use `TM_CLEAR_CACHE=true` to clear the cache on startup, or set `autoCleanup: true` in [replay options](/tardis-machine/replaying-historical-data#replay-options) to remove cached data after each replay completes. See the [replay options](/tardis-machine/replaying-historical-data#replay-options) section for `autoCleanup` concurrency caveats.
{% endhint %}

Tardis-machine also supports exchange-specific environment variables (exchange credentials, proxy, WebSocket URL overrides, Binance rate limit tuning) — see the [Node.js client environment variables](/node-client/normalization#environment-variables-advanced) for the full list.

### **npm**

{% hint style="info" %}
Requires Node.js v24+ and git installed.
{% endhint %}

{% hint style="info" %}
Node.js examples in this section use ES modules and top-level await. Save snippets as `.mjs` or set `"type": "module"` in your `package.json`.
{% endhint %}

Install and run `tardis-machine` via `npx`:

```bash
npx tardis-machine --api-key=YOUR_API_KEY
```

or install globally via `npm`:

```bash
npm install -g tardis-machine
```

and then run:

```bash
tardis-machine --api-key=YOUR_API_KEY
```

Tardis Machine HTTP endpoints will be available on port `8000` and WebSocket endpoints on port `8001`. Replace `YOUR_API_KEY` with your API key.

#### **CLI config flags**

{% hint style="info" %}
You can configure tardis-machine server via [environment variables](#config-environment-variables) as described in Docker section as well.
{% endhint %}

You can set following CLI config flags when starting tardis-machine server installed via `npm`:

| name               | default                     | description                                                                                                                                                                     |
| ------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **--api-key**      |                             | API key for [Tardis.dev](https://tardis.dev/) HTTP API - if not provided only first day of each month of historical data is accessible                                          |
| **--port**         | `8000`                      | HTTP port on which server will be running, **WebSocket port is always this value + 1** (`8001` with port set to `8000`)                                                         |
| **--cache-dir**    | `<os.tmpdir>/.tardis-cache` | path to local dir that will be used as cache location - if not provided default `temp` dir for given OS will be used                                                            |
| **--cluster-mode** | `false`                     | will launch [cluster of Node.js processes](https://nodejs.org/api/cluster.html) to handle the incoming requests if set to `true`, by default server runs in single process mode |
| **--debug**        | `false`                     | server will print verbose debug logs to stdout if set to `true`                                                                                                                 |
| **--clear-cache**  | `false`                     | server will clear local cache dir on startup is set to `true`                                                                                                                   |
| **--help**         |                             | shows CLI help                                                                                                                                                                  |
| **--version**      |                             | shows tardis-machine version number                                                                                                                                             |

## Examples

### Historical normalized replay

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

```python
import asyncio
import aiohttp
import json
import urllib.parse


async def replay_normalized(options):
    encoded_options = urllib.parse.quote_plus(json.dumps(options))
    url = f"http://localhost:8000/replay-normalized?options={encoded_options}"

    async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=0)) as session:
        async with session.get(url) as response:
            async for line in response.content:
                print(json.loads(line))


asyncio.run(
    replay_normalized(
        {
            "exchange": "binance",
            "from": "2024-03-01",
            "to": "2024-03-02",
            "symbols": ["btcusdt"],
            "dataTypes": ["trade", "book_change"],
        }
    )
)
```

{% endtab %}

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

```javascript
import split2 from "split2";
import { Readable } from "stream";

const serialize = (options) => encodeURIComponent(JSON.stringify(options));

async function* replayNormalized(options) {
  const url = `http://localhost:8000/replay-normalized?options=${serialize(options)}`;
  const response = await fetch(url);
  const lines = Readable.fromWeb(response.body).pipe(split2());

  for await (const line of lines) {
    yield JSON.parse(line);
  }
}

const messages = replayNormalized({
  exchange: "binance",
  from: "2024-03-01",
  to: "2024-03-02",
  symbols: ["btcusdt"],
  dataTypes: ["trade", "book_change"],
});

for await (const message of messages) {
  console.log(message);
}
```

{% endtab %}
{% endtabs %}

{% content-ref url="/pages/2BAG1UWBJPCuk9zXug9y" %}
[Replaying Historical Data](/tardis-machine/replaying-historical-data)
{% endcontent-ref %}

### Real-time normalized streaming

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

```python
import asyncio
import aiohttp
import json
import urllib.parse


async def main():
    stream_options = {
        "exchange": "binance",
        "symbols": ["btcusdt"],
        "dataTypes": ["trade", "book_change"],
    }
    options = urllib.parse.quote_plus(json.dumps(stream_options))
    url = f"ws://localhost:8001/ws-stream-normalized?options={options}"

    async with aiohttp.ClientSession() as session:
        async with session.ws_connect(url) as websocket:
            async for message in websocket:
                print(message.data)


asyncio.run(main())
```

{% endtab %}

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

```javascript
import WebSocket from "ws";

const options = encodeURIComponent(
  JSON.stringify({
    exchange: "binance",
    symbols: ["btcusdt"],
    dataTypes: ["trade", "book_change"],
  }),
);

const ws = new WebSocket(
  `ws://localhost:8001/ws-stream-normalized?options=${options}`,
);

ws.onmessage = (message) => {
  console.log(message.data);
};
```

{% endtab %}
{% endtabs %}

{% content-ref url="/pages/IaFlsH1FFOKOxW2QHpgn" %}
[Streaming Real-Time Data](/tardis-machine/streaming-real-time-data)
{% endcontent-ref %}


# Replaying Historical Data

HTTP and WebSocket replay endpoints with options and response formats

HTTP and WebSocket endpoints for tick-by-tick historical market data replay in both exchange-native and normalized formats.

## Exchange-native market data APIs

Exchange-native market data API endpoints provide historical data in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format). The main difference between HTTP and WebSocket endpoints is the logic of requesting data:

* [HTTP API](#http-get-replay-options-options) accepts [request options](#replay-options) payload via query string param
* [WebSocket API](#websocket-ws-replay-exchange-exchange-and-from-fromdate-and-to-todate) accepts exchanges' specific 'subscribe' messages that define what data will be then "replayed" and send to WebSocket client

### `HTTP GET` /replay?options={options}

Returns historical market data messages in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) for given replay options query string param. Single streaming HTTP response returns data for the whole requested time period as [NDJSON](http://ndjson.org/).

{% hint style="info" %}
In our preliminary benchmarks on AMD Ryzen 7 3700X, 64GB RAM, [HTTP /replay](#http-get-replay-options-options) API endpoint was returning \~700 000 messages/s (already locally cached data).
{% endhint %}

{% hint style="warning" %}
A single replay request can fan out into many upstream `/data-feeds` requests. Running multiple concurrent replay processes can quickly exceed [API rate limits](/api/rate-limits), causing stalls without visible error messages.
{% endhint %}

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

```python
import asyncio
import aiohttp
import json
import urllib.parse


async def replay_via_tardis_machine(replay_options):
    timeout = aiohttp.ClientTimeout(total=0)

    async with aiohttp.ClientSession(timeout=timeout) as session:
        # url encode as json object options
        encoded_options = urllib.parse.quote_plus(json.dumps(replay_options))

        # assumes tardis-machine HTTP API running on localhost:8000
        url = f"http://localhost:8000/replay?options={encoded_options}"

        async with session.get(url) as response:
            # otherwise we may get line to long errors
            response.content._high_water = 100_000_000

            # returned data is in NDJSON format http://ndjson.org/
            # each line is separate message JSON encoded
            async for line in response.content:
                yield line


async def main():
    lines = replay_via_tardis_machine(
        {
            "exchange": "binance",
            "from": "2024-03-01",
            "to": "2024-03-02",
            "filters": [
                {"channel": "trade", "symbols": ["btcusdt"]},
                {"channel": "depth", "symbols": ["btcusdt"]},
            ],
        }
    )

    async for line in lines:
        message = json.loads(line)
        # localTimestamp string marks timestamp when message was received
        # message is a message dict as provided by exchange real-time stream
        print(message["localTimestamp"], message["message"])


asyncio.run(main())
```

{% hint style="info" %}
See also official Tardis.dev [Python client](/python-client/quickstart) library.
{% endhint %}
{% endtab %}

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

```javascript
import split2 from 'split2'
import { Readable } from 'stream'


const serialize = options => {
  return encodeURIComponent(JSON.stringify(options))
}

async function* replayViaTardisMachine(options) {
  // assumes tardis-machine HTTP API running on localhost:8000
  const url = `http://localhost:8000/replay?options=${serialize(options)}`
  const response = await fetch(url)

  // returned data is in NDJSON format http://ndjson.org/
  // each line is separate message JSON encoded

  // split response body stream by new lines
  const lines = Readable.fromWeb(response.body).pipe(split2())

  for await (const line of lines) {
    yield line
  }
}

const options = {
  exchange: 'binance',
  from: '2024-03-01',
  to: '2024-03-02',
  filters: [
    {
      channel: 'trade',
      symbols: ['btcusdt']
    },
    {
      channel: 'depth',
      symbols: ['btcusdt']
    }
  ]
}

const lines = replayViaTardisMachine(options)

for await (const line of lines) {
  // localTimestamp string marks timestamp when message was received
  // message is a message object as provided by exchange real-time stream
  const { message, localTimestamp } = JSON.parse(line)

  console.log(message, localTimestamp)
}
```

{% hint style="info" %}
See also official Tardis.dev [Node.js client](/node-client/quickstart) library.
{% endhint %}
{% endtab %}

{% tab title="cURL" %}

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance","filters":[{"channel":"trade","symbols":["btcusdt"]},{"channel":"depth","symbols":["btcusdt"]}],"from":"2024-03-01","to":"2024-03-02"}'
```

{% embed url="<http://localhost:8000/replay?options={%22exchange%22:%22binance%22,%22filters%22:[{%22channel%22:%22trade%22,%22symbols%22:[%22btcusdt%22]},{%22channel%22:%22depth%22,%22symbols%22:[%22btcusdt%22]}],%22from%22:%222024-03-01%22,%22to%22:%222024-03-02%22}>" %}
Click to see API response in the browser as long as tardis-machine is running on localhost:8000
{% endembed %}
{% endtab %}

{% tab title="Your preferred language" %}
We're working on providing more samples and dedicated client libraries in different languages, but in the meanwhile to consume [HTTP /replay](#http-get-replay-options-options) API responses in your language of choice, you should:

1. Provide url encoded JSON [options object](#replay-options) via options query string param when sending HTTP request
2. Parse HTTP response stream line by line as it's returned - buffering in memory whole response may result in slow performance and memory overflows
3. Parse each response line as JSON containing messages in [exchange-native format](#response-format)
   {% endtab %}
   {% endtabs %}

#### Replay options

[HTTP /replay](#http-get-replay-options-options) endpoint accepts required options query string param in **url encoded JSON format**.

| name                            | type                                     | default   | description                                                                                                                                                                                                                                                                          |
| ------------------------------- | ---------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **exchange**                    | string                                   | -         | requested exchange id - use [/exchanges HTTP API](/api/http-api-reference#exchanges) to get list of valid exchanges ids                                                                                                                                                              |
| **filters**                     | {channel:string, symbols?: string\[]}\[] | \[]       | optional filters of requested historical data feed - check [historical data details](/historical-data-details/overview) for each exchange and [/exchanges/:exchange HTTP API](/api/http-api-reference#exchanges-exchange) to get allowed channels and symbols for requested exchange |
| **from**                        | string                                   | -         | replay period start date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-01`                                                                                                                                                                    |
| **to**                          | string                                   | -         | replay period end date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-02`                                                                                                                                                                      |
| **withDisconnects**             | boolean (optional)                       | undefined | when set to `true`, response includes empty lines (`\n`) that mark events when real-time WebSocket connection that was used to collect the historical data got disconnected                                                                                                          |
| **waitWhenDataNotYetAvailable** | boolean or number (optional)             | undefined | when set to `true`, waits for data that is not yet available — useful when replaying near real-time data. Defaults to a 30-minute offset. When set to a number, specifies the offset in minutes (minimum effective value is 6 minutes).                                              |
| **autoCleanup**                 | boolean (optional)                       | undefined | when set to `true`, automatically removes cached data from disk after it has been processed. Not safe for concurrent replay — see [warning](#replay-options)                                                                                                                         |
| **withMicroseconds**            | boolean (optional)                       | undefined | when set to `true`, `localTimestamp` in response is returned with microsecond precision                                                                                                                                                                                              |

When `symbols` array is empty or omitted in filters, data for all active symbols is returned.

{% hint style="info" %}
**Disconnect markers**: An empty line in raw replay (or a `disconnect` message in normalized replay) indicates that the WebSocket connection used during data collection was interrupted. After a reconnect, exchanges typically re-send initial snapshots, so duplicate snapshot messages are expected following a disconnect marker. Disconnect markers apply to the entire connection, not individual channels.
{% endhint %}

{% hint style="warning" %}
**`autoCleanup` concurrency**: avoid using `autoCleanup` with concurrent replay — the cache path is keyed by exchange, a hash of the filters, and the calendar day, so any concurrent jobs sharing those three components will conflict (even with non-overlapping time windows within the same day) and cause file-not-found errors. Clean the cache manually after all jobs complete instead.
{% endhint %}

#### **Response format**

Streamed HTTP response provides data in NDJSON format (new line delimited JSON) - each response line is a JSON with market data message in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) plus local timestamp:

* `localTimestamp` - date when message has been received in ISO 8601 format
* `message` - JSON with exactly the same format as provided by requested exchange real-time feeds

**Sample response**

```javascript
{"localTimestamp":"2024-03-01T00:00:00.001409Z","message":{"stream":"btcusdt@trade","data":{"e":"trade","E":1709251199998,"s":"BTCUSDT","t":3445374963,"p":"61130.98000000","q":"0.00145000","b":25230662315,"a":25230662808,"T":1709251199998,"m":true,"M":true}}}
{"localTimestamp":"2024-03-01T00:00:00.001417Z","message":{"stream":"btcusdt@trade","data":{"e":"trade","E":1709251199999,"s":"BTCUSDT","t":3445374964,"p":"61130.98000000","q":"0.00182000","b":25230662315,"a":25230662809,"T":1709251199998,"m":true,"M":true}}}
{"localTimestamp":"2024-03-01T00:00:00.001423Z","message":{"stream":"btcusdt@trade","data":{"e":"trade","E":1709251199999,"s":"BTCUSDT","t":3445374965,"p":"61130.98000000","q":"0.00034000","b":25230662315,"a":25230662810,"T":1709251199998,"m":true,"M":true}}}
{"localTimestamp":"2024-03-01T00:00:00.001429Z","message":{"stream":"btcusdt@trade","data":{"e":"trade","E":1709251200000,"s":"BTCUSDT","t":3445374966,"p":"61130.98000000","q":"0.00182000","b":25230662315,"a":25230662811,"T":1709251199999,"m":true,"M":true}}}
{"localTimestamp":"2024-03-01T00:00:00.006791Z","message":{"stream":"btcusdt@trade","data":{"e":"trade","E":1709251200000,"s":"BTCUSDT","t":3445374967,"p":"61130.98000000","q":"0.00038000","b":25230662315,"a":25230662812,"T":1709251199999,"m":true,"M":true}}}
```

### `WebSocket` /ws-replay?exchange={exchange}\&from={fromDate}\&to={toDate}

Exchanges' WebSocket APIs are designed to publish real-time market data feeds, not historical ones. Tardis-machine [WebSocket /ws-replay](#websocket-ws-replay-exchange-exchange-and-from-fromdate-and-to-todate) API fills that gap and allows "replaying" historical market data from any given past point in time with the same data format and 'subscribe' logic as real-time exchanges' APIs. In many cases existing exchanges' WebSocket clients can be used to connect to this endpoint just by changing URL, and receive historical market data in [exchange-native](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) format for date ranges specified in URL query string params.

After connection is established, client has 2 seconds to send subscriptions payloads and then market data replay starts.

If two clients connect at the same time requesting data for different exchanges and provide the same [session key via query string param](#query-string-params), then data being send to those clients will be synchronized (by local timestamp).

{% hint style="info" %}
In our preliminary benchmarks on AMD Ryzen 7 3700X, 64GB RAM, [WebSocket /ws-replay](#websocket-ws-replay-exchange-exchange-and-from-fromdate-and-to-todate) API endpoint was sending \~500 000 messages/s (already locally cached data).
{% endhint %}

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

```python
import asyncio
import aiohttp
import json


async def main():
    WS_REPLAY_URL = "ws://localhost:8001/ws-replay"
    URL = f"{WS_REPLAY_URL}?exchange=binance&from=2024-03-01&to=2024-03-02"

    async with aiohttp.ClientSession() as session:
        async with session.ws_connect(URL) as websocket:

            await websocket.send_str(
                json.dumps(
                    {
                        "method": "SUBSCRIBE",
                        "params": ["btcusdt@trade", "btcusdt@depth@100ms"],
                        "id": 1,
                    }
                )
            )

            async for msg in websocket:
                print(msg.data)


asyncio.run(main())
```

{% hint style="info" %}
You can also try using existing WebSocket client by changing URL endpoint to the one shown in the example above.
{% endhint %}
{% endtab %}

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

```javascript
import WebSocket from 'ws'


const WS_REPLAY_URL = 'ws://localhost:8001/ws-replay'

const ws = new WebSocket(
  `${WS_REPLAY_URL}?exchange=binance&from=2024-03-01&to=2024-03-02`
)

ws.onmessage = message => {
  console.log(message.data)
}

ws.onopen = () => {
  ws.send(
    JSON.stringify({
      method: 'SUBSCRIBE',
      params: ['btcusdt@trade', 'btcusdt@depth@100ms'],
      id: 1
    })
  )
}
```

{% hint style="info" %}
You can also use existing WebSocket client by changing URL endpoint to the one shown in the example above.
{% endhint %}
{% endtab %}

{% tab title="Your preferred language" %}
As long as you already use existing WebSocket client that connects to and consumes real-time exchange market data feed, in most cases you can use it to connect to [/ws-replay](#websocket-ws-replay-exchange-exchange-and-from-fromdate-and-to-todate) API as well just by changing URL endpoint.
{% endtab %}
{% endtabs %}

#### **Query string params**

| name         | type              | default   | description                                                                                                                                                                          |
| ------------ | ----------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **exchange** | string            | -         | requested exchange id - use [/exchanges HTTP API](/api/http-api-reference#exchanges) to get list of valid exchanges ids                                                              |
| **from**     | string            | -         | replay period start date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-01`                                                                    |
| **to**       | string            | -         | replay period end date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-02`                                                                      |
| **session**  | string (optional) | undefined | optional replay session key. When specified and multiple clients use it when connecting at the same time then data being send to those clients is synchronized (by local timestamp). |

## Normalized market data APIs

Normalized market data API endpoints provide data in [unified format](/tardis-machine/data-types) across all supported exchanges. Both [HTTP /replay-normalized](#http-get-replay-normalized-options-options) and [WebSocket /ws-replay-normalized](#websocket-ws-replay-normalized-options-options) APIs accept the same replay options payload via query string param. It's mostly a matter of preference when choosing which protocol to use, but [WebSocket /ws-replay-normalized API](#websocket-ws-replay-normalized-options-options) also has its real-time counterpart [/ws-stream-normalized](/tardis-machine/streaming-real-time-data#websocket-ws-stream-normalized-options-options), which connects directly to exchanges' real-time WebSocket APIs. This opens the **possibility of seamless switching between real-time streaming and historical normalized market data replay**.

### `HTTP GET` /replay-normalized?options={options}

Returns historical market data for [data types](#replay-normalized-options) specified via query string. Single streaming HTTP response returns data for the whole requested time period as [NDJSON](http://ndjson.org/). See [supported data types](/tardis-machine/data-types) which include normalized [trade](/tardis-machine/data-types#trade), [order book change](/tardis-machine/data-types#book_change), [customizable order book snapshots](/tardis-machine/data-types#book_snapshot_-number_of_levels-_-snapshot_interval-time_unit) etc.

{% hint style="info" %}
In our preliminary benchmarks on AMD Ryzen 7 3700X, 64GB RAM, [HTTP /replay-normalized](#http-get-replay-normalized-options-options) API endpoint was returning \~100 000 messages/s and \~50 000 messages/s when order book snapshots were also requested.
{% endhint %}

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

```python
import asyncio
import aiohttp
import json
import urllib.parse


async def replay_normalized_via_tardis_machine(replay_options):
    timeout = aiohttp.ClientTimeout(total=0)

    async with aiohttp.ClientSession(timeout=timeout) as session:
        # url encode as json object options
        encoded_options = urllib.parse.quote_plus(json.dumps(replay_options))

        # assumes tardis-machine HTTP API running on localhost:8000
        url = f"http://localhost:8000/replay-normalized?options={encoded_options}"

        async with session.get(url) as response:
            # otherwise we may get line to long errors
            response.content._high_water = 100_000_000

            # returned data is in NDJSON format http://ndjson.org/ streamed
            # each line is separate message JSON encoded
            async for line in response.content:
                yield line


async def main():
    lines = replay_normalized_via_tardis_machine(
        {
            "exchange": "binance",
            "from": "2024-03-01",
            "to": "2024-03-02",
            "symbols": ["btcusdt"],
            "withDisconnectMessages": True,
            # other available data types examples:
            # 'book_snapshot_10_100ms', 'derivative_ticker', 'quote',
            # 'trade_bar_10ms', 'trade_bar_10s'
            "dataTypes": ["trade", "book_change", "book_snapshot_10_100ms"],
        }
    )

    async for line in lines:
        normalized_message = json.loads(line)
        print(normalized_message)


asyncio.run(main())
```

{% endtab %}

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

```javascript
import split2 from 'split2'
import { Readable } from 'stream'


const serialize = options => {
  return encodeURIComponent(JSON.stringify(options))
}

async function* replayNormalizedViaTardisMachine(options) {
  // assumes tardis-machine HTTP API running on localhost:8000
  const url = `http://localhost:8000/replay-normalized?options=${serialize(
    options
  )}`
  const response = await fetch(url)

  // returned data is in NDJSON format http://ndjson.org/
  // each line is separate message JSON encoded

  // split response body stream by new lines
  const lines = Readable.fromWeb(response.body).pipe(split2())

  for await (const line of lines) {
    yield line
  }
}

const options = {
  exchange: 'binance',
  from: '2024-03-01',
  to: '2024-03-02',
  symbols: ['btcusdt'],
  withDisconnectMessages: true,
  // other available data types examples:
  // 'book_snapshot_10_100ms', 'derivative_ticker', 'quote',
  // 'trade_bar_10ms', 'trade_bar_10s'
  dataTypes: ['trade', 'book_change', 'book_snapshot_10_100ms']
}

const lines = replayNormalizedViaTardisMachine(options)

for await (const line of lines) {
  const normalizedMessage = JSON.parse(line)

  console.log(normalizedMessage)
}
```

{% hint style="info" %}
See also official Tardis.dev [Node.js client](/node-client/quickstart) library.
{% endhint %}
{% endtab %}

{% tab title="cURL" %}

```bash
curl -g 'http://localhost:8000/replay-normalized?options={"exchange":"binance","from":"2024-03-01","to":"2024-03-02","symbols":["btcusdt"],"withDisconnectMessages":true,"dataTypes":["trade","book_change","book_snapshot_10_100ms"]}'
```

{% embed url="<http://localhost:8000/replay-normalized?options={%22exchange%22:%22binance%22,%22from%22:%222024-03-01%22,%22to%22:%222024-03-02%22,%22symbols%22:[%22btcusdt%22],%22withDisconnectMessages%22:true,%22dataTypes%22:[%22trade%22,%22book_change%22,%22book_snapshot_10_100ms%22]}>" %}
Click to see API response in the browser as long as tardis-machine is running on localhost:8000
{% endembed %}
{% endtab %}

{% tab title="Your preferred language" %}
We're working on providing more samples and dedicated client libraries in different languages, but in the meanwhile to consume [HTTP /replay-normalized](#http-get-replay-normalized-options-options) API responses in your language of choice, you should:

1. Provide URL-encoded JSON [options](#replay-normalized-options) via the options query string parameter when sending an HTTP request
2. Parse HTTP response stream line by line as it's returned - buffering in memory whole response may result in slow performance and memory overflows
3. Parse each response line as JSON containing [normalized data messages](/tardis-machine/data-types).
   {% endtab %}
   {% endtabs %}

#### Replay normalized options

[HTTP /replay-normalized](#http-get-replay-normalized-options-options) endpoint accepts required options query string param in **url encoded JSON format**.

Options JSON needs to be an object or an array of objects with fields as specified below. If array is provided, then data requested for multiple exchanges is returned synchronized (by local timestamp).

**Synchronized multi-exchange example**

The same `options` array format works for both [`HTTP /replay-normalized`](#http-get-replay-normalized-options-options) and [`WebSocket /ws-replay-normalized`](#websocket-ws-replay-normalized-options-options). For example, to replay synchronized normalized trades from Binance and OKX for the same symbol and time range:

```bash
curl -g 'http://localhost:8000/replay-normalized?options=[{"exchange":"binance","from":"2024-03-01","to":"2024-03-02","symbols":["btcusdt"],"dataTypes":["trade"]},{"exchange":"okex","from":"2024-03-01","to":"2024-03-02","symbols":["btcusdt"],"dataTypes":["trade"]}]'
```

Each response line is still a single normalized message, but messages from both exchanges are merged into one stream and ordered by `localTimestamp`.

| name                            | type                         | default   | description                                                                                                                                                                                                                             |
| ------------------------------- | ---------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **exchange**                    | string                       | -         | requested exchange id - use [/exchanges HTTP API](/api/http-api-reference#exchanges) to get list of valid exchanges ids                                                                                                                 |
| **symbols**                     | string\[] (optional)         | undefined | optional symbols of requested historical data feed - use [/exchanges/:exchange HTTP API](/api/http-api-reference#exchanges-exchange) to get allowed symbols for requested exchange                                                      |
| **from**                        | string                       | -         | replay period start date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-01`                                                                                                                       |
| **to**                          | string                       | -         | replay period end date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-02`                                                                                                                         |
| **dataTypes**                   | string\[]                    | -         | array of normalized [data types](/tardis-machine/data-types) for which historical data will be returned                                                                                                                                 |
| **withDisconnectMessages**      | boolean (optional)           | undefined | when set to `true`, response includes [disconnect](/tardis-machine/data-types#disconnect) messages that mark events when real-time WebSocket connection that was used to collect the historical data got disconnected                   |
| **waitWhenDataNotYetAvailable** | boolean or number (optional) | undefined | when set to `true`, waits for data that is not yet available — useful when replaying near real-time data. Defaults to a 30-minute offset. When set to a number, specifies the offset in minutes (minimum effective value is 6 minutes). |
| **autoCleanup**                 | boolean (optional)           | undefined | when set to `true`, automatically removes cached data from disk after it has been processed. Not safe for concurrent replay — see [warning](#replay-options)                                                                            |

#### **Response format & sample messages**

See [Output Data Types](/tardis-machine/data-types).

### `WebSocket` /ws-replay-normalized?options={options}

Sends [normalized](/tardis-machine/data-types) historical market data for [data types](#replay-normalized-options-1) specified via query string. See [supported data types](/tardis-machine/data-types) which include normalized [trade](/tardis-machine/data-types#trade), [order book change](/tardis-machine/data-types#book_change), [customizable order book snapshots](/tardis-machine/data-types#book_snapshot_-number_of_levels-_-snapshot_interval-time_unit) etc.

{% hint style="info" %}
[WebSocket /ws-stream-normalized](/tardis-machine/streaming-real-time-data#websocket-ws-stream-normalized-options-options) is the real-time counterpart of this API endpoint, providing real-time market data in the same format, but not requiring API key as connects directly to exchanges' real-time WebSocket APIs.
{% endhint %}

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

```python
import asyncio
import aiohttp
import json
import urllib.parse


async def main():
    replay_options = {
        "exchange": "binance",
        "from": "2024-03-01",
        "to": "2024-03-02",
        "symbols": ["btcusdt"],
        "withDisconnectMessages": True,
        # other available data types examples:
        # 'book_snapshot_10_100ms', 'derivative_ticker', 'quote',
        # 'trade_bar_10ms', 'trade_bar_10s'
        "dataTypes": ["trade", "book_change", "book_snapshot_10_100ms"],
    }

    options = urllib.parse.quote_plus(json.dumps(replay_options))

    URL = f"ws://localhost:8001/ws-replay-normalized?options={options}"

    async with aiohttp.ClientSession() as session:
        async with session.ws_connect(URL) as websocket:
            async for msg in websocket:
                print(msg.data)


asyncio.run(main())
```

{% endtab %}

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

```javascript
import WebSocket from 'ws'


const serialize = options => {
  return encodeURIComponent(JSON.stringify(options))
}

const replayOptions = {
  exchange: 'binance',
  from: '2024-03-01',
  to: '2024-03-02',
  symbols: ['btcusdt'],
  withDisconnectMessages: true,
  // other available data types examples:
  // 'book_snapshot_10_100ms', 'derivative_ticker', 'quote',
  // 'trade_bar_10ms', 'trade_bar_10s'
  dataTypes: ['trade', 'book_change', 'book_snapshot_10_100ms']
}

const options = serialize(replayOptions)
const URL = `ws://localhost:8001/ws-replay-normalized?options=${options}`
const ws = new WebSocket(URL)

ws.onmessage = message => {
  console.log(message.data)
}

```

{% hint style="info" %}
See also official Tardis.dev [Node.js client](/node-client/quickstart) library.
{% endhint %}
{% endtab %}

{% tab title="Your preferred language" %}
We're working on providing more samples and dedicated client libraries in different languages, but in the meanwhile to consume [WebSocket /ws-replay-normalized](#websocket-ws-replay-normalized-options-options) API responses in your language of choice, you should:

1. Provide url encoded JSON [options](#replay-normalized-options-1) via options query string param when connecting to

   [WebSocket /ws-replay-normalized](#websocket-ws-replay-normalized-options-options) endpoint
2. Parse each received WebSocket message as JSON containing [normalized data](/tardis-machine/data-types).
   {% endtab %}
   {% endtabs %}

#### Replay normalized options

[WebSocket /ws-replay-normalized](#websocket-ws-replay-normalized-options-options) endpoint accepts required options query string param in **url encoded JSON format**.

Options JSON needs to be an object or an array of objects with fields as specified below. If array is provided, then data requested for multiple exchanges is sent synchronized (by local timestamp). See the [multi-exchange example above](#replay-normalized-options).

| name                            | type                         | default   | description                                                                                                                                                                                                                             |
| ------------------------------- | ---------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **exchange**                    | string                       | -         | requested exchange id - use [/exchanges HTTP API](/api/http-api-reference#exchanges) to get list of valid exchanges ids                                                                                                                 |
| **symbols**                     | string\[] (optional)         | undefined | optional symbols of requested historical data feed - use [/exchanges/:exchange HTTP API](/api/http-api-reference#exchanges-exchange) to get allowed symbols for requested exchange                                                      |
| **from**                        | string                       | -         | replay period start date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-01`                                                                                                                       |
| **to**                          | string                       | -         | replay period end date (UTC) in a [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g., `2019-04-02`                                                                                                                         |
| **dataTypes**                   | string\[]                    | -         | array of normalized [data types](/tardis-machine/data-types) for which historical data will be provided                                                                                                                                 |
| **withDisconnectMessages**      | boolean (optional)           | undefined | when set to `true`, sends also [disconnect](/tardis-machine/data-types#disconnect) messages that mark events when real-time WebSocket connection that was used to collect the historical data got disconnected                          |
| **waitWhenDataNotYetAvailable** | boolean or number (optional) | undefined | when set to `true`, waits for data that is not yet available — useful when replaying near real-time data. Defaults to a 30-minute offset. When set to a number, specifies the offset in minutes (minimum effective value is 6 minutes). |
| **autoCleanup**                 | boolean (optional)           | undefined | when set to `true`, automatically removes cached data from disk after it has been processed. Not safe for concurrent replay — see [warning](#replay-options)                                                                            |

{% hint style="info" %}
In our preliminary benchmarks on AMD Ryzen 7 3700X, 64GB RAM, [WebSocket /ws-replay-normalized](#websocket-ws-replay-normalized-options-options) API endpoint was returning \~70 000 messages/s and \~40 000 messages/s when order book snapshots were also requested.
{% endhint %}

#### **Response format & sample messages**

See [Output Data Types](/tardis-machine/data-types).


# Streaming Real-Time Data

WebSocket endpoint for consolidated real-time normalized market data streaming

## `WebSocket` /ws-stream-normalized?options={options}

Sends [normalized](/tardis-machine/data-types) real-time market data for [data types](#stream-normalized-options) specified via query string. See [supported data types](/tardis-machine/data-types) which include normalized [trade](/tardis-machine/data-types#trade), [order book change](/tardis-machine/data-types#book_change), [customizable order book snapshots](/tardis-machine/data-types#book_snapshot_-number_of_levels-_-snapshot_interval-time_unit) etc.

**Doesn't require an API key, as it connects directly to exchanges' real-time WebSocket APIs** and transparently restarts closed, broken, or stale connections (open connections without data being sent for a specified amount of time).

Provides **consolidated real-time market data streaming** functionality with [options](#stream-normalized-options) as an array - provides single consolidated real-time data stream for all exchanges specified in [options array](#stream-normalized-options).

{% hint style="info" %}
[WebSocket /ws-replay-normalized](/tardis-machine/replaying-historical-data#websocket-ws-replay-normalized-options-options) is the historical counterpart of this API endpoint, providing historical market data in the same format.
{% endhint %}

{% hint style="info" %}
Tardis-machine provides real-time streaming only for [normalized data types](/tardis-machine/data-types). If you need real-time data in exchange-native format, connect directly to the exchange's WebSocket API.
{% endhint %}

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

```python
import asyncio
import aiohttp
import json
import urllib.parse


async def main():
    data_types = ["trade", "book_change", "book_snapshot_10_100ms"]

    stream_options = [
        {
            "exchange": "binance",
            "symbols": ["btcusdt"],
            "dataTypes": data_types,
        },
        {
            "exchange": "binance-futures",
            "symbols": ["BTCUSDT"],
            "dataTypes": data_types,
        },
    ]

    options = urllib.parse.quote_plus(json.dumps(stream_options))

    URL = f"ws://localhost:8001/ws-stream-normalized?options={options}"
    # real-time normalized data for two exchanges via single connection
    async with aiohttp.ClientSession() as session:
        async with session.ws_connect(URL) as websocket:

            async for msg in websocket:
                print(msg.data)


asyncio.run(main())
```

{% endtab %}

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

```javascript
import WebSocket from 'ws'


const serialize = options => {
  return encodeURIComponent(JSON.stringify(options))
}
// other available data types examples:
// 'book_snapshot_10_100ms', 'derivative_ticker', 'quote',
// 'trade_bar_10ms', 'trade_bar_10s'
const dataTypes = ['trade', 'book_change', 'book_snapshot_10_100ms']

const streamOptions = [
  {
    exchange: 'binance',
    symbols: ['btcusdt'],
    dataTypes
  },
  {
    exchange: 'binance-futures',
    symbols: ['BTCUSDT'],
    dataTypes
  }
]

const options = serialize(streamOptions)
const URL = `ws://localhost:8001/ws-stream-normalized?options=${options}`
const ws = new WebSocket(URL)
// real-time normalized data for two exchanges via single connection
ws.onmessage = message => {
  console.log(message.data)
}
```

{% hint style="info" %}
See also official Tardis.dev [Node.js client](/node-client/quickstart) library.
{% endhint %}
{% endtab %}

{% tab title="Your preferred language" %}
We're working on providing more samples and dedicated client libraries in different languages, but in the meanwhile to consume [WebSocket /ws-stream-normalized](#websocket-ws-stream-normalized-options-options) API responses in your language of choice, you should:

1. Provide url encoded JSON [options](#stream-normalized-options) via options query string param when connecting to

   [WebSocket /ws-stream-normalized](#websocket-ws-stream-normalized-options-options) endpoint
2. Parse each received WebSocket message as JSON containing [normalized data](/tardis-machine/data-types).
   {% endtab %}
   {% endtabs %}

#### Stream normalized options

[WebSocket /ws-stream-normalized](#websocket-ws-stream-normalized-options-options) endpoint accepts required options query string param in **url encoded JSON format**.

Options JSON needs to be an object or an array of objects with fields as specified below. If array is specified then API provides single consolidated real-time data stream for all exchanges specified (as in examples above).

| name                       | type                 | default   | description                                                                                                                                                                                                                              |
| -------------------------- | -------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **exchange**               | string               | -         | requested exchange id - use [/exchanges HTTP API](/api/http-api-reference#exchanges) to get list of valid exchanges ids                                                                                                                  |
| **symbols**                | string\[] (optional) | undefined | optional symbols of requested real-time data feed                                                                                                                                                                                        |
| **dataTypes**              | string\[]            | -         | array of normalized [data types](/tardis-machine/data-types) for which real-time data will be provided                                                                                                                                   |
| **withDisconnectMessages** | boolean (optional)   | undefined | when set to `true`, sends [disconnect](/tardis-machine/data-types#disconnect) messages anytime underlying exchange real-time WebSocket connection(s) gets disconnected                                                                   |
| **timeoutIntervalMS**      | number               | 10000     | specifies time in milliseconds after which connection to real-time exchanges' WebSocket API is restarted if no message has been received                                                                                                 |
| **withErrorMessages**      | boolean (optional)   | undefined | when set to `true`, sends `error` messages whenever an underlying exchange WebSocket connection error occurs. Error message format: `{"type":"error","exchange":"...","localTimestamp":"...","details":"...","subSequentErrorsCount":1}` |

{% hint style="info" %}
**Tips:**

* For sparse instruments (e.g., illiquid options), increase `timeoutIntervalMS` (e.g., `60000`) to prevent unnecessary connection restarts when no messages arrive for extended periods. This is especially important for `trade_bar_*` data types on low-volume symbols.
* When providing `options` as an array, each element creates a separate WebSocket connection to the target exchange. This can be used for multi-exchange streaming, but also for the same exchange — for example, to work around per-connection limits on the number of symbols or channels.
  {% endhint %}

#### **Response format & sample messages**

See [Output Data Types](/tardis-machine/data-types).


# Data Types

Normalized schemas for trade, book\_change, book\_snapshot and more

Schema reference for normalized data types returned by tardis-machine replay and streaming APIs.

* [trade](#trade)
* [book\_change](#book_change)
* [book\_ticker](#book_ticker)
* [derivative\_ticker](#derivative_ticker)
* [quote\_{snapshot\_interval}{time\_unit}](#book_snapshot_-number_of_levels-_-snapshot_interval-time_unit)
* [book\_snapshot\_{number\_of\_levels}\_{snapshot\_interval}{time\_unit}](#book_snapshot_-number_of_levels-_-snapshot_interval-time_unit)
* [trade\_bar\_{aggregation\_interval}{suffix}](#trade_bar_-aggregation_interval-suffix)
* [liquidation](#liquidation)
* [option\_summary](#option_summary)
* [disconnect](#disconnect)
* [error](#error)

### trade

Individual trade

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "trade",
  "symbol": "BTCUSDT",
  "exchange": "binance",
  "id": "3445374963",
  "price": 61130.98,
  "amount": 0.00145,
  "side": "sell",
  "timestamp": "2024-02-29T23:59:59.998Z",
  "localTimestamp": "2024-03-01T00:00:00.001Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'trade'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  id: string | undefined // trade id if provided by exchange
  price: number // trade price as provided by exchange
  amount: number // trade amount as provided by exchange
  side: 'buy' | 'sell' | 'unknown' // liquidity taker side (aggressor)
  timestamp: string // trade timestamp provided by exchange (ISO 8601 format)
  localTimestamp: string // message arrival timestamp (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

### book\_change

Initial [L2 (market by price)](/faq/order-books#what-l2-order-book-data-can-be-used-for) order book snapshot (`isSnapshot=true`) plus incremental updates for each order book change. Please note that `amount` is the updated amount at that price level, not a delta. An `amount` of `0` indicates the price level can be removed.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "book_change",
  "symbol": "BTCUSDT",
  "exchange": "binance",
  "isSnapshot": false,
  "bids": [
    {
      "price": 61141.09,
      "amount": 2.02515
    }
  ],
  "asks": [
    {
      "price": 61141.1,
      "amount": 4.09368
    }
  ],
  "timestamp": "2024-03-01T00:00:01.489Z",
  "localTimestamp": "2024-03-01T00:00:01.491Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'book_change'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  isSnapshot: boolean // if true marks initial order book snapshot
  bids: { price: number; amount: number }[] // updated bids price-amount levels
  asks: { price: number; amount: number }[] // updated asks price-amount levels
  timestamp: string // order book update timestamp if provided by exchange,
                    // otherwise equals to localTimestamp, (ISO 8601 format)
  localTimestamp: string // message arrival timestamp (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

When processing `book_change` updates: an `amount` of `0` means remove that price level. If you receive a removal for a price level not in your local book, ignore it. Snapshot levels may include zero-amount entries — these should also be treated as absent levels.

### book\_ticker

Top of the book (best bid/ask) data from exchanges' native best bid/offer channels (e.g., Binance `bookTicker`, Bybit `orderbook.1`). Unlike [`quote`](#book_snapshot_-number_of_levels-_-snapshot_interval-time_unit) which is derived from L2 order book data, `book_ticker` is sourced from the native exchange-provided WebSocket best bid/offer feed.

Because it is a standalone feed, `book_ticker` replay can start from any point in time, whereas `quote` requires starting from 00:00 UTC (when the initial L2 order book snapshot is provided).

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "book_ticker",
  "symbol": "BTCUSDT",
  "exchange": "binance-futures",
  "askPrice": 63125.5,
  "askAmount": 2.5,
  "bidPrice": 63125.4,
  "bidAmount": 1.8,
  "timestamp": "2024-01-15T10:30:00.123Z",
  "localTimestamp": "2024-01-15T10:30:00.234Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'book_ticker'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  askPrice: number | undefined // best ask price, undefined if there aren't any asks
  askAmount: number | undefined // best ask amount, undefined if there aren't any asks
  bidPrice: number | undefined // best bid price, undefined if there aren't any bids
  bidAmount: number | undefined // best bid amount, undefined if there aren't any bids
  timestamp: string // message timestamp provided by exchange (ISO 8601 format)
  localTimestamp: string // message arrival timestamp (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

### derivative\_ticker

Derivative instrument ticker info sourced from real-time ticker & instrument channels.

Funding fields describe upcoming funding events relative to the message timestamp. `fundingTimestamp` is the next funding event time: the immediately upcoming event, not a previously settled funding time. `fundingRate` is the rate for that next event and can change until the event occurs. `predictedFundingRate`, when present, estimates the following funding event.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "derivative_ticker",
  "symbol": "BTCUSDT",
  "exchange": "binance-futures",
  "lastPrice": 61131.0,
  "openInterest": 1458236000,
  "fundingRate": 0.0001,
  "fundingTimestamp": "2024-03-01T08:00:00.000Z",
  "predictedFundingRate": 0.00009,
  "indexPrice": 61130.9,
  "markPrice": 61131.1,
  "timestamp": "2024-03-01T00:00:00.250Z",
  "localTimestamp": "2024-03-01T00:00:00.251Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'derivative_ticker'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  lastPrice: number | undefined // last instrument price if provided by exchange
  openInterest: number | undefined // last open interest if provided by exchange
  fundingRate: number | undefined // funding rate for the next funding event if provided by exchange
  indexPrice: number | undefined // last index price if provided by exchange
  markPrice: number | undefined // last mark price if provided by exchange
  fundingTimestamp: string | undefined // next funding event timestamp if provided by exchange (ISO 8601 format)
  predictedFundingRate: number | undefined // estimated funding rate for the following funding event if provided by exchange
  timestamp: string // message timestamp provided by exchange (ISO 8601 format)
  localTimestamp: string // message arrival timestamp (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

### book\_snapshot\_{number\_of\_levels}\_{snapshot\_interval}{time\_unit}

Order book snapshot for selected `number_of_levels` (top bids and asks), `snapshot_interval` and [`time_unit`](#available-time-units). When `snapshot_interval` is set to `0`, snapshots are taken anytime order book state within specified levels has changed, otherwise snapshots are taken anytime `snapshot_interval` time has passed and there was an order book state change within specified levels. Order book snapshots are computed from exchanges' real-time order book streaming [L2 data (market by price)](/faq/order-books#what-l2-order-book-data-can-be-used-for).

#### Examples:

* `book_snapshot_10_0ms` - provides top 10 levels tick-by-tick order book snapshots
* `book_snapshot_50_100ms` - provides top 50 levels order book snapshots taken at 100 millisecond intervals
* `book_snapshot_10_grouped100_100ms` - provides top 10 levels order book snapshots grouped into price buckets of `100` and taken at 100 millisecond intervals
* `book_snapshot_30_10s` - provides top 30 levels order book snapshots taken at 10 second intervals
* `quote` - provides top of the book (best bid/ask) tick-by-tick order book snapshots (equivalent to depth 1, interval 0). Returned messages have `type: "book_snapshot"` and `name: "quote"`
* `quote_10s` - provides top of the book (best bid/ask) order book snapshots taken at 10 second intervals. Returned messages have `type: "book_snapshot"` and `name: "quote_10s"`

When grouped snapshots are requested, use `book_snapshot_{depth}_grouped{grouping}_{interval}{time_unit}`. The `grouping` field in the response then contains the requested grouping value.

#### Available time units:

* `ms` - milliseconds
* `s` - seconds
* `m` - minutes

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "book_snapshot",
  "symbol": "BTCUSDT",
  "exchange": "binance-futures",
  "name": "book_snapshot_2_50ms",
  "depth": 2,
  "interval": 50,
  "bids": [
    {
      "price": 61141.09,
      "amount": 2.02515
    },
    {
      "price": 61141.08,
      "amount": 0.55321
    }
  ],
  "asks": [
    {
      "price": 61141.1,
      "amount": 4.09368
    },
    {
      "price": 61141.11,
      "amount": 1.20457
    }
  ],
  "timestamp": "2024-03-01T00:00:01.450Z",
  "localTimestamp": "2024-03-01T00:00:01.491Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'book_snapshot'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  name: string // name with format book_snapshot_{depth}_{interval}{time_unit}
               // or book_snapshot_{depth}_grouped{grouping}_{interval}{time_unit}
  depth: number // requested number of levels (top bids/asks)
  interval: number // requested snapshot interval in milliseconds
  bids: { price: number | undefined; amount: number | undefined }[] // top "depth" bids price-amount levels
  asks: { price: number | undefined; amount: number | undefined }[] // top "depth" asks price-amount levels
  grouping: number | undefined // present for grouped snapshots
  timestamp: string // snapshot timestamp based on last book_change message
                    // processed timestamp adjusted to snapshot interval
  localTimestamp: string // message arrival timestamp
                         // that triggered snapshot (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

### liquidation

Liquidation events sourced from exchange-native liquidation feeds. Available for exchanges that publish liquidation data (e.g., Binance `forceOrder`, Bybit `allLiquidation`, OKX `liquidation-orders`). See [which exchanges support liquidations](/faq/data#which-exchanges-support-liquidations-data-type).

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "liquidation",
  "symbol": "BTCUSDT",
  "exchange": "binance-futures",
  "id": "1709251200123",
  "price": 61120.5,
  "amount": 12.5,
  "side": "sell",
  "timestamp": "2024-03-01T00:00:00.123Z",
  "localTimestamp": "2024-03-01T00:00:00.234Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'liquidation'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  id: string | undefined // liquidation id if provided by exchange
  price: number // liquidation price
  amount: number // liquidation amount
  side: 'buy' | 'sell' | 'unknown' // liquidation side: buy means short liquidation, sell means long liquidation
  timestamp: string // message timestamp provided by exchange (ISO 8601 format); some exchanges do not provide a separate liquidation timestamp, in which case this equals localTimestamp
  localTimestamp: string // message arrival timestamp (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

### option\_summary

Options instrument summary sourced from exchange-native options feeds. Available for exchanges that provide options data (e.g., Deribit, OKX Options, Binance European Options). Includes greeks, implied volatility, and best bid/ask for options instruments.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "option_summary",
  "symbol": "BTC-28JUN24-70000-C",
  "exchange": "deribit",
  "optionType": "call",
  "strikePrice": 70000,
  "expirationDate": "2024-06-28T08:00:00.000Z",
  "bestBidPrice": 0.035,
  "bestBidAmount": 5,
  "bestBidIV": 0.55,
  "bestAskPrice": 0.04,
  "bestAskAmount": 10,
  "bestAskIV": 0.58,
  "lastPrice": 0.0375,
  "openInterest": 150,
  "markPrice": 0.0372,
  "markIV": 0.565,
  "delta": 0.25,
  "gamma": 0.00002,
  "vega": 45.5,
  "theta": -15.2,
  "rho": 0.05,
  "underlyingPrice": 63500,
  "underlyingIndex": "BTC-USD",
  "timestamp": "2024-01-15T10:30:00.123Z",
  "localTimestamp": "2024-01-15T10:30:00.234Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'option_summary'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  optionType: 'put' | 'call' // option type
  strikePrice: number // strike price
  expirationDate: string // option expiration date (ISO 8601 format)
  bestBidPrice: number | undefined // best bid price
  bestBidAmount: number | undefined // best bid amount
  bestBidIV: number | undefined // best bid implied volatility
  bestAskPrice: number | undefined // best ask price
  bestAskAmount: number | undefined // best ask amount
  bestAskIV: number | undefined // best ask implied volatility
  lastPrice: number | undefined // last trade price
  openInterest: number | undefined // open interest
  markPrice: number | undefined // mark price
  markIV: number | undefined // mark implied volatility
  delta: number | undefined // delta greek
  gamma: number | undefined // gamma greek
  vega: number | undefined // vega greek
  theta: number | undefined // theta greek
  rho: number | undefined // rho greek
  underlyingPrice: number | undefined // underlying asset price
  underlyingIndex: string // underlying index name
  timestamp: string // message timestamp provided by exchange (ISO 8601 format)
  localTimestamp: string // message arrival timestamp (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

### trade\_bar\_{aggregation\_interval}{suffix}

Trades data in aggregated form, known as OHLC, candlesticks, klines etc. Not only most common time based aggregation is supported, but volume and tick count based as well. Bars are computed from tick-by-tick raw trade data, if in given interval no trades happened, there is no bar produced. For time-based bars, a bar is emitted when the first trade of the next interval arrives — not at the exact interval boundary. The bar's `timestamp` reflects the end of the interval period, while `openTimestamp` and `closeTimestamp` reflect actual trade times within that interval.

#### Examples:

* `trade_bar_10ms` - provides time based trade bars with 10 milliseconds intervals
* `trade_bar_5m` - provides time based trade bars with 5 minute intervals
* `trade_bar_100ticks` - provides ticks based trade bars with 100 ticks (individual trades) intervals
* `trade_bar_100000vol` - provides volume based trade bars with 100 000 volume intervals

Allowed suffixes:

* `ms` - milliseconds
* `s` - seconds
* `m` - minutes
* `ticks` - number of ticks
* `vol` - volume size

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "trade_bar",
  "symbol": "BTCUSDT",
  "exchange": "binance-futures",
  "name": "trade_bar_10000ms",
  "interval": 10000,
  "kind": "time",
  "open": 61130.98,
  "high": 61142.3,
  "low": 61129.75,
  "close": 61138.12,
  "volume": 12.845,
  "buyVolume": 7.421,
  "sellVolume": 5.424,
  "trades": 18,
  "vwap": 61135.84,
  "openTimestamp": "2024-03-01T00:00:00.112Z",
  "closeTimestamp": "2024-03-01T00:00:09.881Z",
  "localTimestamp": "2024-03-01T00:00:10.004Z",
  "timestamp": "2024-03-01T00:00:10.000Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'trade_bar'
  symbol: string // instrument symbol as provided by exchange
  exchange: string // exchange id
  name: string // name with format trade_bar_{interval}{suffix}
  interval: number // requested trade bar interval
  kind: 'time' | 'volume' | 'tick' // trade bar kind
  open: number // open price
  high: number // high price
  low: number // low price
  close: number // close price
  volume: number // total volume traded in given interval
  buyVolume: number // buy volume traded in given interval
  sellVolume: number // sell volume traded in given interval
  trades: number // trades count in given interval
  vwap: number // volume weighted average price
  openTimestamp: string // timestamp of first trade for given bar (ISO 8601 format)
  closeTimestamp: string // timestamp of last trade for given bar (ISO 8601 format)
  timestamp: string // end of interval period timestamp (ISO 8601 format)
  localTimestamp: string // message arrival timestamp
                         // that triggered given bar computation (ISO 8601 format)
}
```

{% endtab %}
{% endtabs %}

### disconnect

Message that marks events when real-time WebSocket connection that was used to collect the historical data got disconnected.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "disconnect",
  "exchange": "deribit",
  "localTimestamp": "2019-10-23T11:34:29.416Z"
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'disconnect'
  exchange: string // exchange id
  localTimestamp: string // timestamp when disconnect occurred (ISO 8601 format)
  symbols: string[] | undefined
}
```

{% endtab %}
{% endtabs %}

### error

Message sent when an underlying exchange WebSocket connection error occurs. Only available for [/ws-stream-normalized](/tardis-machine/streaming-real-time-data#websocket-ws-stream-normalized-options-options) when `withErrorMessages` is set to `true`. The `subSequentErrorsCount` tracks consecutive errors without successful data — if it reaches 50, the connection is closed.

{% tabs %}
{% tab title="sample message" %}

```javascript
{
  "type": "error",
  "exchange": "binance-futures",
  "localTimestamp": "2024-01-15T10:30:00.123Z",
  "details": "WebSocket connection error: Connection reset by peer",
  "subSequentErrorsCount": 1
}
```

{% endtab %}

{% tab title="schema" %}

```typescript
{
  type: 'error'
  exchange: string // exchange id
  localTimestamp: string // timestamp when error occurred (ISO 8601 format)
  details: string // error message
  subSequentErrorsCount: number // number of consecutive errors without successful data
}
```

{% endtab %}
{% endtabs %}


# Quickstart

Install, configure and get started with the tardis-dev Python package

Python `tardis-dev` package provides convenient access to tick-level historical cryptocurrency market data in exchange-native format. It focuses on two primary workflows: historical replay and CSV dataset downloads.

## Features

* [historical market data replay](/python-client/replaying-historical-data)
* [CSV dataset downloads](/downloadable-csv-files/overview)

{% hint style="warning" %}
If you're migrating older Python code that used `tardis-client`, `TardisClient` or `from tardis_dev import datasets`, start with [Migration Notice](/python-client/migration-notice).
{% endhint %}

{% embed url="<https://github.com/tardis-dev/tardis-python>" %}
Python tardis-dev GitHub repository
{% endembed %}

## Installation

Requires Python >=3.9.

```bash
pip install tardis-dev
```

## Historical Replay

```python
import asyncio
from tardis_dev import Channel, replay


async def main():
    async for local_timestamp, message in replay(
        exchange="binance",
        from_date="2024-03-01",
        to_date="2024-03-02",
        filters=[Channel("trade", ["btcusdt"]), Channel("depth", ["btcusdt"])],
        api_key="YOUR_API_KEY",
    ):
        print(local_timestamp, message)


asyncio.run(main())
```

See [Replaying Historical Data](/python-client/replaying-historical-data) for replay arguments, `Channel` filters, disconnect events and cache behavior.

{% content-ref url="/pages/6dztE6gHE7Lm6xalHDjP" %}
[Replaying Historical Data](/python-client/replaying-historical-data)
{% endcontent-ref %}

## CSV Dataset Downloads

```python
from tardis_dev import download_datasets

download_datasets(
    exchange="binance",
    data_types=["trades", "incremental_book_L2"],
    symbols=["BTCUSDT"],
    from_date="2024-03-01",
    to_date="2024-03-02",
    api_key="YOUR_API_KEY",
)
```

{% hint style="info" %}
If you're calling from an existing event loop, use `download_datasets_async()` instead of `download_datasets()`.
{% endhint %}

See also [Downloadable CSV files docs](/downloadable-csv-files/overview).

### `download_datasets(...)`

`download_datasets()` is the synchronous wrapper around `download_datasets_async()`. It raises `RuntimeError` if called inside a running event loop.

| name             | type                | default                          | description                                                                                                                                                                           |
| ---------------- | ------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `exchange`       | string              | -                                | exchange id with `supportsDatasets=true`; use [`get_exchange_details()`](#historical-market-data-helpers) to inspect available dataset symbols and data types                         |
| `data_types`     | sequence of strings | -                                | dataset types to download, e.g. `trades`, `incremental_book_L2`, `quotes`, `book_snapshot_25`, `book_snapshot_5`, `book_ticker`, `derivative_ticker`, `options_chain`, `liquidations` |
| `symbols`        | sequence of strings | -                                | dataset symbols to download, e.g. `BTCUSDT` or grouped symbols such as `OPTIONS`                                                                                                      |
| `from_date`      | string              | -                                | start date in ISO format, e.g. `2024-03-01`                                                                                                                                           |
| `to_date`        | string              | -                                | end date in ISO format (non-inclusive)                                                                                                                                                |
| `api_key`        | string (optional)   | `""`                             | API key for premium historical datasets                                                                                                                                               |
| `download_dir`   | string (optional)   | `"./datasets"`                   | local directory where downloaded files will be stored                                                                                                                                 |
| `endpoint`       | string (optional)   | `https://datasets.tardis.dev/v1` | override datasets API endpoint                                                                                                                                                        |
| `timeout`        | integer (optional)  | `1800`                           | HTTP timeout in seconds                                                                                                                                                               |
| `http_proxy`     | string (optional)   | `None`                           | HTTP proxy URL passed to `aiohttp`                                                                                                                                                    |
| `format`         | literal `"csv"`     | `"csv"`                          | dataset file format                                                                                                                                                                   |
| `concurrency`    | integer (optional)  | `20`                             | number of parallel download tasks; must be greater than `0`                                                                                                                           |
| `get_filename`   | callable (optional) | `default_file_name`              | function that returns the relative output path for each downloaded file                                                                                                               |
| `skip_if_exists` | boolean (optional)  | `True`                           | when `True`, skips files that already exist locally                                                                                                                                   |

### `download_datasets_async(...)`

Use `download_datasets_async()` inside an existing `asyncio` event loop. It accepts the same arguments as `download_datasets()`.

## Historical Market Data Helpers

```python
from tardis_dev import clear_cache, find_instrument_symbols, get_exchange_details

details = get_exchange_details("binance")
print(details["availableSymbols"][0]["id"])

symbols_by_exchange = find_instrument_symbols(
    ["bitmex", "binance-futures", "okex-swap", "bybit"],
    {
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "linear_perpetual",
        "active": True,
    },
    api_key="YOUR_API_KEY",
)
print(symbols_by_exchange)

clear_cache()
```

`get_exchange_details()` is the synchronous wrapper around `get_exchange_details_async()`.

### `get_exchange_details_async(exchange, *, endpoint=..., timeout=60, http_proxy=None)`

Use `get_exchange_details_async()` inside an existing `asyncio` event loop when you need exchange metadata without blocking on the synchronous wrapper.

| name         | type               | default                     | description                          |
| ------------ | ------------------ | --------------------------- | ------------------------------------ |
| `exchange`   | string             | -                           | exchange id to query, e.g. `binance` |
| `endpoint`   | string (optional)  | `https://api.tardis.dev/v1` | override HTTP API endpoint           |
| `timeout`    | integer (optional) | `60`                        | HTTP timeout in seconds              |
| `http_proxy` | string (optional)  | `None`                      | HTTP proxy URL passed to `aiohttp`   |

### `get_instrument_info(...)` and `get_instrument_info_async(...)`

Use `get_instrument_info()` when you need full instrument metadata such as tick sizes, contract multipliers, base/quote currencies, `id`, and `datasetId` after the symbol appears in exported dataset metadata. It can query a single symbol, a single exchange with a filter, or multiple exchanges with the same filter.

```python
from tardis_dev import get_instrument_info

info = get_instrument_info("binance", symbol="btcusdt", api_key="YOUR_API_KEY")
print(info["priceIncrement"])
```

Use `get_instrument_info_async()` inside an existing `asyncio` event loop.

### `find_instrument_symbols(...)` and `find_instrument_symbols_async(...)`

Use this helper when you know the market you want but not each exchange's symbol format. It queries the [Instruments Metadata API](/api/instruments-metadata-api) with normalized criteria and returns the correct exchange-specific `id` for each requested exchange, ready to pass to replay or raw data feeds.

```python
from tardis_dev import find_instrument_symbols

symbols_by_exchange = find_instrument_symbols(
    ["bitmex", "binance-futures", "okex-swap", "bybit"],
    {
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "linear_perpetual",
        "active": True,
    },
    api_key="YOUR_API_KEY",
)

print(symbols_by_exchange)
# [
#   {"exchange": "bitmex", "symbols": ["XBTUSDT"]},
#   {"exchange": "binance-futures", "symbols": ["btcusdt"]},
#   {"exchange": "okex-swap", "symbols": ["BTC-USDT-SWAP"]},
#   {"exchange": "bybit", "symbols": ["BTCUSDT"]},
# ]
```

The optional `selector` keyword defaults to `id`. Pass `selector="datasetId"` only when you need symbols for direct CSV dataset file downloads:

```python
csv_symbols_by_exchange = find_instrument_symbols(
    ["bitmex", "binance-futures", "okex-swap", "bybit"],
    {
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "linear_perpetual",
        "active": True,
    },
    selector="datasetId",
    api_key="YOUR_API_KEY",
)
```

Returned `id` symbols are exchange-provided IDs and are not normalized by the client. Returned `datasetId` symbols are CSV dataset IDs for instruments whose symbols appear in exported dataset metadata; `download_datasets()` URL-encodes them when constructing dataset URLs. Use `find_instrument_symbols_async()` inside an existing `asyncio` event loop.

## Other Public Exports

```python
from tardis_dev import Response, default_file_name
```

* `Response` is the public `NamedTuple` returned by `replay()`. See [Replaying Historical Data](/python-client/replaying-historical-data#type-of-messages-returned-by-replay) for details.
* `default_file_name(exchange, data_type, date, symbol, format)` is the default helper used by `download_datasets()` and `download_datasets_async()` to build output file names.


# Replaying Historical Data

Replaying historical market data in exchange-native format with the tardis-dev Python package

{% hint style="info" %}
See [historical data details](/historical-data-details/overview) page to get detailed information about historical market data available for each exchange.
{% endhint %}

## `replay(...)`

Replays historical market data messages for given replay arguments in [exchange-native format](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format). Historical market data is fetched in parallel from the [Tardis.dev HTTP API](/api/http-api-reference#data-feeds-exchange), cached locally on disk in compressed format and returned as an async generator.

`from_date` and `to_date` accept either ISO date strings or Python `datetime` values. Naive datetimes are treated as UTC.

{% hint style="info" %}
For filtered historical replay, the client automatically uses the [recommended `sliceSize`](/api/http-api-reference#data-feeds-exchange) to reduce `/data-feeds` request count.
{% endhint %}

```python
import asyncio
from tardis_dev import Channel, replay


async def main():
    async for local_timestamp, message in replay(
        exchange="binance",
        from_date="2024-03-01",
        to_date="2024-03-02",
        filters=[
            Channel("trade", ["btcusdt"]),
            Channel("depth", ["btcusdt"]),
        ],
        api_key="YOUR_API_KEY",
    ):
        print(local_timestamp, message)


asyncio.run(main())
```

When `symbols` is omitted or `None` in `Channel`, data for all active symbols for that channel is returned. Use that form when you need the whole channel instead of starting one replay per symbol. If you need selected symbols, pass them together in one `Channel(name, [...])` entry.

{% hint style="info" %}
The replay API fetches data in parallel. Avoid blocking the async loop with slow I/O (for example synchronous file writes) inside the iteration — use async I/O or buffer writes to prevent slowdowns and timeouts.
{% endhint %}

#### replay arguments

| name               | type                            | default                           | description                                                                                                                                                    |
| ------------------ | ------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `exchange`         | string                          | -                                 | requested exchange id - use [`get_exchange_details()`](/python-client/quickstart#historical-market-data-helpers) to inspect available channels and symbols     |
| `from_date`        | string or `datetime`            | -                                 | replay period start date (UTC) as ISO string or Python `datetime`, e.g. `2019-04-01` or `2019-04-01T12:00:00Z`; naive datetimes are treated as UTC             |
| `to_date`          | string or `datetime`            | -                                 | replay period end date (UTC, non-inclusive) as ISO string or Python `datetime`; naive datetimes are treated as UTC                                             |
| `filters`          | `Sequence[Channel]` (optional)  | `None`                            | optional filters of requested historical data feed                                                                                                             |
| `api_key`          | string (optional)               | `""`                              | API key for Tardis.dev [HTTP API](/api/http-api-reference#data-feeds-exchange) - if not provided only first day of each month of historical data is accessible |
| `cache_dir`        | string (optional)               | `<system temp dir>/.tardis-cache` | path to local dir that will be used as cache location                                                                                                          |
| `endpoint`         | string (optional)               | `https://api.tardis.dev/v1`       | override HTTP API endpoint                                                                                                                                     |
| `timeout`          | integer (optional)              | `135`                             | timeout in seconds for each replay HTTP request attempt                                                                                                        |
| `http_proxy`       | string (optional)               | `None`                            | HTTP proxy URL passed to `aiohttp`                                                                                                                             |
| `compression`      | `"zstd"` or `"gzip"` (optional) | `"zstd"`                          | preferred compression for replay requests; set to `"gzip"` when you need gzip-compressed slices                                                                |
| `decode_response`  | boolean (optional)              | `True`                            | when set to `False`, returns raw bytes instead of decoding JSON                                                                                                |
| `with_disconnects` | boolean (optional)              | `False`                           | when set to `True`, yields `None` for events when the recording connection got disconnected                                                                    |
| `auto_cleanup`     | boolean (optional)              | `False`                           | when set to `True`, automatically removes cached data from disk after it has been processed                                                                    |
| `json`             | module-like object (optional)   | `json`                            | custom JSON module/object with a `loads()` function used when `decode_response=True`                                                                           |

## `Channel(name, symbols=None)`

Use `Channel` objects to filter replay by exchange-native channel name and symbol list.

| name      | type                           | description                                                                           |
| --------- | ------------------------------ | ------------------------------------------------------------------------------------- |
| `name`    | string                         | exchange-native channel name, e.g. `trade` or `depth`                                 |
| `symbols` | sequence of strings (optional) | symbols to include; omit or pass `None` to include all active symbols for the channel |

```python
from tardis_dev import Channel

Channel("trade", ["btcusdt", "ethusdt"])
Channel("depth", ["btcusdt"])
Channel("trade")
```

{% hint style="warning" %}
The client can fetch replay data with up to 60 concurrent `/data-feeds` HTTP requests per replay job. Long date ranges, many channel/symbol filters and multiple concurrent replay processes can quickly exceed [API rate limits](/api/rate-limits), causing request failures.
{% endhint %}

{% hint style="warning" %}
Avoid using `auto_cleanup=True` with concurrent replay jobs that share the same exchange, filters and calendar day. Those jobs reuse the same cache path and can remove files that are still needed by another replay task.
{% endhint %}

#### type of messages returned by `replay`

`replay()` yields `Response(local_timestamp, message)` items, where `Response` is the public `NamedTuple` export from `tardis_dev`:

* `local_timestamp` is a Python `datetime` marking when the message was received from the exchange real-time feed
* `message` is a Python dict with parsed JSON in exchange-native format

When `decode_response=False`, both fields are returned as raw bytes instead.

When `with_disconnects=True`, replay can also yield `None` for disconnect events.

#### sample message

```python
{
  "stream": "btcusdt@trade",
  "data": {
    "e": "trade",
    "E": 1709251199998,
    "s": "BTCUSDT",
    "t": 3445374963,
    "p": "61130.98000000",
    "q": "0.00145000",
    "b": 25230662315,
    "a": 25230662808,
    "T": 1709251199998,
    "m": True,
    "M": True
  }
}
```

{% hint style="info" %}
Python `tardis-dev` currently documents exchange-native replay only. If you need normalized replay or real-time streaming, use the [Node.js client](/node-client/quickstart) or [tardis-machine](/tardis-machine/quickstart).
{% endhint %}


# Migration Notice

Migrate from tardis-client and tardis\_dev.datasets to the unified tardis-dev package

Python client v3 unifies historical replay, CSV dataset downloads and exchange metadata into one package: `tardis-dev`.

{% hint style="warning" %}
This is a hard break. There is no compatibility layer for `tardis-client`, `TardisClient`, `tardis_dev.datasets`, reconstructors or any temporary shim.
{% endhint %}

## Install the new package

```bash
pip uninstall tardis-client
pip install tardis-dev
```

If you were already using the dataset-download package, upgrade it in place:

```bash
pip install --upgrade tardis-dev
```

## API mapping

| Before                                            | After                                                                |
| ------------------------------------------------- | -------------------------------------------------------------------- |
| `from tardis_client import TardisClient, Channel` | `from tardis_dev import replay, Channel`                             |
| `tardis_client = TardisClient(api_key="...")`     | pass `api_key="..."` directly to `replay()` or `download_datasets()` |
| `tardis_client.replay(...)`                       | `replay(...)`                                                        |
| `from tardis_dev import datasets`                 | `from tardis_dev import download_datasets`                           |
| `datasets.download(...)`                          | `download_datasets(...)`                                             |
| `tardis_client.clear_cache()`                     | `clear_cache()`                                                      |
| `get_exchange_details(exchange)`                  | `get_exchange_details(exchange)`                                     |

## Replay migration

### Before

```python
import asyncio
from tardis_client import TardisClient, Channel


async def main():
    tardis_client = TardisClient(api_key="YOUR_API_KEY")

    async for local_timestamp, message in tardis_client.replay(
        exchange="bitmex",
        from_date="2019-06-01",
        to_date="2019-06-02",
        filters=[Channel("trade", ["XBTUSD"])],
    ):
        print(local_timestamp, message)


asyncio.run(main())
```

### After

```python
import asyncio
from tardis_dev import Channel, replay


async def main():
    async for local_timestamp, message in replay(
        exchange="bitmex",
        from_date="2019-06-01",
        to_date="2019-06-02",
        filters=[Channel("trade", ["XBTUSD"])],
        api_key="YOUR_API_KEY",
    ):
        print(local_timestamp, message)


asyncio.run(main())
```

What changed:

* `TardisClient` is gone; `replay()` is now a top-level async generator
* configuration stays explicit at the call site via keyword arguments
* `Channel.symbols=None` or omitting `symbols` means all symbols for that channel

## Dataset download migration

### Before

```python
from tardis_dev import datasets

datasets.download(
    exchange="deribit",
    data_types=["trades", "incremental_book_L2"],
    symbols=["BTC-PERPETUAL"],
    from_date="2019-11-01",
    to_date="2019-11-02",
    api_key="YOUR_API_KEY",
)
```

### After

```python
from tardis_dev import download_datasets

download_datasets(
    exchange="deribit",
    data_types=["trades", "incremental_book_L2"],
    symbols=["BTC-PERPETUAL"],
    from_date="2019-11-01",
    to_date="2019-11-02",
    api_key="YOUR_API_KEY",
)
```

What changed:

* `datasets` subpackage was removed
* `download()` was renamed to `download_datasets()`
* `download_datasets()` is the synchronous wrapper; use `download_datasets_async()` inside an existing event loop

## Cache cleanup migration

### Before

```python
from tardis_client import TardisClient

tardis_client = TardisClient()
tardis_client.clear_cache()
```

### After

```python
from tardis_dev import clear_cache

clear_cache()
clear_cache(cache_dir="./cache")
```

## Removed APIs

The following public APIs are intentionally removed in v3:

* `TardisClient`
* `reconstruct_market()`
* `tardis_client.reconstructors`
* `tardis_dev.datasets`

## Related docs

* [Quickstart](/python-client/quickstart)
* [Replaying Historical Data](/python-client/replaying-historical-data)
* [Downloadable CSV Files Quickstart](/downloadable-csv-files/overview)
* [Downloadable CSV Files API Reference](/downloadable-csv-files/api)


# Overview

Historical market data details for each supported exchange — available symbols, channels, date ranges...

{% hint style="info" %}
Historical data details describes data collection specifics for each supported exchange and what's available via Tardis.dev [HTTP API](/api/http-api-reference). If you'd like to work with [normalized market data](/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) see [official libraries](/api/quickstart) and [downloadable CSV files](/downloadable-csv-files/overview).
{% endhint %}

You'll find here per-exchange details about:

* historical data availability date ranges — since when the historical data has been collected and is available
* captured real-time market data channels also described as streams, subscription topics, tables etc in exchanges' docs — available historical raw market data is being sourced from WebSocket real-time APIs provided by the exchanges and can be filtered by channels, e.g.: to get historical trades for BitMEX, channel `trade` needs to be provided alongside requested instruments symbols (via [HTTP API](/api/http-api-reference#data-feeds-exchange) or [client libs](/api/quickstart) function args).
* symbols of recorded instruments/currency pairs
* incidents - known Tardis.dev market data collection issues where data may be missing or affected for a given exchange

Some exchanges encode requested symbol in channel name, e.g.: Deribit `trades.BTC-PERPETUAL.100ms` channel. This is not the case with our API as we always consider channel name and symbol to be separate inputs. In case of Deribit example channel name would be `trades` and symbol `BTC-PERPETUAL`. If channel provides option of frequency of updates (e.g.: 100ms vs raw tick by tick) always higher frequency one is being chosen and recorded.

{% hint style="info" %}
[What is the channel field used in the HTTP API and client libs replay functions?](/faq/data#what-is-the-channel-field-used-in-the-http-api-and-client-libs-replay-functions)
{% endhint %}

## Market data collection overview

* All market data collection is being performed on one of the highly available [Google Cloud Platform Kubernetes Clusters](https://cloud.google.com/kubernetes-engine/) - London, UK (europe-west2 region) or Tokyo, Japan (asia-northeast1 region) - information which data center location is used for particular exchange is described on exchange historical data details page.
* When exchange provides choice of real-time data frequency for specific data types (e.g. order book data ) always most granular, non aggregated data feed is being collected.
* Choice if single or multiple WebSocket connections are being used to record full real-time data feed is made on case by case basis - we take into account exchange API limits and latency which may be higher or lower if single connection is being used - detailed information which strategy is used for particular exchange is described on exchange historical data details page.
* WebSocket connection is dynamically re-subscribed (or restarted for some exchanges) at 00:00 UTC every day in order to receive [initial order book snapshots](#collected-order-book-data-details).
* Each received message is timestamped with 100ns precision using [synchronized clock](https://developers.google.com/time) at arrival time and stored in ISO 8601 format.
* Messages provided by exchanges' WebSocket feeds are being stored without any modifications.
* Checks for new instruments available on a given exchange are performed every minute.
* Market data collection services are being constantly monitored both manually and via automated tools (monitoring, alert notifications) and have built-in self-healing capabilities. We also constantly monitor for upcoming exchanges' API changes and adapt to those beforehand.
* There are multiple built-in checks that detect whether a connection to an exchange is healthy during the data collection process, such as:
  * validating subscription responses - if an exchange does not confirm subscriptions within 20 seconds, the connection is restarted
  * [Heartbeat pings](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#Pings_and_Pongs_The_Heartbeat_of_WebSockets)
  * order book sequence number validation for exchanges that provide those
  * validating JSON format as in some unusual circumstances exchanges return data that is invalid JSON
  * stale connection detection - if there are no responses received within a certain period (adjusted per exchange), it's most likely a stale connection that is automatically restarted
  * detection of an unusually low message count from an exchange in a given time period, which likely means the connection is not healthy, e.g. receiving only 'pings' without data messages
  * and many more
* Any incident that is caused by us (bugs, network errors etc.) is being logged and available [via API](/api/http-api-reference#exchanges-exchange).
* New market data delay is 6 minutes in relation to real-time (`T - 6min`).

## Collected order book data details

Historical market data available via [HTTP API](/api/http-api-reference#data-feeds-exchange) provides order book snapshots at the beginning of each day (00:00 UTC) and every time a WebSocket connection has been closed while recording real-time data feeds (the connection is restarted and a new snapshot is provided via a fresh connection). This means that to be sure to receive initial order book snapshots, one must replay historical data from 00:00 UTC of that day. It also means there is a tiny **gap in historical data** (around `300-3000ms`, depending on the exchange) during re-subscription to real-time WebSocket feeds (every 24 hours) to receive order book snapshots.

Some exchanges do not provide initial order book snapshots when subscribing to WebSocket real-time feeds (like Binance, Bitstamp or Coinbase Exchange full order book), hence for those there is a 'generated' snapshot available instead (based on REST API call) - details are specific for each exchange and are described in per-exchange historical details pages.

## Per-exchange historical data details

{% hint style="info" %}
Click any exchange below to see its historical data details - available instruments, captured [real-time channels](/faq/data#what-is-the-channel-field-used-in-the-http-api-and-client-libs-replay-functions), API access details and market data collection specifics.
{% endhint %}

* [Binance USDS-M Futures](/historical-data-details/binance-futures)
* [Binance COIN Futures](/historical-data-details/binance-delivery)
* [Binance European Options](/historical-data-details/binance-european-options)
* [Binance Spot](/historical-data-details/binance)
* [Binance US](/historical-data-details/binance-us)
* [OKX Futures](/historical-data-details/okex-futures)
* [OKX Swap](/historical-data-details/okex-swap)
* [OKX Options](/historical-data-details/okex-options)
* [OKX Spot](/historical-data-details/okex)
* [OKX Nitro Spreads](/historical-data-details/okex-spreads)
* [Coinbase Exchange](/historical-data-details/coinbase)
* [Coinbase International](/historical-data-details/coinbase-international)
* [BitMEX](/historical-data-details/bitmex)
* [Deribit](/historical-data-details/deribit)
* [Bybit Derivatives](/historical-data-details/bybit)
* [Bybit Spot](/historical-data-details/bybit-spot)
* [Bybit Options](/historical-data-details/bybit-options)
* [Kraken Futures](/historical-data-details/cryptofacilities)
* [Kraken](/historical-data-details/kraken)
* [Bitfinex Derivatives](/historical-data-details/bitfinex-derivatives)
* [Bitfinex](/historical-data-details/bitfinex)
* [KuCoin Futures](/historical-data-details/kucoin-futures)
* [KuCoin Spot](/historical-data-details/kucoin)
* [Aster Futures](/historical-data-details/aster-futures)
* [Aster Spot](/historical-data-details/aster)
* [MEXC Spot](/historical-data-details/mexc)
* [MEXC Futures](/historical-data-details/mexc-futures)
* [Crypto.com](/historical-data-details/crypto-com)
* [Bitstamp](/historical-data-details/bitstamp)
* [Bitget Futures](/historical-data-details/bitget-futures)
* [Bitget Spot](/historical-data-details/bitget)
* [Gate.io Futures](/historical-data-details/gate-io-futures)
* [Gate.io](/historical-data-details/gate-io)
* [HTX Coin-M Futures](/historical-data-details/huobi-dm)
* [HTX Coin-M Perpetual](/historical-data-details/huobi-dm-swap)
* [HTX USDT-M Contracts](/historical-data-details/huobi-dm-linear-swap)
* [HTX Spot](/historical-data-details/huobi)
* [Gemini](/historical-data-details/gemini)
* [WOO X](/historical-data-details/woo-x)
* [Upbit](/historical-data-details/upbit)
* [Phemex](/historical-data-details/phemex)
* [Delta Exchange](/historical-data-details/delta)
* [Blockchain.com](/historical-data-details/blockchain-com)
* [Bitnomial](/historical-data-details/bitnomial)
* [bitFlyer](/historical-data-details/bitflyer)
* [HitBTC](/historical-data-details/hitbtc)
* [Poloniex](/historical-data-details/poloniex)
* [Hyperliquid](/historical-data-details/hyperliquid)
* [Lighter](/historical-data-details/lighter)
* [Polymarket](/historical-data-details/polymarket)
* [Bullish](/historical-data-details/bullish)
* [dYdX v4](/historical-data-details/dydx-v4)

### Delisted exchanges

* [FTX](/historical-data-details/ftx)
* [FTX US](/historical-data-details/ftx-us)
* [OKCoin](/historical-data-details/okcoin)
* [AscendEX (BitMax)](/historical-data-details/ascendex)
* [CoinFLEX](/historical-data-details/coinflex)
* [Binance Jersey](/historical-data-details/binance-jersey)
* [Binance DEX](/historical-data-details/binance-dex)
* [HTX Options](/historical-data-details/huobi-dm-options)
* [dYdX](/historical-data-details/dydx)
* [Serum DEX](/historical-data-details/serum)
* [Mango Markets DEX](/historical-data-details/mango)
* [Star Atlas DEX](/historical-data-details/star-atlas)


# Binance USDS-M Futures

Binance USDS-M Futures historical market data details - instruments, data coverage and data collection specifics

Binance USDS-M Futures historical data for **all its instruments** is available since **2019-11-17**.

{% embed url="<https://api.tardis.dev/v1/exchanges/binance-futures>" %}
See Binance USDS-M Futures historical data coverage: available symbols, channels, date ranges and incidents
{% endembed %}

{% hint style="info" %}
Data collection before 2020-05-14 suffered some issues (missing data, latency spikes) during market volatility periods. It has been circumvented by switching to [Tokyo DC](#market-data-collection-details) and using multiple WS connections for real-time market data collection.
{% endhint %}

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

`derivative_ticker` **open interest data is available since 2020-05-13** - date since we've started collecting that info via Binance USDS-M Futures REST API (open interest channel).

| data type             | symbol  | date       |                                                                                                                 |
| --------------------- | ------- | ---------- | --------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSDT | 2020-02-01 | [Download sample](https://datasets.tardis.dev/v1/binance-futures/incremental_book_L2/2020/02/01/BTCUSDT.csv.gz) |
| trades                | BTCUSDT | 2020-02-01 | [Download sample](https://datasets.tardis.dev/v1/binance-futures/trades/2020/02/01/BTCUSDT.csv.gz)              |
| derivative\_ticker    | BTCUSDT | 2020-02-01 | [Download sample](https://datasets.tardis.dev/v1/binance-futures/derivative_ticker/2020/02/01/BTCUSDT.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Binance USDS-M Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="binance-futures",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="depth", symbols=["btcusdt"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Binance USDS-M Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'binance-futures',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'depth', symbols: ['btcusdt'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance-futures?from=2023-03-01&filters=[{"channel":"depth","symbols":["btcusdt"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance-futures?from=2023-03-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22btcusdt%22]}]&offset=0>" %}
Example API response for Binance USDS-M Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance-futures","filters":[{"channel":"depth","symbols":["btcusdt"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://binance-docs.github.io/apidocs/futures/en/#websocket-market-streams>" %}
See Binance USDS-M Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public futures trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22depth%22,%22symbols%22:\[%22btcusdt%22]}]) Incremental futures order book updates stream. Recorded with the fastest API cadence available at the time: until 2020-01-07 it was subscribed as `depth@100ms` (100ms updates), after that as `depth@0ms` (real-time dynamically adjusted update speed).
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22depthSnapshot%22,%22symbols%22:\[%22btcusdt%22]}]) — generated channel Binance USDS-M Futures real-time WebSocket API **does not provide initial order book snapshots**. To overcome this issue we fetch initial order book snapshots from REST API and store them together with the rest of the WebSocket messages — top 1000 levels. Such snapshot messages are marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true` fields.

  During data collection integrity of order book incremental updates is being validated using [sequence numbers](https://binance-docs.github.io/apidocs/futures/en/#how-to-manage-a-local-order-book-correctly) provided by real-time feed (`pu` and `u` fields) — in case of detecting missed message WebSocket connection is being restarted. We also validate if initial book snapshot fetched from REST API overlaps with received `depth` messages.
* [bookTicker](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22bookTicker%22,%22symbols%22:\[%22btcusdt%22]}]) Best bid and best ask updates stream
* [forceOrder](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22forceOrder%22}]) — available since **2020-01-07** Liquidation order stream publishing only the latest liquidation per symbol in each 1000ms window
* [ticker](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22btcusdt%22]}]) 24h futures ticker updates stream
* [markPrice](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22markPrice%22,%22symbols%22:\[%22btcusdt%22]}]) Mark price and funding metrics stream. Subscribed as `@markPrice@1s`. The 1s update speed has been available since 2020-02-13; before that the default (3s) speed was used.
* [premiumIndex](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2026-05-01\&filters=\[{%22channel%22:%22premiumIndex%22,%22symbols%22:\[%22btcusdt%22]}]) — generated channel, available since **2026-04-11**

  Snapshots are fetched from the REST [mark price endpoint](https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Mark-Price) about every 6 seconds for all instruments. The recorder splits the REST response into one generated message per instrument, marked with `"stream":"<symbol>@premiumIndex"` and `"generated":true` fields. This channel includes the `interestRate` field that is not present on the WebSocket `markPrice` stream.
* [indexConstituents](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2026-05-01\&filters=\[{%22channel%22:%22indexConstituents%22,%22symbols%22:\[%22btcusdt%22]}]) — generated channel, available since **2026-04-23**

  Snapshots are fetched from the REST [index price constituents endpoint](https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Index-Constituents) every minute per instrument. Messages are marked with `"stream":"<symbol>@indexConstituents"` and `"generated":true` fields with REST response format.
* [openInterest](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22openInterest%22,%22symbols%22:\[%22btcusdt%22]}]) — generated channel, available since **2020-05-12**

  Snapshots are fetched from the REST [open interest endpoint](https://binance-docs.github.io/apidocs/futures/en/#open-interest) about every 6 seconds per instrument. Messages are marked with `"stream":"<symbol>@openInterest"` and `"generated":true` fields with REST response format.
* [fundingInfo](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2026-03-17\&filters=\[{%22channel%22:%22fundingInfo%22}]) — generated channel, available since **2026-03-17**

  Snapshots are fetched from the REST [funding info endpoint](https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Get-Funding-Rate-Info) every minute. Binance returns only symbols with adjusted funding cap, floor, or interval. Messages are marked with `"stream":"<symbol>@fundingInfo"` and `"generated":true` fields with REST response format.
* [insuranceBalance](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2026-03-17\&filters=\[{%22channel%22:%22insuranceBalance%22}]) — generated channel, available since **2026-03-17**

  Snapshots are fetched from the REST [insurance fund balance endpoint](https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Insurance-Fund-Balance) every minute. Messages are marked with `"stream":"insuranceBalance"` and `"generated":true` fields with REST response format.
* [aggTrade](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22aggTrade%22}]) Aggregated futures trade executions stream
* [compositeIndex](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22compositeIndex%22,%22symbols%22:\[%22defiusdt%22]}]) — available since **2020-10-28** Composite index updates stream for multi-asset index symbols
* [assetIndex](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22assetIndex%22}]) — available since **2023-06-16** Asset index updates stream
* [topLongShortAccountRatio](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22topLongShortAccountRatio%22,%22symbols%22:\[%22btcusdt%22]}]\&offset=3) — generated channel, available since **2020-10-28**

  Top trader long/short ratio (accounts), sourced by querying [REST endpoint](https://binance-docs.github.io/apidocs/futures/en/#top-trader-long-short-ratio-accounts) every minute
* [topLongShortPositionRatio](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22topLongShortPositionRatio%22,%22symbols%22:\[%22btcusdt%22]}]\&offset=3) — generated channel, available since **2020-10-28**

  Top trader long/short ratio (positions), sourced by querying [REST endpoint](https://binance-docs.github.io/apidocs/futures/en/#top-trader-long-short-ratio-positions) every minute
* [globalLongShortAccountRatio](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22globalLongShortAccountRatio%22,%22symbols%22:\[%22btcusdt%22]}]\&offset=3) — generated channel, available since **2020-10-28**

  Global long/short ratio, sourced by querying [REST endpoint](https://binance-docs.github.io/apidocs/futures/en/#long-short-ratio) every minute
* [takerlongshortRatio](https://api.tardis.dev/v1/data-feeds/binance-futures?from=2024-01-01\&filters=\[{%22channel%22:%22takerlongshortRatio%22,%22symbols%22:\[%22btcusdt%22]}]\&offset=3) — generated channel, available since **2021-12-01**

  Taker buy/sell volume ratio, sourced by querying [REST endpoint](https://binance-docs.github.io/apidocs/futures/en/#taker-buy-sell-volume) every minute
* `!contractInfo` — available since **2023-07-24** Contract metadata updates stream pushed when listing, settlement, or bracket information changes

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Binance USDS-M Futures **since 2020-05-14** is located in GCP asia-northeast1 region (Tokyo, Japan), before that it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://fstream.binance.com/stream`.

{% hint style="info" %}
Binance servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Binance COIN Futures

Binance COIN Margined Futures historical market data details - instruments, data coverage and data collection specifics

Binance COIN Futures historical data for **all its instruments** is available since **2020-06-16**.

{% embed url="<https://api.tardis.dev/v1/exchanges/binance-delivery>" %}
See Binance COIN Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol         | date       |                                                                                                                        |
| --------------------- | -------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD\_200925 | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/binance-delivery/incremental_book_L2/2020/07/01/BTCUSD_200925.csv.gz) |
| trades                | BTCUSD\_200925 | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/binance-delivery/trades/2020/07/01/BTCUSD_200925.csv.gz)              |
| derivative\_ticker    | BTCUSD\_200925 | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/binance-delivery/derivative_ticker/2020/07/01/BTCUSD_200925.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Binance COIN Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="binance-delivery",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="depth", symbols=["btcusd_perp"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Binance COIN Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'binance-delivery',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'depth', symbols: ['btcusd_perp'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2023-03-01&filters=[{"channel":"depth","symbols":["btcusd_perp"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2023-03-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22btcusd_perp%22]}]&offset=0>" %}
Example API response for Binance COIN Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance-delivery","filters":[{"channel":"depth","symbols":["btcusd_perp"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://binance-docs.github.io/apidocs/delivery/en/#websocket-market-streams>" %}
See Binance COIN Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public COIN futures trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22depth%22,%22symbols%22:\[%22btcusd_perp%22]}]) Incremental COIN futures order book updates stream. Subscribed as `depth@0ms` with real-time dynamically adjusted update speed.
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22depthSnapshot%22,%22symbols%22:\[%22btcusd_perp%22]}]) — generated channel Binance COIN Futures real-time WebSocket API **does not provide initial order book snapshots**. To overcome this issue we fetch initial order book snapshots from REST API and store them together with the rest of the WebSocket messages — top 1000 levels. Such snapshot messages are marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true` fields.

  During data collection integrity of order book incremental updates is being validated using [sequence numbers](https://binance-docs.github.io/apidocs/delivery/en/#diff-book-depth-streams) provided by real-time feed (`U` and `u` fields) — in case of detecting missed message WebSocket connection is being restarted. We also validate if initial book snapshot fetched from REST API overlaps with received `depth` messages.
* [bookTicker](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22bookTicker%22}]) Best bid and best ask updates stream
* [forceOrder](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22forceOrder%22}]) — available since **2020-07-08** Liquidation order stream publishing only the latest liquidation per symbol in each 1000ms window
* [markPrice](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22markPrice%22}]) Mark price and funding metrics stream subscribed as `@markPrice@1s`
* [indexPrice](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22indexPrice%22}]) Index price updates stream subscribed as `@indexPrice@1s`
* [openInterest](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22openInterest%22,%22symbols%22:\[%22btcusd_perp%22]}]) — generated channel

  Snapshots are fetched from the REST [open interest endpoint](https://binance-docs.github.io/apidocs/delivery/en/#open-interest) about every 6 seconds per instrument. Messages are marked with `"stream":"<symbol>@openInterest"` and `"generated":true` fields with REST response format.
* [fundingInfo](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2026-03-17\&filters=\[{%22channel%22:%22fundingInfo%22}]) — generated channel, available since **2026-03-17**

  Snapshots are fetched from the REST [funding info endpoint](https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Get-Funding-Info) every minute. Binance returns only symbols with adjusted funding cap, floor, or interval. Messages are marked with `"stream":"<symbol>@fundingInfo"` and `"generated":true` fields with REST response format.
* [aggTrade](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22aggTrade%22}]) Aggregated COIN futures trade executions stream
* [ticker](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) 24h COIN futures ticker updates stream
* [topLongShortAccountRatio](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-02-01\&filters=\[{%22channel%22:%22topLongShortAccountRatio%22,%22symbols%22:\[]}]\&offset=4) — generated channel, available since **2020-10-28**

  Top trader long/short ratio (accounts), sourced by querying REST endpoint every minute
* [topLongShortPositionRatio](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-02-01\&filters=\[{%22channel%22:%22topLongShortPositionRatio%22,%22symbols%22:\[]}]\&offset=4) — generated channel, available since **2020-10-28**

  Top trader long/short ratio (positions), sourced by querying REST endpoint every minute
* [globalLongShortAccountRatio](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-02-01\&filters=\[{%22channel%22:%22globalLongShortAccountRatio%22,%22symbols%22:\[]}]\&offset=4) — generated channel, available since **2020-10-28**

  Global long/short ratio, sourced by querying REST endpoint every minute
* [takerBuySellVol](https://api.tardis.dev/v1/data-feeds/binance-delivery?from=2024-02-01\&filters=\[{%22channel%22:%22takerBuySellVol%22,%22symbols%22:\[]}]\&offset=4) — generated channel, available since **2021-12-01**

  Taker buy/sell volume ratio, sourced by querying REST endpoint every minute
* `!contractInfo` — available since **2023-04-01** Contract metadata updates stream pushed when listing, settlement, or bracket information changes

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Binance COIN Futures is located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://dstream.binance.com/stream`.

{% hint style="info" %}
Binance servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Binance European Options

Binance European Options historical market data details - instruments, data coverage and data collection specifics

Binance European Options historical data for **all its instruments** is available since **2023-06-15**.

{% embed url="<https://api.tardis.dev/v1/exchanges/binance-european-options>" %}
See Binance European Options historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol             | date       |                                                                                                                                     |
| --------------------- | ------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-250328-50000-C | 2024-08-01 | [Download sample](https://datasets.tardis.dev/v1/binance-european-options/incremental_book_L2/2024/08/01/BTC-250328-50000-C.csv.gz) |
| trades                | BTC-250328-50000-C | 2024-08-01 | [Download sample](https://datasets.tardis.dev/v1/binance-european-options/trades/2024/08/01/BTC-250328-50000-C.csv.gz)              |
| options\_chain        | OPTIONS            | 2024-01-01 | [Download sample](https://datasets.tardis.dev/v1/binance-european-options/options_chain/2024/01/01/OPTIONS.csv.gz)                  |

### API Access and data format

Historical data format is the same as provided by real-time Binance European Options WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="binance-european-options",
        from_date="2026-01-01",
        to_date="2026-01-02",
        filters=[Channel(name="depth20")],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Binance European Options real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'binance-european-options',
  from: '2026-01-01',
  to: '2026-01-02',
  filters: [{ channel: 'depth20' }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01&filters=[{"channel":"depth20"}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01&filters=[{%22channel%22:%22depth20%22}]&offset=0>" %}
Example API response for Binance European Options historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance-european-options","filters":[{"channel":"depth20"}],"from":"2026-01-01","to":"2026-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://developers.binance.com/docs/derivatives/options-trading/websocket-market-streams>" %}
See Binance European Options WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (since 2025-12-17):**

* [optionTrade](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01\&filters=\[{%22channel%22:%22optionTrade%22}]) — available since **2025-12-17** Public option trade executions stream
* [depth20](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01\&filters=\[{%22channel%22:%22depth20%22}]) — available since **2025-12-17** Options order book updates stream with top 20 levels subscribed as @depth20\@100ms
* [bookTicker](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01\&filters=\[{%22channel%22:%22bookTicker%22}]) — available since **2025-12-17** Best bid and best ask updates stream
* [optionTicker](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01\&filters=\[{%22channel%22:%22optionTicker%22}]) — available since **2025-12-17** Options ticker updates stream
* [optionMarkPrice](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01\&filters=\[{%22channel%22:%22optionMarkPrice%22}]) — available since **2025-12-17** Option mark price updates stream
* [optionOpenInterest](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01\&filters=\[{%22channel%22:%22optionOpenInterest%22}]) — available since **2025-12-17** Option open interest updates stream
* [optionIndexPrice](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-01-01\&filters=\[{%22channel%22:%22optionIndexPrice%22}]) — available since **2025-12-17** Option index price updates stream

**Legacy channels (eapi v1, until 2025-12-17):**

* [trade](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2024-06-01\&filters=\[{%22channel%22:%22trade%22}]) — available until **2025-12-17** Public options trade executions stream
* [depth100](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2024-01-01\&filters=\[{%22channel%22:%22depth100%22}]) — available until **2025-12-17** Options order book updates stream with top 100 levels
* [index](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2024-06-01\&filters=\[{%22channel%22:%22index%22}]) — available until **2025-12-17** Options index price updates stream
* [ticker](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) — available until **2025-12-17** Options ticker updates stream
* [openInterest](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2024-06-01\&filters=\[{%22channel%22:%22openInterest%22}]) — available until **2025-12-17** Options open interest updates stream
* [markPrice](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2024-06-01\&filters=\[{%22channel%22:%22markPrice%22}]) — available until **2025-12-17** Options mark price updates stream
* [!optionSymbol](https://api.tardis.dev/v1/data-feeds/binance-european-options?from=2026-03-01\&filters=\[{%22channel%22:%22!optionSymbol%22}]\&offset=0) — available since **2025-12-17** Option contract metadata and status updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Binance European Options is located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://fstream.binance.com/public/stream`.

{% hint style="info" %}
Binance servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Binance Spot

Binance historical market data details - currency pairs, data coverage and data collection specifics

Binance historical data for **high caps currency pairs** is available since **2019-03-30**, data for all currency pairs is available since **2021-03-05**.

{% embed url="<https://api.tardis.dev/v1/exchanges/binance>" %}
See Binance historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                         |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSDT | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance/incremental_book_L2/2019/12/01/BTCUSDT.csv.gz) |
| trades                | BTCUSDT | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance/trades/2019/12/01/BTCUSDT.csv.gz)              |
| quotes                | BTCUSDT | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance/quotes/2019/12/01/BTCUSDT.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Binance WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="binance",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="depth", symbols=["btcusdt"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Binance real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'binance',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'depth', symbols: ['btcusdt'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance?from=2023-03-01&filters=[{"channel":"depth","symbols":["btcusdt"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance?from=2023-03-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22btcusdt%22]}]&offset=0>" %}
Example API response for Binance historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance","filters":[{"channel":"depth","symbols":["btcusdt"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://binance-docs.github.io/apidocs/spot/en/#websocket-market-streams>" %}
See Binance WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/binance?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public spot trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/binance?from=2024-01-01\&filters=\[{%22channel%22:%22depth%22,%22symbols%22:\[%22btcusdt%22]}]) Incremental order book updates stream. Recorded with the fastest API cadence available at the time: until 2019-08-30 it was subscribed as `depth` (1000ms updates), after that as `depth@100ms` (100ms updates).
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/binance?from=2024-01-01\&filters=\[{%22channel%22:%22depthSnapshot%22,%22symbols%22:\[%22btcusdt%22]}]) — generated channel Binance real-time WebSocket API **does not provide initial order book snapshots**. To overcome this issue we fetch initial order book snapshots from REST API and store them together with the rest of the WebSocket messages — top 1000 levels. Such snapshot messages are marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true` fields.

  During data collection integrity of order book incremental updates is being **validated** using [sequence numbers](https://binance-docs.github.io/apidocs/spot/en/#how-to-manage-a-local-order-book-correctly) provided by real-time feed (`U` and `u` fields) — in case of detecting missed message WebSocket connection is being restarted. We also validate if initial book snapshot fetched from REST API overlaps with received `depth` messages.
* [bookTicker](https://api.tardis.dev/v1/data-feeds/binance?from=2024-01-01\&filters=\[{%22channel%22:%22bookTicker%22,%22symbols%22:\[%22btcusdt%22]}]) — available since **2019-09-21** Best bid and best ask updates stream
* [aggTrade](https://api.tardis.dev/v1/data-feeds/binance?from=2024-01-01\&filters=\[{%22channel%22:%22aggTrade%22}]) — available since **2019-11-19** Aggregated spot trade executions stream
* [ticker](https://api.tardis.dev/v1/data-feeds/binance?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22btcusdt%22]}]) 24h spot ticker updates stream
* [borrowInterest](https://api.tardis.dev/v1/data-feeds/binance?from=2024-01-01\&filters=\[{%22channel%22:%22borrowInterest%22}]) — generated channel, available since **2021-02-23** Margin borrow interest snapshots stream. Polled from Binance margin REST endpoint about every minute. Messages are marked as `"stream":"<asset>@borrowInterest"` and `"generated":true`.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Binance **since 2020-05-18** is located in GCP asia-northeast1 region (Tokyo, Japan), before that it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://stream.binance.com/stream?timeUnit=microsecond`.

{% hint style="info" %}
Binance servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Binance US

Binance US  historical market data details - currency pairs, data coverage and data collection specifics

Binance US exchange historical data for **all its currency pairs** is available since **2019-09-25**.

{% embed url="<https://api.tardis.dev/v1/exchanges/binance-us>" %}
See Binance US historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                           |
| --------------------- | ------ | ---------- | --------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance-us/incremental_book_L2/2019/12/01/BTCUSD.csv.gz) |
| trades                | BTCUSD | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance-us/trades/2019/12/01/BTCUSD.csv.gz)              |
| quotes                | BTCUSD | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance-us/quotes/2019/12/01/BTCUSD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Binance US WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="binance-us",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="depth", symbols=["btcusd"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Binance US real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'binance-us',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'depth', symbols: ['btcusd'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance-us?from=2023-03-01&filters=[{"channel":"depth","symbols":["btcusd"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance-us?from=2023-03-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22btcusd%22]}]&offset=0>" %}
Example API response for Binance US historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance-us","filters":[{"channel":"depth","symbols":["btcusd"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://github.com/binance-us/binance-official-api-docs>" %}
See Binance US WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/binance-us?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22,%22symbols%22:\[%22btcusdt%22]}]) Public spot trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/binance-us?from=2024-01-01\&filters=\[{%22channel%22:%22depth%22,%22symbols%22:\[%22btcusdt%22]}]) Incremental order book updates stream subscribed as @depth\@100ms
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/binance-us?from=2024-01-01\&filters=\[{%22channel%22:%22depthSnapshot%22,%22symbols%22:\[%22btcusdt%22]}]) — generated Generated full order book snapshots stream. Binance.US real-time WebSocket API does not provide initial order book snapshots. To overcome this issue we fetch initial order book snapshots from REST API and store them together with the rest of the WebSocket messages (top 1000 levels). Snapshot messages are marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true`.

  During data collection, integrity of incremental order book updates is validated using sequence numbers from the real-time feed (U and u fields). If a missed message is detected, the WebSocket connection is restarted. Initial book snapshots fetched from REST API are also validated for overlap with received depth messages.
* [bookTicker](https://api.tardis.dev/v1/data-feeds/binance-us?from=2024-01-01\&filters=\[{%22channel%22:%22bookTicker%22,%22symbols%22:\[%22btcusdt%22]}]) Best bid and best ask updates stream
* [aggTrade](https://api.tardis.dev/v1/data-feeds/binance-us?from=2024-01-01\&filters=\[{%22channel%22:%22aggTrade%22,%22symbols%22:\[%22btcusdt%22]}]) — available since **2019-11-19** Aggregated spot trade executions stream
* [ticker](https://api.tardis.dev/v1/data-feeds/binance-us?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22btcusdt%22]}]) 24h spot ticker updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Binance US is located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://stream.binance.us:9443/stream`.

{% hint style="info" %}
Binance.US servers are located in AWS us-east-1 region (N. Virginia, USA).
{% endhint %}


# OKX Futures

OKX Futures historical market data details - instruments, data coverage and data collection specifics

OKX historical data for **all its futures instruments** is available since **2019-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/okex-futures>" %}
See OKX Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Liquidations datasets are available since 2020-12-18.
{% endhint %}

| data type             | symbol         | date       |                                                                                                                     |
| --------------------- | -------------- | ---------- | ------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD-200103 | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-futures/incremental_book_L2/2020/01/01/BTC-USD-200103.csv.gz) |
| trades                | BTC-USD-200103 | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-futures/trades/2020/01/01/BTC-USD-200103.csv.gz)              |
| derivative\_ticker    | BTC-USD-200103 | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-futures/derivative_ticker/2020/01/01/BTC-USD-200103.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time OKX WebSocket **v5** API with addition of local timestamps (before 2021-12-23 it was **v3** API version). If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="okex-futures",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="books", symbols=["BTC-USD-240329"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by OKX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'okex-futures',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'books', symbols: ['BTC-USD-240329'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01&filters=[{"channel":"books","symbols":["BTC-USD-240329"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01&filters=[{%22channel%22:%22books%22,%22symbols%22:[%22BTC-USD-240329%22]}]&offset=0>" %}
Example API response for OKX Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"okex-futures","filters":[{"channel":"books","symbols":["BTC-USD-240329"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.okx.com/docs-v5/en/>" %}
See OKX Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v5, since 2021-12-23):**

* [trades](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public futures trade executions stream
* [trades-all](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22trades-all%22}]) — available since **2023-10-19** All trades stream including non-aggregated trade messages
* [books-l2-tbt](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22books-l2-tbt%22}]) — available until **2026-05-21** Tick-by-tick L2 futures order book updates
* [books](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22books%22}]) — available from **2023-02-24** to **2024-07-19**, and from **2026-05-21** onward Incremental futures order book depth updates
* [bbo-tbt](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22bbo-tbt%22}]) — available since **2022-05-05** Tick-by-tick best bid and offer updates
* [tickers](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22}]) 24h futures ticker updates
* [liquidations](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22liquidations%22}]) Liquidation events with at most one update per second per contract
* [liquidation-orders](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-03-01\&filters=\[{%22channel%22:%22liquidation-orders%22}]) — available since **2023-03-30** Liquidation orders with at most one update per second per contract
* [open-interest](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22open-interest%22}]) Open interest updates
* [mark-price](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22mark-price%22}]) Mark price updates with keepalive up to 10s when unchanged
* [index-tickers](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22index-tickers%22}]) Index ticker updates with keepalive up to 1m when unchanged
* [funding-rate](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2026-09-01\&filters=\[{%22channel%22:%22funding-rate%22}]) — available since **2026-08-05** for X-Perp futures Funding rate updates for X-Perp futures with upcoming funding time (30s to 90s cadence); source for normalized `derivative_ticker` messages
* [price-limit](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22price-limit%22}]) Price limit updates
* [status](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22status%22}]) Exchange status and maintenance notifications
* [instruments](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22instruments%22}]) Instrument state updates (listing, suspension, parameter changes)
* [long-short-account-ratio](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22long-short-account-ratio%22}]) — generated channel Long/short account ratio snapshots from REST statistics endpoint (1m). From **2023-06-09 15:30 UTC** to **2026-08-04 11:16 UTC**, updates occurred at varying intervals longer than the documented 1m.
* [taker-volume](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22taker-volume%22}]) — generated channel Taker buy/sell volume snapshots from REST statistics endpoint (1m). From **2023-06-09 15:30 UTC** to **2026-08-04 11:16 UTC**, updates occurred at varying intervals longer than the documented 1m.
* [estimated-price](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22estimated-price%22}]) Estimated delivery/settlement price updates
* [public-block-trades](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22public-block-trades%22}]) — available since **2023-01-01** Public block trades stream
* [public-struc-block-trades](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-01-01\&filters=\[{%22channel%22:%22public-struc-block-trades%22}]) — available since **2023-01-01** Public structured block trades stream
* [taker-volume-contract](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-09-01\&filters=\[{%22channel%22:%22taker-volume-contract%22}]) — generated channel, available since **2024-08-08** Contract-level taker buy/sell volume snapshots from REST statistics endpoint
* [long-short-account-ratio-contract-top-trader](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-09-01\&filters=\[{%22channel%22:%22long-short-account-ratio-contract-top-trader%22}]) — generated channel, available since **2024-08-08** Contract-level top-trader long/short account ratio snapshots from REST statistics endpoint
* [long-short-position-ratio-contract-top-trader](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-09-01\&filters=\[{%22channel%22:%22long-short-position-ratio-contract-top-trader%22}]) — generated channel, available since **2024-08-08** Contract-level top-trader long/short position ratio snapshots from REST statistics endpoint
* [long-short-account-ratio-contract](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2024-09-01\&filters=\[{%22channel%22:%22long-short-account-ratio-contract%22}]) — generated channel, available since **2024-08-08** Contract-level long/short account ratio snapshots from REST statistics endpoint

**Legacy channels (API v3, until 2021-12-23):**

* [futures/trade](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2019-12-01\&filters=\[{%22channel%22:%22futures/trade%22}]) Public futures trade executions stream
* [futures/depth](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2019-12-01\&filters=\[{%22channel%22:%22futures/depth%22}]) — available **until 2020-01-29** Incremental futures order book updates (legacy depth channel)
* [futures/depth\_l2\_tbt](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2020-01-01\&filters=\[{%22channel%22:%22futures/depth_l2_tbt%22,%22symbols%22:\[%22BTC-USD-200103%22]}]) — available since **2019-12-03** Tick-by-tick L2 futures order book updates with sequencing
* [futures/ticker](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2020-01-01\&filters=\[{%22channel%22:%22futures/ticker%22,%22symbols%22:\[%22BTC-USD-200103%22]}]) 24h futures ticker updates
* [futures/liquidation](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2021-01-01\&filters=\[{%22channel%22:%22futures/liquidation%22}]) — available since **2020-12-17** Futures liquidation events
* [futures/mark\_price](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2020-01-01\&filters=\[{%22channel%22:%22futures/mark_price%22,%22symbols%22:\[%22BTC-USD-200103%22]}]) Mark price with keepalive up to 10s when unchanged
* [index/ticker](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2020-01-01\&filters=\[{%22channel%22:%22index/ticker%22}]) — available since **2019-09-20** Index ticker for futures contracts with keepalive up to 1m when unchanged
* [system/status](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2020-08-01\&filters=\[{%22channel%22:%22system/status%22}]) — available since **2020-07-01** Exchange status and maintenance notifications
* [information/sentiment](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2021-01-01\&filters=\[{%22channel%22:%22information/sentiment%22}]) — generated channel, available since **2020-10-28** Market sentiment ratio metrics
* [information/long\_short\_ratio](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2021-01-01\&filters=\[{%22channel%22:%22information/long_short_ratio%22}]) — generated channel, available since **2020-10-28** Long/short account ratio metrics
* [information/margin](https://api.tardis.dev/v1/data-feeds/okex-futures?from=2021-01-01\&filters=\[{%22channel%22:%22information/margin%22}]) — generated channel, available since **2020-10-28** Margin ratio metrics

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for OKX Futures is located in GCP asia-northeast1 region (Tokyo, Japan) since **2026-05-21**. Before that, from **2022-05-04**, it was located in AWS HK region (Hong Kong, China, VPC colo setup), before that, since **2020-05-15** it was located in GCP asia-northeast1 region (Tokyo, Japan) and initially it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.okx.com:8443/ws/v5/public`. Before **2026-05-21**, data was captured from the OKX colocation endpoint at `wss://awscolows1.okx.com:8443/ws/v5/public`.

{% hint style="info" %}
OKX servers are located in Alibaba Cloud cn-hongkong region (Hong Kong, China).
{% endhint %}


# OKX Swap

OKX Swap historical market data details - instruments, data coverage and data collection specifics

OKX historical data for **all its perpetual swap instruments** is available since **2019-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/okex-swap>" %}
See OKX Swap historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Liquidations datasets are available since 2020-12-18.
{% endhint %}

| data type             | symbol       | date       |                                                                                                                |
| --------------------- | ------------ | ---------- | -------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD-SWAP | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-swap/incremental_book_L2/2020/01/01/BTC-USD-SWAP.csv.gz) |
| trades                | BTC-USD-SWAP | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-swap/trades/2020/01/01/BTC-USD-SWAP.csv.gz)              |
| derivative\_ticker    | BTC-USD-SWAP | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-swap/derivative_ticker/2020/01/01/BTC-USD-SWAP.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time OKX WebSocket **v5** API with addition of local timestamps (before 2021-12-23 it was **v3** API version). If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="okex-swap",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="books", symbols=["BTC-USD-SWAP"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by OKX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'okex-swap',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'books', symbols: ['BTC-USD-SWAP'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01&filters=[{"channel":"books","symbols":["BTC-USD-SWAP"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01&filters=[{%22channel%22:%22books%22,%22symbols%22:[%22BTC-USD-SWAP%22]}]&offset=0>" %}
Example API response for OKX Swap historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"okex-swap","filters":[{"channel":"books","symbols":["BTC-USD-SWAP"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.okx.com/docs-v5/en/>" %}
See OKX WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v5, since 2021-12-23):**

* [trades](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) Public swap trade executions stream
* [trades-all](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22trades-all%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) — available since **2023-10-19** All trades stream including non-aggregated trade messages
* [books-l2-tbt](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22books-l2-tbt%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) — available until **2026-05-21** Tick-by-tick L2 swap order book updates (10ms)
* [books](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2023-06-01\&filters=\[{%22channel%22:%22books%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) — available from **2023-02-24** to **2024-07-19**, and from **2026-05-21** onward Incremental swap order book depth updates (100ms)
* [bbo-tbt](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22bbo-tbt%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) — available since **2022-05-05** Tick-by-tick best bid and offer updates (10ms)
* [tickers](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) 24h swap ticker updates (100ms)
* [liquidations](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22liquidations%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) Liquidation events with at most one update per second per contract
* [liquidation-orders](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-03-01\&filters=\[{%22channel%22:%22liquidation-orders%22}]) — available since **2023-03-30** Liquidation orders with at most one update per second per contract
* [open-interest](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22open-interest%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) Open interest updates (3s)
* [mark-price](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22mark-price%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) Mark price updates with keepalive up to 10s when unchanged (200ms)
* [funding-rate](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22funding-rate%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) Funding rate updates with upcoming funding time (30s to 90s cadence)
* [index-tickers](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22index-tickers%22}]) Index ticker updates with keepalive up to 1m when unchanged (100ms)
* [price-limit](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22price-limit%22,%22symbols%22:\[%22BTC-USDT-SWAP%22]}]) Price limit updates (200ms)
* [status](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22status%22}]) Exchange status and maintenance notifications
* [instruments](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22instruments%22}]) Instrument state updates (listing, suspension, parameter changes)
* [long-short-account-ratio](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22long-short-account-ratio%22}]) Long/short account ratio snapshots from REST statistics endpoint (1m). From **2023-06-09 15:30 UTC** to **2026-08-04 11:16 UTC**, updates occurred at varying intervals longer than the documented 1m.
* [taker-volume](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22taker-volume%22}]) Taker buy/sell volume snapshots from REST statistics endpoint (1m). From **2023-06-09 15:30 UTC** to **2026-08-04 11:16 UTC**, updates occurred at varying intervals longer than the documented 1m.
* [public-block-trades](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22public-block-trades%22}]) — available since **2023-01-01** Public block trades stream (15m)
* [public-struc-block-trades](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-01-01\&filters=\[{%22channel%22:%22public-struc-block-trades%22}]) — available since **2023-01-01** Public structured block trades stream (15m)
* [taker-volume-contract](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-09-01\&filters=\[{%22channel%22:%22taker-volume-contract%22}]) — available since **2024-08-08** Contract-level taker buy/sell volume snapshots from REST statistics endpoint (1m)
* [long-short-account-ratio-contract-top-trader](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-09-01\&filters=\[{%22channel%22:%22long-short-account-ratio-contract-top-trader%22}]) — available since **2024-08-08** Contract-level top-trader long/short account ratio snapshots (1m)
* [long-short-position-ratio-contract-top-trader](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-09-01\&filters=\[{%22channel%22:%22long-short-position-ratio-contract-top-trader%22}]) — available since **2024-08-08** Contract-level top-trader long/short position ratio snapshots (1m)
* [long-short-account-ratio-contract](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2024-09-01\&filters=\[{%22channel%22:%22long-short-account-ratio-contract%22}]) — available since **2024-08-08** Contract-level long/short account ratio snapshots from REST statistics endpoint (1m)

**Legacy channels (API v3, until 2021-12-23):**

* [swap/trade](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2020-01-01\&filters=\[{%22channel%22:%22swap/trade%22,%22symbols%22:\[%22BTC-USD-SWAP%22]}]) — until **2021-12-23** Public swap trade executions stream
* [swap/depth](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2019-08-01\&filters=\[{%22channel%22:%22swap/depth%22,%22symbols%22:\[%22BTC-USD-SWAP%22]}]) — until **2020-02-13** Incremental swap order book updates (legacy depth channel, 100ms)
* [swap/depth\_l2\_tbt](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2020-06-01\&filters=\[{%22channel%22:%22swap/depth_l2_tbt%22,%22symbols%22:\[%22BTC-USD-SWAP%22]}]) — available since **2020-02-07**, until **2021-12-23** Tick-by-tick L2 swap order book updates with sequencing
* [swap/ticker](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2020-01-01\&filters=\[{%22channel%22:%22swap/ticker%22,%22symbols%22:\[%22BTC-USD-SWAP%22]}]) — until **2021-12-23** 24h swap ticker updates
* [swap/liquidation](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2021-01-01\&filters=\[{%22channel%22:%22swap/liquidation%22}]) — available since **2020-12-18**, until **2021-12-23** Swap liquidation events
* [swap/funding\_rate](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2020-01-01\&filters=\[{%22channel%22:%22swap/funding_rate%22,%22symbols%22:\[%22BTC-USD-SWAP%22]}]) — until **2021-12-23** Funding rate updates
* [swap/mark\_price](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2020-01-01\&filters=\[{%22channel%22:%22swap/mark_price%22,%22symbols%22:\[%22BTC-USD-SWAP%22]}]) — until **2021-12-23** Mark price with keepalive up to 10s when unchanged
* [index/ticker](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2020-01-01\&filters=\[{%22channel%22:%22index/ticker%22}]) — available since **2019-09-20**, until **2021-12-23** Index ticker for swap contracts with keepalive up to 1m when unchanged
* [system/status](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2020-08-01\&filters=\[{%22channel%22:%22system/status%22}]) — available since **2020-07-01**, until **2021-12-23** Exchange status and maintenance notifications
* [information/sentiment](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2021-01-01\&filters=\[{%22channel%22:%22information/sentiment%22}]) — available since **2020-10-28**, until **2021-12-23** Market sentiment ratio metrics (75s, REST polling)
* [information/long\_short\_ratio](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2021-01-01\&filters=\[{%22channel%22:%22information/long_short_ratio%22}]) — available since **2020-10-28**, until **2021-12-23** Long/short account ratio metrics (75s, REST polling)
* [information/margin](https://api.tardis.dev/v1/data-feeds/okex-swap?from=2021-01-01\&filters=\[{%22channel%22:%22information/margin%22}]) — available since **2020-10-28**, until **2021-12-23** Margin ratio metrics (75s, REST polling)

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for OKX Swap is located in GCP asia-northeast1 region (Tokyo, Japan) since **2026-05-21**. Before that, from **2022-05-04**T16:45, it was located in AWS HK region (Hong Kong, China, VPC colo setup), before that, starting since **2020-05-15** it was located in GCP asia-northeast1 (Tokyo, Japan) and initially it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.okx.com:8443/ws/v5/public`. Before **2026-05-21**, data was captured from the OKX colocation endpoint at `wss://awscolows1.okx.com:8443/ws/v5/public`.

{% hint style="info" %}
OKX servers are located in Alibaba Cloud cn-hongkong region (Hong Kong, China).
{% endhint %}


# OKX Options

OKX Options historical market data details - instruments, data coverage and data collection specifics

OKX historical data for **all its options instruments** is available since **2020-02-01**.

{% embed url="<https://api.tardis.dev/v1/exchanges/okex-options>" %}
See OKX Options historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol                | date       |                                                                                                                            |
| --------------------- | --------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD-200327-8500-P | 2020-03-01 | [Download sample](https://datasets.tardis.dev/v1/okex-options/incremental_book_L2/2020/03/01/BTC-USD-200327-8500-P.csv.gz) |
| trades                | BTC-USD-200327-8500-P | 2020-03-01 | [Download sample](https://datasets.tardis.dev/v1/okex-options/trades/2020/03/01/BTC-USD-200327-8500-P.csv.gz)              |
| options\_chain        | OPTIONS               | 2020-03-01 | [Download sample](https://datasets.tardis.dev/v1/okex-options/options_chain/2020/03/01/OPTIONS.csv.gz)                     |

### API Access and data format

Historical data format is the same as provided by real-time OKX WebSocket **v5** API with addition of local timestamps (before 2021-12-23 it was **v3** API version). If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="okex-options",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="books", symbols=[])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by OKX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'okex-options',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'books', symbols: [] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01&filters=[{"channel":"books","symbols":[]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01&filters=[{%22channel%22:%22books%22,%22symbols%22:[]}]&offset=0>" %}
Example API response for OKX Options historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"okex-options","filters":[{"channel":"books","symbols":[]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.okx.com/docs-v5/en/>" %}
See OKX Options WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v5, since 2021-12-23):**

* [trades](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public options trade executions stream
* [trades-all](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22trades-all%22}]) — available since **2023-10-19** All trades stream including non-aggregated trade messages
* [option-trades](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22option-trades%22}]) — available since **2023-03-30** Option trades stream
* [books-l2-tbt](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22books-l2-tbt%22}]) — available until **2026-05-21** Tick-by-tick L2 options order book updates
* [books](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22books%22}]) — available from **2023-02-24** to **2024-07-19**, and from **2026-05-21** onward Incremental options order book depth updates
* [bbo-tbt](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22bbo-tbt%22}]) — available since **2022-05-05** Tick-by-tick best bid and offer updates
* [tickers](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22}]) 24h options ticker updates
* [opt-summary](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22opt-summary%22}]) Option summary with greeks, implied volatility and contract statistics
* [index-tickers](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22index-tickers%22}]) Index ticker updates with keepalive up to 1m when unchanged
* [open-interest](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22open-interest%22}]) Open interest updates
* [mark-price](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22mark-price%22}]) Mark price updates with keepalive up to 10s when unchanged
* [status](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22status%22}]) Exchange status and maintenance notifications
* [instruments](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22instruments%22}]) Instrument state updates (listing, suspension, parameter changes)
* [price-limit](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22price-limit%22}]) Price limit updates
* [estimated-price](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22estimated-price%22}]) Estimated delivery/settlement price updates
* [public-block-trades](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22public-block-trades%22}]) — available since **2023-01-01** Public block trades stream
* [public-struc-block-trades](https://api.tardis.dev/v1/data-feeds/okex-options?from=2024-01-01\&filters=\[{%22channel%22:%22public-struc-block-trades%22}]) — available since **2023-01-01** Public structured block trades stream

**Legacy channels (API v3, until 2021-12-23):**

* [option/trade](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22option/trade%22}]) — available until **2021-12-23** Public options trade executions stream
* [option/trades](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22option/trades%22}]) — available since **2020-07-30**, until **2021-12-23** Public options trade executions stream
* [option/depth](https://api.tardis.dev/v1/data-feeds/okex-options?from=2020-02-01\&filters=\[{%22channel%22:%22option/depth%22}]) — available until **2020-02-13** Incremental options order book updates (legacy depth channel)
* [option/depth\_l2\_tbt](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22option/depth_l2_tbt%22}]) — available since **2020-02-07**, until **2021-12-23** Tick-by-tick L2 options order book updates with sequencing
* [option/ticker](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22option/ticker%22}]) — available until **2021-12-23** 24h options ticker updates
* [option/summary](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22option/summary%22}]) — available until **2021-12-23** Option summary with greeks, implied volatility and contract statistics
* [index/ticker](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22index/ticker%22}]) — available since **2020-06-08**, until **2021-12-23** Index ticker for options contracts with keepalive up to 1m when unchanged
* [option/instruments](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22option/instruments%22}]) — available until **2021-12-23** Option instruments metadata updates (listing, expiry, contract parameter changes)
* [system/status](https://api.tardis.dev/v1/data-feeds/okex-options?from=2021-01-01\&filters=\[{%22channel%22:%22system/status%22}]) — available since **2020-07-01**, until **2021-12-23** Exchange status and maintenance notifications

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for OKX Options is located in GCP asia-northeast1 region (Tokyo, Japan) since **2026-05-21**. Before that, from **2022-05-04**, it was located in AWS HK region (Hong Kong, China, VPC colo setup), before that, since **2020-05-15** it was located in GCP asia-northeast1 region (Tokyo, Japan) and initially it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.okx.com:8443/ws/v5/public`. Before **2026-05-21**, data was captured from the OKX colocation endpoint at `wss://awscolows1.okx.com:8443/ws/v5/public`.

{% hint style="info" %}
OKX servers are located in Alibaba Cloud cn-hongkong region (Hong Kong, China).
{% endhint %}


# OKX Spot

OKX Spot historical market data details - currency pairs, data coverage and data collection specifics

OKX historical data for **spot high caps currency pairs** is available since **2019-03-30**, data for all spot currency pairs is available since **2021-03-11**.

{% embed url="<https://api.tardis.dev/v1/exchanges/okex>" %}
See OKX Spot historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol   | date       |                                                                                                       |
| --------------------- | -------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USDT | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex/incremental_book_L2/2020/01/01/BTC-USDT.csv.gz) |
| trades                | BTC-USDT | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex/trades/2020/01/01/BTC-USDT.csv.gz)              |
| quotes                | BTC-USDT | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex/quotes/2020/01/01/BTC-USDT.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time OKX WebSocket **v5** API with addition of local timestamps (before 2021-12-23 it was **v3** API version). If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="okex",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="books", symbols=["BTC-USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by OKX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'okex',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'books', symbols: ['BTC-USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01&filters=[{"channel":"books","symbols":["BTC-USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01&filters=[{%22channel%22:%22books%22,%22symbols%22:[%22BTC-USDT%22]}]&offset=0>" %}
Example API response for OKX Spot historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"okex","filters":[{"channel":"books","symbols":["BTC-USDT"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.okx.com/docs-v5/en/>" %}
See OKX Spot WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v5, since 2021-12-23):**

* [trades](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public spot trade executions stream
* [trades-all](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22trades-all%22}]) — available since **2023-10-19** All trades stream including non-aggregated trade messages
* [books-l2-tbt](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22books-l2-tbt%22}]) — available until **2026-05-21** Tick-by-tick L2 spot order book updates
* [books](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22books%22}]) — available from **2023-02-24** to **2024-07-19**, and from **2026-05-21** onward Incremental spot order book depth updates
* [bbo-tbt](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22bbo-tbt%22}]) — available since **2022-05-05** Tick-by-tick best bid and offer updates
* [tickers](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22}]) 24h spot ticker updates
* [interest-rate-loan-quota](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22interest-rate-loan-quota%22}]) — generated channel Public interest rate and loan quota snapshots from REST endpoint
* [vip-interest-rate-loan-quota](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22vip-interest-rate-loan-quota%22}]) — generated channel VIP interest rate and loan quota snapshots from REST endpoint
* [status](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22status%22}]) Exchange status and maintenance notifications
* [instruments](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22instruments%22}]) Instrument state updates (listing, suspension, parameter changes)
* [taker-volume](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22taker-volume%22}]) — generated channel Taker buy/sell volume snapshots from REST statistics endpoint (1m). From **2023-06-09 15:30 UTC** to **2026-08-04 11:16 UTC**, updates occurred at varying intervals longer than the documented 1m.
* [liquidations](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22liquidations%22}]) — generated channel Margin liquidation events from REST liquidation orders endpoint
* [public-block-trades](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22public-block-trades%22}]) — available since **2023-01-01** Public block trades stream
* [public-struc-block-trades](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22public-struc-block-trades%22}]) — available since **2023-01-01** Public structured block trades stream
* [loan-ratio](https://api.tardis.dev/v1/data-feeds/okex?from=2024-01-01\&filters=\[{%22channel%22:%22loan-ratio%22}]) — generated channel Margin loan ratio snapshots from REST statistics endpoint (1m). From **2023-06-09 15:30 UTC** to **2026-08-04 11:16 UTC**, updates occurred at varying intervals longer than the documented 1m.

**Legacy channels (API v3, until 2021-12-23):**

* [spot/trade](https://api.tardis.dev/v1/data-feeds/okex?from=2021-01-01\&filters=\[{%22channel%22:%22spot/trade%22}]) Public spot trade executions stream
* [spot/depth](https://api.tardis.dev/v1/data-feeds/okex?from=2020-01-01\&filters=\[{%22channel%22:%22spot/depth%22}]) — available until **2020-04-11** Incremental spot order book updates (legacy depth channel)
* [spot/depth\_l2\_tbt](https://api.tardis.dev/v1/data-feeds/okex?from=2021-01-01\&filters=\[{%22channel%22:%22spot/depth_l2_tbt%22}]) — available since **2020-04-09** Tick-by-tick L2 spot order book updates with sequencing
* [spot/ticker](https://api.tardis.dev/v1/data-feeds/okex?from=2021-01-01\&filters=\[{%22channel%22:%22spot/ticker%22}]) 24h spot ticker updates
* [system/status](https://api.tardis.dev/v1/data-feeds/okex?from=2021-01-01\&filters=\[{%22channel%22:%22system/status%22}]) — available since **2020-07-01** Exchange status and maintenance notifications
* [margin/interest\_rate](https://api.tardis.dev/v1/data-feeds/okex?from=2021-06-01\&filters=\[{%22channel%22:%22margin/interest_rate%22}]) — available since **2021-02-24** Margin interest rate updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for OKX Spot is located in GCP asia-northeast1 region (Tokyo, Japan) since **2026-05-21**. Before that, from **2022-05-04**, it was located in AWS HK region (Hong Kong, China, VPC colo setup), before that, since **2020-05-15** it was located in GCP asia-northeast1 region (Tokyo, Japan) and initially it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.okx.com:8443/ws/v5/public`. Before **2026-05-21**, data was captured from the OKX colocation endpoint at `wss://awscolows1.okx.com:8443/ws/v5/public`.

{% hint style="info" %}
OKX servers are located in Alibaba Cloud cn-hongkong region (Hong Kong, China).
{% endhint %}


# OKX Nitro Spreads

OKX Nitro Spreads historical market data details - instruments, data coverage and data collection specifics

OKX Nitro Spreads historical data for **all its instruments** is available since **2023-12-22**.

{% embed url="<https://api.tardis.dev/v1/exchanges/okex-spreads>" %}
See OKX Nitro Spreads historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol                  | date       |                                                                                                                             |
| --------------------- | ----------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USDT\_BTC-USDT-SWAP | 2024-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-spreads/incremental_book_L2/2024/01/01/BTC-USDT_BTC-USDT-SWAP.csv.gz) |
| trades                | BTC-USDT\_BTC-USDT-SWAP | 2024-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-spreads/trades/2024/01/01/BTC-USDT_BTC-USDT-SWAP.csv.gz)              |
| quotes                | BTC-USDT\_BTC-USDT-SWAP | 2024-01-01 | [Download sample](https://datasets.tardis.dev/v1/okex-spreads/quotes/2024/01/01/BTC-USDT_BTC-USDT-SWAP.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time OKX WebSocket **v5** API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="okex-spreads",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="sprd-books5", symbols=[])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by OKX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'okex-spreads',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'sprd-books5', symbols: [] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/okex-spreads?from=2024-01-01&filters=[{"channel":"sprd-books5","symbols":[]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/okex-spreads?from=2024-01-01&filters=[{%22channel%22:%22sprd-books5%22,%22symbols%22:[]}]&offset=0>" %}
Example API response for OKX Nitro Spreads historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"okex-spreads","filters":[{"channel":"sprd-books5","symbols":[]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.okx.com/docs-v5/en/>" %}
See OKX Nitro Spreads WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [sprd-public-trades](https://api.tardis.dev/v1/data-feeds/okex-spreads?from=2024-01-01\&filters=\[{%22channel%22:%22sprd-public-trades%22}]) Public spread trade executions stream
* [sprd-books5](https://api.tardis.dev/v1/data-feeds/okex-spreads?from=2024-01-01\&filters=\[{%22channel%22:%22sprd-books5%22}]) Spread order book depth updates
* [sprd-bbo-tbt](https://api.tardis.dev/v1/data-feeds/okex-spreads?from=2024-01-01\&filters=\[{%22channel%22:%22sprd-bbo-tbt%22}]) Tick-by-tick best bid and offer updates
* [sprd-tickers](https://api.tardis.dev/v1/data-feeds/okex-spreads?from=2024-01-01\&filters=\[{%22channel%22:%22sprd-tickers%22}]) 24h spread ticker updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for OKX Nitro Spreads is located in GCP asia-northeast1 region (Tokyo, Japan) since **2026-05-21**. Before that, it was located in AWS ap-east-1 region (Hong Kong, China, VPC colo setup).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.okx.com:8443/ws/v5/business`. Before **2026-05-21**, data was captured from the OKX colocation endpoint at `wss://awscolows1.okx.com:8443/ws/v5/business`.

{% hint style="info" %}
OKX servers are located in Alibaba Cloud cn-hongkong region (Hong Kong, China).
{% endhint %}


# Coinbase Exchange

Coinbase Exchange historical market data details - currency pairs, data coverage and data collection specifics

{% hint style="info" %}
Coinbase Exchange market data is subject to Coinbase market data license restrictions.

See the applicable [Coinbase market data license restrictions](https://docs.tardis.dev/historical-data-details/pages/-LkYDB4Q2h9uctu9Kq7Y#id-23.-coinbase-market-data-license-restrictions).
{% endhint %}

Coinbase Exchange historical data for **all its currency pairs** is available since **2019-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/coinbase>" %}
See Coinbase Exchange historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                          |
| --------------------- | ------- | ---------- | -------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/coinbase/incremental_book_L2/2019/07/01/BTC-USD.csv.gz) |
| trades                | BTC-USD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/coinbase/trades/2019/07/01/BTC-USD.csv.gz)              |
| quotes                | BTC-USD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/coinbase/quotes/2019/07/01/BTC-USD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Coinbase Exchange WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="coinbase",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="l2update", symbols=["BTC-USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Coinbase Exchange real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'coinbase',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'l2update', symbols: ['BTC-USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01&filters=[{"channel":"l2update","symbols":["BTC-USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01&filters=[{%22channel%22:%22l2update%22,%22symbols%22:[%22BTC-USD%22]}]&offset=0>" %}
Example API response for Coinbase Exchange historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"coinbase","filters":[{"channel":"l2update","symbols":["BTC-USD"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.cdp.coinbase.com/exchange/websocket-feed/overview>" %}
See Coinbase Exchange WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [match](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22match%22}]) Trade match events from the matches channel
* [l2update](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22l2update%22}]) Level 2 order book updates
* [snapshot](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22snapshot%22}]) Level 2 order book snapshots
* [ticker](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Ticker updates with last trade and best bid and ask
* [subscriptions](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22subscriptions%22}]) Subscription acknowledgements stream
* [received](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22received%22}]) Order received events from the full channel
* [open](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22open%22}]) Order open events from the full channel
* [done](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22done%22}]) Order done and cancel events from the full channel
* [change](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22change%22}]) Order change events from the full channel
* [last\_match](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22last_match%22}]) Most recent trade included with ticker updates
* [full\_snapshot](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22full_snapshot%22,%22symbols%22:\[%22BTC-USD%22]}]) — generated channel Generated full order book L3 snapshots stream. Coinbase full channel does not provide initial snapshots, so snapshots are fetched from REST API and emitted as `"type":"full_snapshot"` with `"generated":true`. This enables historical full (L3) order book reconstruction and sequence-overlap validation against websocket full updates (enabled since 2020-06-11).
* [rfq\_matches](https://api.tardis.dev/v1/data-feeds/coinbase?from=2024-01-01\&filters=\[{%22channel%22:%22rfq_matches%22}]) RFQ match events stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Coinbase Exchange is located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws-direct.exchange.coinbase.com`.

{% hint style="info" %}
Coinbase Exchange servers are located in AWS us-east-1 region (N. Virginia, USA).
{% endhint %}


# Coinbase International

Coinbase International historical market data details - instruments, data coverage and data collection specifics

{% hint style="info" %}
Coinbase International market data is subject to Coinbase market data license restrictions.

See the applicable [Coinbase market data license restrictions](https://docs.tardis.dev/historical-data-details/pages/-LkYDB4Q2h9uctu9Kq7Y#id-23.-coinbase-market-data-license-restrictions).
{% endhint %}

Coinbase International historical data for **all its instruments** is available since **2024-10-31**.

{% embed url="<https://api.tardis.dev/v1/exchanges/coinbase-international>" %}
See Coinbase International historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol   | date       |                                                                                                                         |
| --------------------- | -------- | ---------- | ----------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-PERP | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/coinbase-international/incremental_book_L2/2025/01/01/BTC-PERP.csv.gz) |
| trades                | BTC-PERP | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/coinbase-international/trades/2025/01/01/BTC-PERP.csv.gz)              |
| derivative\_ticker    | BTC-PERP | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/coinbase-international/derivative_ticker/2025/01/01/BTC-PERP.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Coinbase International WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="coinbase-international",
        from_date="2024-11-01",
        to_date="2024-11-02",
        filters=[Channel(name="LEVEL2", symbols=["BTC-PERP"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Coinbase International real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'coinbase-international',
  from: '2024-11-01',
  to: '2024-11-02',
  filters: [{ channel: 'LEVEL2', symbols: ['BTC-PERP'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2024-11-01&filters=[{"channel":"LEVEL2","symbols":["BTC-PERP"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2024-11-01&filters=[{%22channel%22:%22LEVEL2%22,%22symbols%22:[%22BTC-PERP%22]}]&offset=0>" %}
Example API response for Coinbase International historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"coinbase-international","filters":[{"channel":"LEVEL2","symbols":["BTC-PERP"]}],"from":"2024-11-01","to":"2024-11-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.cdp.coinbase.com/international-exchange/websocket-feed/channels>" %}
See Coinbase International WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [MATCH](https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2025-01-01\&filters=\[{%22channel%22:%22MATCH%22}]) Trade match events stream
* [LEVEL2](https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2025-01-01\&filters=\[{%22channel%22:%22LEVEL2%22,%22symbols%22:\[%22BTC-PERP%22]}]) Order book snapshots and deltas
* [LEVEL1](https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2025-01-01\&filters=\[{%22channel%22:%22LEVEL1%22,%22symbols%22:\[%22BTC-PERP%22]}]) Top of book bid and ask updates
* [FUNDING](https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2025-01-01\&filters=\[{%22channel%22:%22FUNDING%22}]) Funding rate and next funding time updates
* [RISK](https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2025-01-01\&filters=\[{%22channel%22:%22RISK%22}]) Risk parameter updates
* [INSTRUMENTS](https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2025-01-01\&filters=\[{%22channel%22:%22INSTRUMENTS%22}]) Instrument metadata and trading state updates
* [CANDLES\_ONE\_MINUTE](https://api.tardis.dev/v1/data-feeds/coinbase-international?from=2025-01-01\&filters=\[{%22channel%22:%22CANDLES_ONE_MINUTE%22}]) One minute candle updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Coinbase International is located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws-md.international.coinbase.com`.

{% hint style="info" %}
Coinbase International servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# BitMEX

BitMEX historical market data details - available data, coverage and data collection specifics

BitMEX historical data for **all its instruments** is available since **2019-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bitmex>" %}
See BitMEX historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                       |
| --------------------- | ------ | ---------- | ----------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | XBTUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/bitmex/incremental_book_L2/2019/07/01/XBTUSD.csv.gz) |
| trades                | XBTUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/bitmex/trades/2019/07/01/XBTUSD.csv.gz)              |
| derivative\_ticker    | XBTUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/bitmex/derivative_ticker/2019/07/01/XBTUSD.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time BitMEX WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bitmex",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="orderBookL2_25", symbols=["XBTUSD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by BitMEX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitmex',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'orderBookL2_25', symbols: ['XBTUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitmex?from=2023-03-01&filters=[{"channel":"orderBookL2_25","symbols":["XBTUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitmex?from=2023-03-01&filters=[{%22channel%22:%22orderBookL2_25%22,%22symbols%22:[%22XBTUSD%22]}]&offset=0>" %}
Example API response for BitMEX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitmex","filters":[{"channel":"orderBookL2_25","symbols":["XBTUSD"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.bitmex.com/app/wsAPI>" %}
See BitMEX WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22,%22symbols%22:\[%22XBTUSD%22]}]) Public trade executions stream
* [orderBookL2](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22orderBookL2%22,%22symbols%22:\[%22XBTUSD%22]}]\&offset=1) Order book snapshots and deltas by price level
* [quote](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22quote%22}]\&offset=0) Best bid and ask quote updates
* [liquidation](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22liquidation%22}]\&offset=0) Liquidation events stream
* [instrument](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22instrument%22}]) Instrument state snapshots and deltas with bidPrice/askPrice/midPrice on 5s timer. `partial` messages returned via HTTP API may contain data for all BitMEX instruments and require filtering client-side if only selected symbols were requested
* [connected](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22connected%22}]) Connection heartbeat and system status events
* [announcement](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22announcement%22}]) Exchange announcements stream
* [chat](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22chat%22}]) Public chat messages stream
* [publicNotifications](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22publicNotifications%22}]) Public notification messages stream
* [settlement](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22settlement%22}]) Contract settlement events stream
* [funding](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22funding%22}]\&offset=1200) Funding rate updates stream
* [insurance](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22insurance%22}]) Daily insurance fund balance updates
* [orderBookL2\_25](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22orderBookL2_25%22}]) Order book snapshots and deltas with up to 25 levels
* [orderBook10](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22orderBook10%22}]) — available since **2021-02-20** Top 10 level order book snapshots, throttled to 50ms since 2023-09-19
* [quoteBin1m](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22quoteBin1m%22}]\&offset=0) Quote bins at 1 minute interval
* [quoteBin5m](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22quoteBin5m%22}]) Quote bins at 5 minute interval
* [quoteBin1h](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22quoteBin1h%22}]) Quote bins at 1 hour interval
* [quoteBin1d](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22quoteBin1d%22}]) Quote bins at 1 day interval
* [tradeBin1m](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22tradeBin1m%22}]) Trade bins at 1 minute interval
* [tradeBin5m](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22tradeBin5m%22}]) Trade bins at 5 minute interval
* [tradeBin1h](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22tradeBin1h%22}]) Trade bins at 1 hour interval
* [tradeBin1d](https://api.tardis.dev/v1/data-feeds/bitmex?from=2024-01-01\&filters=\[{%22channel%22:%22tradeBin1d%22}]) Trade bins at 1 day interval

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for BitMEX is located in GCP asia-northeast1 region (Tokyo, Japan). Before **2025-08-23** it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **single WebSocket connection** to `wss://direct.bitmex.com:443/realtimePublic`.

{% hint style="info" %}
BitMEX servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Deribit

Deribit historical market data details - available data, coverage and data collection specifics

Deribit historical data for **all its instruments (including all options)** is available since **2019-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/deribit>" %}
See Deribit historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol        | date       |                                                                                                               |
| --------------------- | ------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-PERPETUAL | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/deribit/incremental_book_L2/2019/07/01/BTC-PERPETUAL.csv.gz) |
| trades                | BTC-PERPETUAL | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/deribit/trades/2019/07/01/BTC-PERPETUAL.csv.gz)              |
| options\_chain        | OPTIONS       | 2020-03-01 | [Download sample](https://datasets.tardis.dev/v1/deribit/options_chain/2020/03/01/OPTIONS.csv.gz)             |

### API Access and data format

Historical data format is the same as provided by real-time Deribit WebSocket **v2** API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="deribit",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="book", symbols=["BTC-PERPETUAL"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Deribit real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'deribit',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'book', symbols: ['BTC-PERPETUAL'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01&filters=[{"channel":"book","symbols":["BTC-PERPETUAL"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[%22BTC-PERPETUAL%22]}]&offset=0>" %}
Example API response for Deribit historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"deribit","filters":[{"channel":"book","symbols":["BTC-PERPETUAL"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.deribit.com/v2/#subscriptions>" %}
See Deribit WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Trade executions stream. Collected with raw interval (no aggregation). Until 2023-10-03 included real-time liquidation info — Deribit removed the liquidation field from public trade subscriptions to avoid sharing price-sensitive data.
* [book](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22book%22,%22symbols%22:\[%22BTC-PERPETUAL%22]}]) Order book incremental updates stream with sequence number validation. Collected with raw interval (no aggregation). During data collection integrity of order book incremental updates is being **validated** using [sequence numbers](https://docs.deribit.com/v2/#book-instrument_name-interval) provided by Deribit's real-time feed (`prev_change_id`) - in case of detecting missed message WebSocket connection is being restarted.
* [ticker](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22BTC-PERPETUAL%22]}]) — available since **2019-10-01** Instrument ticker updates stream including price, volume, open interest, funding rate and Greeks for options. Collected with raw interval (no aggregation).
* [deribit\_price\_index](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22deribit_price_index%22}]) Real-time index price updates stream used across pricing, margining and settlement
* [deribit\_price\_ranking](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22deribit_price_ranking%22}]) Price ranking updates for the component exchanges used to calculate the Deribit index
* [deribit\_volatility\_index](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22deribit_volatility_index%22}]) — available since **2021-04-01** Volatility index (DVOL) updates stream
* [estimated\_expiration\_price](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22estimated_expiration_price%22}]) Estimated expiration (delivery) price updates stream
* [markprice.options](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22markprice.options%22}]) — available since **2019-10-01** Options mark price and implied volatility updates stream for all options under a given index
* [perpetual](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22perpetual%22,%22symbols%22:\[%22BTC-PERPETUAL%22]}]) — available since **2019-10-01** Perpetual instrument interest rate and index price updates stream. Collected with raw interval (no aggregation).
* [quote](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22quote%22,%22symbols%22:\[%22BTC-PERPETUAL%22]}]) — available since **2019-10-01** Best bid and ask price and size updates stream
* [platform\_state](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22platform_state%22}]) — available since **2019-12-31** Platform state, maintenance and price index lock notifications stream
* [instrument.state.any](https://api.tardis.dev/v1/data-feeds/deribit?from=2024-01-01\&filters=\[{%22channel%22:%22instrument.state.any%22}]) Instrument lifecycle state updates stream (new listings, expirations, settlements)

### Market data collection details

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

Real-time market data is captured via **multiple WebSocket connections** to `wss://www.deribit.com/ws/api/v2` (proxied via Cloudflare).

{% hint style="info" %}
Deribit servers are located in Equinix LD4 (Slough, UK).
{% endhint %}


# Bybit Derivatives

Bybit Derivatives historical market data details - available instruments, data coverage and data collection specifics

Bybit Derivatives historical data for **all its inverse contracts** is available since **2019-11-07** (for linear contracts since 2020-05-28).

{% embed url="<https://api.tardis.dev/v1/exchanges/bybit>" %}
See Bybit Derivatives historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Liquidations datasets are available since 2020-12-18.
{% endhint %}

| data type             | symbol     | date       |                                                                                                      |
| --------------------- | ---------- | ---------- | ---------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD     | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/bybit/incremental_book_L2/2020/01/01/BTCUSD.csv.gz) |
| trades                | BTCUSD     | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/bybit/trades/2020/01/01/BTCUSD.csv.gz)              |
| quotes                | BTCUSD     | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/bybit/quotes/2020/01/01/BTCUSD.csv.gz)              |
| derivative\_ticker    | BTCUSD     | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/bybit/derivative_ticker/2020/01/01/BTCUSD.csv.gz)   |
| trades                | ETHUSD     | 2020-03-01 | [Download sample](https://datasets.tardis.dev/v1/bybit/trades/2020/03/01/ETHUSD.csv.gz)              |
| incremental\_book\_L2 | ETHUSD     | 2020-03-01 | [Download sample](https://datasets.tardis.dev/v1/bybit/incremental_book_L2/2020/03/01/ETHUSD.csv.gz) |
| liquidations          | PERPETUALS | 2021-09-01 | [Download sample](https://datasets.tardis.dev/v1/bybit/liquidations/2021/09/01/PERPETUALS.csv.gz)    |

### API Access and data format

Historical data format is the same as provided by real-time Bybit Derivatives WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bybit",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="orderbook.50", symbols=["BTCUSD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bybit Derivatives real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bybit',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'orderbook.50', symbols: ['BTCUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bybit?from=2024-01-01&filters=[{"channel":"orderbook.50","symbols":["BTCUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bybit?from=2024-01-01&filters=[{%22channel%22:%22orderbook.50%22,%22symbols%22:[%22BTCUSD%22]}]&offset=0>" %}
Example API response for Bybit Derivatives historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bybit","filters":[{"channel":"orderbook.50","symbols":["BTCUSD"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://bybit-exchange.github.io/docs/v5/intro>" %}
See Bybit Derivatives WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [publicTrade](https://api.tardis.dev/v1/data-feeds/bybit?from=2024-01-01\&filters=\[{%22channel%22:%22publicTrade%22}]) — available since **2023-04-05** Real-time public trade executions stream
* [orderbook.50](https://api.tardis.dev/v1/data-feeds/bybit?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook.50%22}]) — available since **2023-04-05** Order book snapshots and deltas at depth 50
* [orderbook.rpi](https://api.tardis.dev/v1/data-feeds/bybit?from=2026-09-01\&filters=\[{%22channel%22:%22orderbook.rpi%22,%22symbols%22:\[%22BTCUSDT%22]}]) — available since **2026-08-19** Order book snapshots and deltas at depth 50. Each level contains price, non-RPI quantity, and RPI quantity.
* [orderbook.full](https://api.tardis.dev/v1/data-feeds/bybit?from=2026-09-01\&filters=\[{%22channel%22:%22orderbook.full%22,%22symbols%22:\[%22BTCUSDT%22]}]) — available since **2026-08-19** Full-depth incremental order book updates with generated initial snapshots. The WebSocket feed is delta-only and excludes RPI orders. Tardis fetches initial snapshots with up to 10,000 levels per side from Bybit's full order book REST endpoint. Generated snapshots are marked with `"generated":true` and synchronized with buffered WebSocket updates using `u` and `seq`.
* [orderbook.500](https://api.tardis.dev/v1/data-feeds/bybit?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook.500%22}]) — available since **2023-04-05** — available until **2025-09-05** Order book snapshots and deltas at depth 500
* [orderbook.1000](https://api.tardis.dev/v1/data-feeds/bybit?from=2025-10-01\&filters=\[{%22channel%22:%22orderbook.1000%22,%22symbols%22:\[%22BTCUSDT%22]}]) — available since **2025-09-04** — available until **2026-08-19** Order book snapshots and deltas at depth 1000
* [orderbook.1](https://api.tardis.dev/v1/data-feeds/bybit?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook.1%22}]) — available since **2023-04-05** Order book snapshots and deltas at depth 1
* [allLiquidation](https://api.tardis.dev/v1/data-feeds/bybit?from=2025-03-01\&filters=\[{%22channel%22:%22allLiquidation%22}]) — available since **2025-02-25** All liquidation events stream with 500ms push frequency
* [tickers](https://api.tardis.dev/v1/data-feeds/bybit?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22}]) — available since **2023-04-05** Ticker snapshots and deltas with 24h stats and reference prices
* [trade](https://api.tardis.dev/v1/data-feeds/bybit?from=2023-03-01\&filters=\[{%22channel%22:%22trade%22,%22symbols%22:\[%22BTCUSDT%22]}]) — available until **2023-04-05** Public trade executions stream
* [orderBookL2\_25](https://api.tardis.dev/v1/data-feeds/bybit?from=2023-03-01\&filters=\[{%22channel%22:%22orderBookL2_25%22,%22symbols%22:\[%22BTCUSDT%22]}]) — available until **2023-04-05** Order book snapshots and deltas at depth 25
* [orderBook\_200](https://api.tardis.dev/v1/data-feeds/bybit?from=2023-03-01\&filters=\[{%22channel%22:%22orderBook_200%22,%22symbols%22:\[%22BTCUSDT%22]}]) — available since **2019-12-23** — available until **2023-04-05** Order book snapshots and deltas at depth 200
* [liquidation](https://api.tardis.dev/v1/data-feeds/bybit?from=2023-03-01\&filters=\[{%22channel%22:%22liquidation%22,%22symbols%22:\[%22BTCUSDT%22]}]\&offset=50) — available since **2020-11-03** — available until **2023-04-05** Liquidation stream for each symbol, up to one message per second
* [instrument\_info](https://api.tardis.dev/v1/data-feeds/bybit?from=2023-03-01\&filters=\[{%22channel%22:%22instrument_info%22,%22symbols%22:\[%22BTCUSDT%22]}]) — available until **2023-04-05** Instrument ticker and contract state updates
* [insurance](https://api.tardis.dev/v1/data-feeds/bybit?from=2022-11-01\&filters=\[{%22channel%22:%22insurance%22}]\&offset=49) — available until **2023-04-05** Insurance fund balance updates
* [long\_short\_ratio](https://api.tardis.dev/v1/data-feeds/bybit?from=2023-03-01\&filters=\[{%22channel%22:%22long_short_ratio%22}]) — available since **2022-03-20** — available until **2023-04-05** — generated channel Generated global long/short account ratio snapshots from REST account-ratio endpoint using 5min period buckets

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Bybit Derivatives **since 2020-05-28** is located in GCP asia-northeast1 (Tokyo, Japan), before that it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://stream.bybit.com/v5/public`.

{% hint style="info" %}
Bybit servers are located in AWS ap-southeast-1 region (Singapore, Asia Pacific).
{% endhint %}


# Bybit Spot

Bybit Spot historical market data details - available instruments, data coverage and data collection specifics

Bybit Spot historical data for **all its currency pairs** is available since **2021-12-04.**

{% embed url="<https://api.tardis.dev/v1/exchanges/bybit-spot>" %}
See Bybit Spot historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                            |
| --------------------- | ------- | ---------- | ---------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSDT | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/bybit-spot/incremental_book_L2/2023/03/01/BTCUSDT.csv.gz) |
| trades                | BTCUSDT | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/bybit-spot/trades/2023/03/01/BTCUSDT.csv.gz)              |
| quotes                | BTCUSDT | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/bybit-spot/quotes/2023/03/01/BTCUSDT.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time **Bybit Spot WebSocket API** with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bybit-spot",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="orderbook.50", symbols=["BTCUSDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bybit Spot real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bybit-spot',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'orderbook.50', symbols: ['BTCUSDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2024-01-01&filters=[{"channel":"orderbook.50","symbols":["BTCUSDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2024-01-01&filters=[{%22channel%22:%22orderbook.50%22,%22symbols%22:[%22BTCUSDT%22]}]&offset=0>" %}
Example API response for Bybit Spot historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bybit-spot","filters":[{"channel":"orderbook.50","symbols":["BTCUSDT"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://bybit-exchange.github.io/docs/v5/intro>" %}
See Bybit Spot WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**v5 API channels** (since 2023-04-05):

* [publicTrade](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2024-01-01\&filters=\[{%22channel%22:%22publicTrade%22}]) — available since **2023-04-05** Real-time public trade executions stream
* [orderbook.50](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook.50%22}]) — available since **2023-04-05** Order book snapshots and deltas at depth 50
* [orderbook.200](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2025-03-01\&filters=\[{%22channel%22:%22orderbook.200%22}]) — available since **2025-02-24** Order book snapshots and deltas at depth 200
* [orderbook.1](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook.1%22}]) — available since **2023-04-05** Order book snapshots and deltas at depth 1
* [tickers](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22}]) — available since **2023-04-05** Ticker snapshots and deltas with 24h stats
* [lt](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2024-01-01\&filters=\[{%22channel%22:%22lt%22}]) — available since **2023-04-05** Leveraged token NAV and basket updates

**v2 API channels** (before 2023-04-05):

* [trade](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2022-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2022-01-01\&filters=\[{%22channel%22:%22depth%22}]) Order book snapshots and deltas
* [bookTicker](https://api.tardis.dev/v1/data-feeds/bybit-spot?from=2022-01-01\&filters=\[{%22channel%22:%22bookTicker%22}]) Best bid and best ask updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Bybit Spot is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://stream.bybit.com/v5/public/spot`.

{% hint style="info" %}
Bybit servers are located in AWS ap-southeast-1 region (Singapore, Asia Pacific).
{% endhint %}


# Bybit Options

Bybit Options historical market data details - instruments, data coverage and data collection specifics

Bybit Options historical data for **all its instruments** is available since **2023-04-05**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bybit-options>" %}
See Bybit Options historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol              | date       |                                                                                                                           |
| --------------------- | ------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-29DEC23-25000-C | 2023-12-01 | [Download sample](https://datasets.tardis.dev/v1/bybit-options/incremental_book_L2/2023/12/01/BTC-29DEC23-25000-C.csv.gz) |
| trades                | BTC-29DEC23-25000-C | 2023-12-01 | [Download sample](https://datasets.tardis.dev/v1/bybit-options/trades/2023/12/01/BTC-29DEC23-25000-C.csv.gz)              |
| options\_chain        | OPTIONS             | 2024-01-01 | [Download sample](https://datasets.tardis.dev/v1/bybit-options/options_chain/2024/01/01/OPTIONS.csv.gz)                   |

### API Access and data format

Historical data format is the same as provided by real-time Bybit Options WebSocket **v5** API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bybit-options",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="orderbook.25", symbols=[])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bybit Options real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bybit-options',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'orderbook.25', symbols: [] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bybit-options?from=2024-01-01&filters=[{"channel":"orderbook.25","symbols":[]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bybit-options?from=2024-01-01&filters=[{%22channel%22:%22orderbook.25%22,%22symbols%22:[]}]&offset=0>" %}
Example API response for Bybit Options historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bybit-options","filters":[{"channel":"orderbook.25","symbols":[]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://bybit-exchange.github.io/docs/v5/intro>" %}
See Bybit Options WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [publicTrade](https://api.tardis.dev/v1/data-feeds/bybit-options?from=2024-01-01\&filters=\[{%22channel%22:%22publicTrade%22}]) Real-time public trade executions stream
* [orderbook.25](https://api.tardis.dev/v1/data-feeds/bybit-options?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook.25%22}]) Order book snapshots and deltas at depth 25
* [orderbook.100](https://api.tardis.dev/v1/data-feeds/bybit-options?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook.100%22}]) Order book snapshots and deltas at depth 100
* [tickers](https://api.tardis.dev/v1/data-feeds/bybit-options?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22}]) Ticker snapshots and deltas with greeks and IV

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Bybit Options is located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://stream.bybit.com/v5/public/option`.

{% hint style="info" %}
Bybit servers are located in AWS ap-southeast-1 region (Singapore, Asia Pacific).
{% endhint %}


# Kraken Futures

Kraken Futures historical market data details - available instruments, data coverage and data collection specifics

Kraken Futures historical data for **all its instruments** is available since **2019-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/cryptofacilities>" %}
See Kraken Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol     | date       |                                                                                                                    |
| --------------------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------ |
| incremental\_book\_L2 | PI\_XBTUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/cryptofacilities/incremental_book_L2/2019/07/01/PI_XBTUSD.csv.gz) |
| trades                | PI\_XBTUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/cryptofacilities/trades/2019/07/01/PI_XBTUSD.csv.gz)              |
| derivative\_ticker    | PI\_XBTUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/cryptofacilities/derivative_ticker/2019/07/01/PI_XBTUSD.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Kraken Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="cryptofacilities",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="book", symbols=["PI_XBTUSD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Kraken Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'cryptofacilities',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'book', symbols: ['PI_XBTUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01&filters=[{"channel":"book","symbols":["PI_XBTUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[%22PI_XBTUSD%22]}]&offset=0>" %}
Example API response for Kraken Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"cryptofacilities","filters":[{"channel":"book","symbols":["PI_XBTUSD"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.kraken.com/api/docs/futures-api/websocket/overview/>" %}
See Kraken Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Trade executions stream
* [book](https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01\&filters=\[{%22channel%22:%22book%22}]) Order book incremental updates stream validated with sequence numbers
* [book\_snapshot](https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01\&filters=\[{%22channel%22:%22book_snapshot%22}]) Order book snapshot stream
* [ticker](https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Derivative ticker updates stream
* [trade\_snapshot](https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01\&filters=\[{%22channel%22:%22trade_snapshot%22}]) Trade snapshot on subscription
* [heartbeat](https://api.tardis.dev/v1/data-feeds/cryptofacilities?from=2024-01-01\&filters=\[{%22channel%22:%22heartbeat%22}]) Heartbeat keepalive events stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Kraken Futures is located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://futures.kraken.com/ws/v1`.

{% hint style="info" %}
Kraken Futures servers are located in AWS eu-west-1 region (Dublin, Ireland).
{% endhint %}


# Kraken

Kraken historical market data details - currency pairs, data coverage and data collection specifics

Kraken historical data for **all its currency pairs** is available since **2019-06-04**.

{% embed url="<https://api.tardis.dev/v1/exchanges/kraken>" %}
See Kraken historical data coverage: available symbols, channels, date ranges and incidents
{% endembed %}

### Symbol changes

Kraken WebSocket v2 uses `BTC` and `DOGE` in exchange-native symbol IDs. WebSocket v1 used `XBT` and `XDG`. Use v1 symbols before **2026-07-10** and v2 symbols from that date onward. This applies to both base and quote currencies, for example:

* `XBT/USD` → `BTC/USD`
* `XDG/USD` → `DOGE/USD`
* `ETH/XBT` → `ETH/BTC`

To resolve symbol IDs programmatically, query the [Instruments Metadata API](/api/instruments-metadata-api) using normalized `baseCurrency` and `quoteCurrency` values:

```json
{
  "baseCurrency": "BTC",
  "quoteCurrency": "USD",
  "type": "spot"
}
```

The response includes both exchange-native symbol IDs:

| id        | active  | availableSince             | availableTo                |
| --------- | ------- | -------------------------- | -------------------------- |
| `XBT/USD` | `false` | `2019-06-04T00:00:00.000Z` | `2026-07-10T00:00:00.000Z` |
| `BTC/USD` | `true`  | `2026-07-10T00:00:00.000Z` |                            |

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

| data type             | symbol  | date       |                                                                                                        |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------ |
| incremental\_book\_L2 | XBT-USD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/kraken/incremental_book_L2/2019/07/01/XBT-USD.csv.gz) |
| trades                | XBT-USD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/kraken/trades/2019/07/01/XBT-USD.csv.gz)              |
| quotes                | XBT-USD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/kraken/quotes/2019/07/01/XBT-USD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Kraken WebSocket **v2** API from **2026-07-10** onward, with addition of local timestamps. Data before **2026-07-10** uses Kraken WebSocket **v1** format. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="kraken",
        from_date="2026-08-01",
        to_date="2026-08-02",
        filters=[Channel(name="book", symbols=["BTC/USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Kraken real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'kraken',
  from: '2026-08-01',
  to: '2026-08-02',
  filters: [{ channel: 'book', symbols: ['BTC/USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/kraken?from=2026-08-01&filters=[{"channel":"book","symbols":["BTC/USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/kraken?from=2026-08-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[%22BTC/USD%22]}]&offset=0>" %}
Example API response for Kraken historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"kraken","filters":[{"channel":"book","symbols":["BTC/USD"]}],"from":"2026-08-01","to":"2026-08-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.kraken.com/exchange/api-reference/spot-websocket>" %}
See Kraken WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v2, since 2026-07-10):**

* [trade](https://api.tardis.dev/v1/data-feeds/kraken?from=2026-08-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [book](https://api.tardis.dev/v1/data-feeds/kraken?from=2026-08-01\&filters=\[{%22channel%22:%22book%22,%22symbols%22:\[%22BTC/USD%22]}]) Level 2 order book snapshots and updates with `depth=1000`
* [ticker](https://api.tardis.dev/v1/data-feeds/kraken?from=2026-08-01\&filters=\[{%22channel%22:%22ticker%22}]) Level 1 market data and 24h statistics, published when the best bid or offer changes (`event_trigger=bbo`)
* [instrument](https://api.tardis.dev/v1/data-feeds/kraken?from=2026-08-01\&filters=\[{%22channel%22:%22instrument%22}]) Reference data snapshots and updates for all active assets and tradeable pairs, including tokenized assets

**Legacy channels (API v1, until 2026-07-10):**

* [trade](https://api.tardis.dev/v1/data-feeds/kraken?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [book](https://api.tardis.dev/v1/data-feeds/kraken?from=2024-01-01\&filters=\[{%22channel%22:%22book%22,%22symbols%22:\[%22XBT/USD%22]}]) Order book snapshots and deltas recorded with depth=1000
* [spread](https://api.tardis.dev/v1/data-feeds/kraken?from=2024-01-01\&filters=\[{%22channel%22:%22spread%22,%22symbols%22:\[%22XBT/USD%22]}]) Best bid and ask spread updates stream
* [ticker](https://api.tardis.dev/v1/data-feeds/kraken?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Ticker updates with best bid and ask plus 24h stats

### Market data collection details

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

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.kraken.com/v2`. Before **2026-07-10**, data was captured from Kraken WebSocket v1 at `wss://ws.kraken.com`.

{% hint style="info" %}
Kraken's Spot trading engine is hosted at Equinix in London, UK.
{% endhint %}


# Bitfinex Derivatives

Bitfinex Derivatives historical market data details - available instruments, data coverage and data collection specifics

Bitfinex exchange historical data for **all its derivative instruments** is available since **2019-09-14.**

{% embed url="<https://api.tardis.dev/v1/exchanges/bitfinex-derivatives>" %}
See Bitfinex Derivatives historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol      | date       |                                                                                                                          |
| --------------------- | ----------- | ---------- | ------------------------------------------------------------------------------------------------------------------------ |
| incremental\_book\_L2 | BTCF0-USTF0 | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitfinex-derivatives/incremental_book_L2/2019/12/01/BTCF0-USTF0.csv.gz) |
| trades                | BTCF0-USTF0 | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitfinex-derivatives/trades/2019/12/01/BTCF0-USTF0.csv.gz)              |
| derivative\_ticker    | BTCF0-USTF0 | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitfinex-derivatives/derivative_ticker/2019/12/01/BTCF0-USTF0.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Bitfinex WebSocket **v2** API with addition of local timestamps and **since 2020-05-27 also with addition of channel and symbol at the end of each message** which allows us providing filtering for the data server-side. If you'd like to work with normalized data format instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bitfinex-derivatives",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="book", symbols=["BTCF0:USTF0"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bitfinex real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitfinex-derivatives',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'book', symbols: ['BTCF0:USTF0'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2023-03-01&filters=[{"channel":"book","symbols":["BTCF0:USTF0"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2023-03-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[%22BTCF0:USTF0%22]}]&offset=0>" %}
Example API response for Bitfinex Derivatives historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitfinex-derivatives","filters":[{"channel":"book","symbols":["BTCF0:USTF0"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.bitfinex.com/v2/docs/ws-general>" %}
See Bitfinex WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public trade executions stream
* [book](https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2024-01-01\&filters=\[{%22channel%22:%22book%22}]) Order book snapshots and deltas (prec=P0, freq=F0, len=100) During data collection integrity of order book incremental updates is being **validated** using [sequence numbers](https://docs.bitfinex.com/v2/docs/ws-general#section-available-options) (SEQ\_ALL option) provided by real-time feed - in case of detecting missed message WebSocket connection is being restarted.
* [ticker](https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Derivative ticker updates with mark and funding related fields
* [liquidations](https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2024-01-01\&filters=\[{%22channel%22:%22liquidations%22}]) Forced liquidation events stream
* [status](https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2024-01-01\&filters=\[{%22channel%22:%22status%22}]) Instrument status and derivative market state updates
* [raw\_book](https://api.tardis.dev/v1/data-feeds/bitfinex-derivatives?from=2024-01-01\&filters=\[{%22channel%22:%22raw_book%22}]) Raw order book snapshots and deltas (prec=R0, freq=F0, len=100)

All data collection is performed with `TIMESTAMP` and `SEQ_ALL` config flags set.

{% hint style="info" %}
Since 2020-05-27 each collected Bitfinex real-time data message has appended channel and symbol at the end of array - this allows us providing data filtering via API. Before that date if filters are provided with API request, always all recorded, unfiltered data feed is being returned.
{% endhint %}

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Bitfinex Derivatives is located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://api-pub.bitfinex.com/ws/2`.

{% hint style="info" %}
Bitfinex servers are located in Market Synergy DC (Switzerland). All its public APIs are proxied through Cloudflare.
{% endhint %}


# Bitfinex

Bitfinex historical market data details - currency pairs, data coverage and data collection specifics

Bitfinex exchange historical data for: BTCUSD, BTCUST, ETHUSD, ETHUST, LTCUSD, TRXUSD, EOSUSD, XRPUSD, LEOUSD, BABUSD currency pairs is **available since 2019-05-23**, data for other high caps is available since 2020-05-28, data for all currency pairs is available since **2021-10-29**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bitfinex>" %}
See Bitfinex historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                         |
| --------------------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD | 2019-08-01 | [Download sample](https://datasets.tardis.dev/v1/bitfinex/incremental_book_L2/2019/08/01/BTCUSD.csv.gz) |
| trades                | BTCUSD | 2019-08-01 | [Download sample](https://datasets.tardis.dev/v1/bitfinex/trades/2019/08/01/BTCUSD.csv.gz)              |
| quotes                | BTCUSD | 2019-08-01 | [Download sample](https://datasets.tardis.dev/v1/bitfinex/quotes/2019/08/01/BTCUSD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Bitfinex WebSocket **v2** API with addition of local timestamps and **since 2020-05-27 also with addition of channel and symbol at the end of each message** which allows us providing filtering for the data server-side. If you'd like to work with normalized data format instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bitfinex",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="book", symbols=["BTCUSD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bitfinex real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitfinex',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'book', symbols: ['BTCUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitfinex?from=2023-03-01&filters=[{"channel":"book","symbols":["BTCUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitfinex?from=2023-03-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[%22BTCUSD%22]}]&offset=0>" %}
Example API response for Bitfinex historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitfinex","filters":[{"channel":"book","symbols":["BTCUSD"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.bitfinex.com/v2/docs/ws-general>" %}
See Bitfinex WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/bitfinex?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public trade executions stream
* [book](https://api.tardis.dev/v1/data-feeds/bitfinex?from=2024-01-01\&filters=\[{%22channel%22:%22book%22}]) Order book snapshots and deltas (prec=P0, freq=F0, len=100) During data collection integrity of order book incremental updates is being **validated** using [sequence numbers](https://docs.bitfinex.com/v2/docs/ws-general#section-available-options) (SEQ\_ALL option) provided by real-time feed - in case of detecting missed message WebSocket connection is being restarted.
* [ticker](https://api.tardis.dev/v1/data-feeds/bitfinex?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Ticker updates with best bid and ask plus 24h stats
* [raw\_book](https://api.tardis.dev/v1/data-feeds/bitfinex?from=2024-01-01\&filters=\[{%22channel%22:%22raw_book%22}]) Raw order book snapshots and deltas (prec=R0, freq=F0, len=100)

All data collection is performed with `TIMESTAMP` and `SEQ_ALL` config flags set.

{% hint style="info" %}
Since 2020-05-27 each collected Bitfinex real-time data message has appended channel and symbol at the end of array - this allows us providing data filtering via API. Before that date if filters are provided with API request, always all recorded, unfiltered data feed is being returned.
{% endhint %}

### Market data collection details

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

Real-time market data is captured via **multiple WebSocket connections** to `wss://api-pub.bitfinex.com/ws/2`.

{% hint style="info" %}
Bitfinex servers are located in Market Synergy DC (Switzerland). All its public APIs are proxied through Cloudflare.
{% endhint %}


# KuCoin Futures

KuCoin Futures historical market data details - instruments, data coverage and data collection specifics

KuCoin Futures historical data for **all its instruments** is available since **2024-01-25**.

{% embed url="<https://api.tardis.dev/v1/exchanges/kucoin-futures>" %}
See KuCoin Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol   | date       |                                                                                                                 |
| --------------------- | -------- | ---------- | --------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | XBTUSDTM | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/kucoin-futures/incremental_book_L2/2025/01/01/XBTUSDTM.csv.gz) |
| trades                | XBTUSDTM | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/kucoin-futures/trades/2025/01/01/XBTUSDTM.csv.gz)              |
| derivative\_ticker    | XBTUSDTM | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/kucoin-futures/derivative_ticker/2025/01/01/XBTUSDTM.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time KuCoin Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="kucoin-futures",
        from_date="2024-02-01",
        to_date="2024-02-02",
        filters=[Channel(name="contractMarket/level2", symbols=["XBTUSDTM"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by KuCoin Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'kucoin-futures',
  from: '2024-02-01',
  to: '2024-02-02',
  filters: [{ channel: 'contractMarket/level2', symbols: ['XBTUSDTM'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-02-01&filters=[{"channel":"contractMarket/level2","symbols":["XBTUSDTM"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-02-01&filters=[{%22channel%22:%22contractMarket/level2%22,%22symbols%22:[%22XBTUSDTM%22]}]&offset=0>" %}
Example API response for KuCoin Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"kucoin-futures","filters":[{"channel":"contractMarket/level2","symbols":["XBTUSDTM"]}],"from":"2024-02-01","to":"2024-02-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.kucoin.com/docs-new/websocket-api/base-info/get-public-token-futures>" %}
See KuCoin Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [contractMarket/execution](https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-06-01\&filters=\[{%22channel%22:%22contractMarket/execution%22}]) Public futures trade executions stream
* [contractMarket/level2](https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-06-01\&filters=\[{%22channel%22:%22contractMarket/level2%22,%22symbols%22:\[%22XBTUSDTM%22]}]) Futures Level 2 order book deltas stream
* [contractMarket/level2Snapshot](https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-06-01\&filters=\[{%22channel%22:%22contractMarket/level2Snapshot%22,%22symbols%22:\[%22XBTUSDTM%22]}]) — generated channel

  Generated futures Level 2 order book snapshots from REST API. Used to bootstrap book state before contractMarket/level2 deltas. Snapshot messages marked as `"generated":true` on topic `/contractMarket/level2Snapshot:<symbol>`.
* [contractMarket/tickerV2](https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-06-01\&filters=\[{%22channel%22:%22contractMarket/tickerV2%22,%22symbols%22:\[%22XBTUSDTM%22]}]) Futures ticker updates with mark price and funding fields
* [contract/instrument](https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-06-01\&filters=\[{%22channel%22:%22contract/instrument%22,%22symbols%22:\[%22XBTUSDTM%22]}]) Instrument status and parameter updates, mark/index up to 1s and funding up to 1m
* [contract/details](https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-06-01\&filters=\[{%22channel%22:%22contract/details%22,%22symbols%22:\[%22XBTUSDTM%22]}]) — generated channel

  Generated contract details snapshots from REST API. Includes open interest and contract state. Snapshot messages marked as `"generated":true` on topic `/contract/details:<symbol>`.
* [contractMarket/snapshot](https://api.tardis.dev/v1/data-feeds/kucoin-futures?from=2024-06-01\&filters=\[{%22channel%22:%22contractMarket/snapshot%22,%22symbols%22:\[%22XBTUSDTM%22]}]) Market snapshot stream with index and open interest data

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for KuCoin Futures is located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws-api-futures.kucoin.com`.

{% hint style="info" %}
KuCoin Futures servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# KuCoin Spot

KuCoin Spot historical market data details - instruments, data coverage and data collection specifics

KuCoin Spot exchange historical data for **all its currency pairs** is available since **2022-08-16**.

{% embed url="<https://api.tardis.dev/v1/exchanges/kucoin>" %}
See KuCoin Spot historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol   | date       |                                                                                                         |
| --------------------- | -------- | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USDT | 2023-02-01 | [Download sample](https://datasets.tardis.dev/v1/kucoin/incremental_book_L2/2023/02/01/BTC-USDT.csv.gz) |
| trades                | BTC-USDT | 2023-02-01 | [Download sample](https://datasets.tardis.dev/v1/kucoin/trades/2023/02/01/BTC-USDT.csv.gz)              |
| quotes                | BTC-USDT | 2023-02-01 | [Download sample](https://datasets.tardis.dev/v1/kucoin/quotes/2023/02/01/BTC-USDT.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time KuCoin Spot WebSocket **Market Data API v1** (<https://docs.kucoin.com/#websocket-feed>) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="kucoin",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="market/level2", symbols=["BTC-USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by KuCoin Spot real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'kucoin',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'market/level2', symbols: ['BTC-USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/kucoin?from=2024-01-01&filters=[{"channel":"market/level2","symbols":["BTC-USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/kucoin?from=2024-01-01&filters=[{%22channel%22:%22market/level2%22,%22symbols%22:[%22BTC-USDT%22]}]&offset=0>" %}
Example API response for KuCoin historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"kucoin","filters":[{"channel":"market/level2","symbols":["BTC-USDT"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.kucoin.com/docs-new/websocket-api>" %}
See KuCoin Spot WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [market/match](https://api.tardis.dev/v1/data-feeds/kucoin?from=2024-01-01\&filters=\[{%22channel%22:%22market/match%22}]) Public trade executions stream
* [market/level2](https://api.tardis.dev/v1/data-feeds/kucoin?from=2024-01-01\&filters=\[{%22channel%22:%22market/level2%22}]) Level 2 order book deltas stream
* [market/level2Snapshot](https://api.tardis.dev/v1/data-feeds/kucoin?from=2024-01-01\&filters=\[{%22channel%22:%22market/level2Snapshot%22}]) — generated channel Generated Level 2 order book snapshots from REST API. Used to bootstrap book state before market/level2 deltas. Snapshot messages marked as `"generated":true` on topic `/market/level2Snapshot:<symbol>`.
* [market/ticker](https://api.tardis.dev/v1/data-feeds/kucoin?from=2024-01-01\&filters=\[{%22channel%22:%22market/ticker%22}]) Ticker updates with best bid and ask plus 24h stats
* [market/snapshot](https://api.tardis.dev/v1/data-feeds/kucoin?from=2024-01-01\&filters=\[{%22channel%22:%22market/snapshot%22}]) Market summary snapshots stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for KuCoin Spot is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws-api-spot.kucoin.com`.

{% hint style="info" %}
KuCoin Spot servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Aster Futures

Aster Futures historical market data details - instruments, data coverage and data collection specifics

Aster Futures historical data for **all its perpetual instruments** is available since **2026-08-23**.

{% embed url="<https://api.tardis.dev/v1/exchanges/aster-futures>" %}
See Aster Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                               |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster-futures/incremental_book_L2/2026/09/01/BTCUSDT.csv.gz) |
| trades                | BTCUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster-futures/trades/2026/09/01/BTCUSDT.csv.gz)              |
| derivative\_ticker    | BTCUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster-futures/derivative_ticker/2026/09/01/BTCUSDT.csv.gz)   |
| liquidations          | BTCUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster-futures/liquidations/2026/09/01/BTCUSDT.csv.gz)        |
| book\_ticker          | BTCUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster-futures/book_ticker/2026/09/01/BTCUSDT.csv.gz)         |

### API Access and data format

Historical data format is the same as provided by Aster Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="aster-futures",
        from_date="2026-09-01",
        to_date="2026-09-02",
        filters=[Channel(name="depth", symbols=["btcusdt"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Aster Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'aster-futures',
  from: '2026-09-01',
  to: '2026-09-02',
  filters: [{ channel: 'depth', symbols: ['btcusdt'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01&filters=[{"channel":"depth","symbols":["btcusdt"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22btcusdt%22]}]&offset=0>" %}
Example API response for Aster Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"aster-futures","filters":[{"channel":"depth","symbols":["btcusdt"]}],"from":"2026-09-01","to":"2026-09-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://asterdex.github.io/aster-api-website/futures-v3/websocket-market-streams/>" %}
See Aster Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22trade%22,%22symbols%22:\[%22btcusdt%22]}]) Public futures trade executions stream
* [aggTrade](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22aggTrade%22,%22symbols%22:\[%22btcusdt%22]}]) Aggregated futures trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22depth%22,%22symbols%22:\[%22btcusdt%22]}]) Incremental futures order book updates stream. Subscribed as `depth@0ms` (real-time dynamically adjusted update speed).
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22depthSnapshot%22,%22symbols%22:\[%22btcusdt%22]}]) — generated channel Generated initial order book snapshots containing up to 1000 levels per side from the REST API, used to bootstrap depth updates. Snapshot messages are marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true`.

  During collection, depth sequence continuity and initial snapshot overlap are validated. The connection is restarted if a sequence gap is detected.
* [bookTicker](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22bookTicker%22,%22symbols%22:\[%22btcusdt%22]}]) Best bid and best ask futures updates stream
* [ticker](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22btcusdt%22]}]) 24h futures ticker updates stream
* [markPrice](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22markPrice%22,%22symbols%22:\[%22btcusdt%22]}]) Mark price and funding metrics stream. Subscribed as `@markPrice@1s`.
* [forceOrder](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22forceOrder%22,%22symbols%22:\[%22btcusdt%22]}]) Liquidation order stream publishing only the latest liquidation per symbol in each 1000ms window
* [assetIndex](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22assetIndex%22,%22symbols%22:\[%22btcusd%22]}]) Asset index updates stream
* [openInterest](https://api.tardis.dev/v1/data-feeds/aster-futures?from=2026-09-01\&filters=\[{%22channel%22:%22openInterest%22,%22symbols%22:\[%22btcusdt%22]}]) — generated channel Generated open interest snapshots from REST API. Snapshots are fetched from `/fapi/v3/openInterest` about every 30 seconds per instrument and are marked with `"stream":"<symbol>@openInterest"` and `"generated":true`.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Aster Futures is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://fstream.asterdex.com/stream`.

{% hint style="info" %}
Aster Futures servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Aster Spot

Aster Spot historical market data details - currency pairs, data coverage and data collection specifics

Aster Spot historical data for **all its currency pairs** is available since **2026-08-23**.

{% embed url="<https://api.tardis.dev/v1/exchanges/aster>" %}
See Aster Spot historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol    | date       |                                                                                                         |
| --------------------- | --------- | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | ASTERUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster/incremental_book_L2/2026/09/01/ASTERUSDT.csv.gz) |
| trades                | ASTERUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster/trades/2026/09/01/ASTERUSDT.csv.gz)              |
| quotes                | ASTERUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster/quotes/2026/09/01/ASTERUSDT.csv.gz)              |
| book\_ticker          | ASTERUSDT | 2026-09-01 | [Download sample](https://datasets.tardis.dev/v1/aster/book_ticker/2026/09/01/ASTERUSDT.csv.gz)         |

### API Access and data format

Historical data format is the same as provided by Aster Spot WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="aster",
        from_date="2026-09-01",
        to_date="2026-09-02",
        filters=[Channel(name="depth", symbols=["asterusdt"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Aster Spot real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'aster',
  from: '2026-09-01',
  to: '2026-09-02',
  filters: [{ channel: 'depth', symbols: ['asterusdt'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01&filters=[{"channel":"depth","symbols":["asterusdt"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22asterusdt%22]}]&offset=0>" %}
Example API response for Aster Spot historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"aster","filters":[{"channel":"depth","symbols":["asterusdt"]}],"from":"2026-09-01","to":"2026-09-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://asterdex.github.io/aster-api-website/spot-v3/websocket-market-streams/>" %}
See Aster Spot WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01\&filters=\[{%22channel%22:%22trade%22,%22symbols%22:\[%22asterusdt%22]}]) Public spot trade executions stream
* [aggTrade](https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01\&filters=\[{%22channel%22:%22aggTrade%22,%22symbols%22:\[%22asterusdt%22]}]) Aggregated spot trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01\&filters=\[{%22channel%22:%22depth%22,%22symbols%22:\[%22asterusdt%22]}]) Incremental order book updates stream. Subscribed as `depth@0ms` (real-time dynamically adjusted update speed).
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01\&filters=\[{%22channel%22:%22depthSnapshot%22,%22symbols%22:\[%22asterusdt%22]}]) — generated channel Generated initial order book snapshots containing up to 1000 levels per side from the REST API, used to bootstrap depth updates. Snapshot messages are marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true`.

  During collection, depth sequence continuity and initial snapshot overlap are validated. The connection is restarted if a sequence gap is detected.
* [bookTicker](https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01\&filters=\[{%22channel%22:%22bookTicker%22,%22symbols%22:\[%22asterusdt%22]}]) Best bid and best ask updates stream
* [ticker](https://api.tardis.dev/v1/data-feeds/aster?from=2026-09-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22asterusdt%22]}]) 24h spot ticker updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Aster Spot is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://sstream.asterdex.com/stream`.

{% hint style="info" %}
Aster Spot servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# MEXC Spot

MEXC Spot historical market data details - currency pairs, data coverage and data collection specifics

MEXC Spot historical data for **all its currency pairs** is available since **2026-06-25**.

{% embed url="<https://api.tardis.dev/v1/exchanges/mexc>" %}
See MEXC Spot historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                      |
| --------------------- | ------- | ---------- | ---------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSDT | 2026-07-01 | [Download sample](https://datasets.tardis.dev/v1/mexc/incremental_book_L2/2026/07/01/BTCUSDT.csv.gz) |
| trades                | BTCUSDT | 2026-07-01 | [Download sample](https://datasets.tardis.dev/v1/mexc/trades/2026/07/01/BTCUSDT.csv.gz)              |
| quotes                | BTCUSDT | 2026-07-01 | [Download sample](https://datasets.tardis.dev/v1/mexc/quotes/2026/07/01/BTCUSDT.csv.gz)              |
| book\_ticker          | BTCUSDT | 2026-07-01 | [Download sample](https://datasets.tardis.dev/v1/mexc/book_ticker/2026/07/01/BTCUSDT.csv.gz)         |

### API Access and data format

Historical data format is the same as provided by MEXC Spot WebSocket API v3 Market Streams with addition of local timestamps. MEXC Spot WebSocket market data is delivered as Protocol Buffers messages; Tardis.dev stores the decoded JSON form. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="mexc",
        from_date="2026-07-01",
        to_date="2026-07-02",
        filters=[Channel(name="spot@public.aggre.depth.v3.api.pb@10ms", symbols=["BTCUSDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by MEXC Spot real-time stream, decoded from protobuf to JSON
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'mexc',
  from: '2026-07-01',
  to: '2026-07-02',
  filters: [{ channel: 'spot@public.aggre.depth.v3.api.pb@10ms', symbols: ['BTCUSDT'] }],
  apiKey: 'YOUR_API_KEY'
});

// messages as provided by MEXC Spot real-time stream, decoded from protobuf to JSON
for await (const { localTimestamp, message } of messages) {
  console.log(localTimestamp, message);
}
```

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/mexc?from=2026-07-01&filters=[{"channel":"spot@public.aggre.depth.v3.api.pb@10ms","symbols":["BTCUSDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/mexc?from=2026-07-01&filters=[{%22channel%22:%22spot@public.aggre.depth.v3.api.pb@10ms%22,%22symbols%22:[%22BTCUSDT%22]}]&offset=0>" %}
Example API response for MEXC Spot historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"mexc","filters":[{"channel":"spot@public.aggre.depth.v3.api.pb@10ms","symbols":["BTCUSDT"]}],"from":"2026-07-01","to":"2026-07-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.mexc.com/api-docs/spot-v3/websocket-market-streams>" %}
See MEXC Spot WebSocket API v3 Market Streams docs providing documentation for each captured channel's format
{% endembed %}

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

* [spot@public.aggre.deals.v3.api.pb@10ms](https://api.tardis.dev/v1/data-feeds/mexc?from=2026-07-01\&filters=\[{%22channel%22:%22spot@public.aggre.deals.v3.api.pb@10ms%22,%22symbols%22:\[%22BTCUSDT%22]}]) Spot public trade executions stream
* [spot@public.aggre.depth.v3.api.pb@10ms](https://api.tardis.dev/v1/data-feeds/mexc?from=2026-07-01\&filters=\[{%22channel%22:%22spot@public.aggre.depth.v3.api.pb@10ms%22,%22symbols%22:\[%22BTCUSDT%22]}]) Spot order book incremental updates stream
* [spot@public.aggre.depth.snapshot.v3.api.pb@10ms](https://api.tardis.dev/v1/data-feeds/mexc?from=2026-07-01\&filters=\[{%22channel%22:%22spot@public.aggre.depth.snapshot.v3.api.pb@10ms%22,%22symbols%22:\[%22BTCUSDT%22]}]) Generated spot order book snapshots from REST API, up to 5000 levels. Snapshot messages are marked with `"generated":true`.
* [spot@public.aggre.bookTicker.v3.api.pb@10ms](https://api.tardis.dev/v1/data-feeds/mexc?from=2026-07-01\&filters=\[{%22channel%22:%22spot@public.aggre.bookTicker.v3.api.pb@10ms%22,%22symbols%22:\[%22BTCUSDT%22]}]) Best bid and ask price and amount updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for MEXC Spot is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://wbs-api.mexc.com/ws`.

{% hint style="info" %}
MEXC Spot servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# MEXC Futures

MEXC Futures historical market data details - available instruments, data coverage and data collection specifics

MEXC Futures historical data for **all its instruments** is available since **2026-06-25**.

{% embed url="<https://api.tardis.dev/v1/exchanges/mexc-futures>" %}
See MEXC Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol    | date       |                                                                                                               |
| --------------------- | --------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC\_USDT | 2026-07-01 | [Download sample](https://datasets.tardis.dev/v1/mexc-futures/incremental_book_L2/2026/07/01/BTC_USDT.csv.gz) |
| trades                | BTC\_USDT | 2026-07-01 | [Download sample](https://datasets.tardis.dev/v1/mexc-futures/trades/2026/07/01/BTC_USDT.csv.gz)              |
| derivative\_ticker    | BTC\_USDT | 2026-07-01 | [Download sample](https://datasets.tardis.dev/v1/mexc-futures/derivative_ticker/2026/07/01/BTC_USDT.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time MEXC Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="mexc-futures",
        from_date="2026-07-01",
        to_date="2026-07-02",
        filters=[Channel(name="push.depth", symbols=["BTC_USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by MEXC Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'mexc-futures',
  from: '2026-07-01',
  to: '2026-07-02',
  filters: [{ channel: 'push.depth', symbols: ['BTC_USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01&filters=[{"channel":"push.depth","symbols":["BTC_USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01&filters=[{%22channel%22:%22push.depth%22,%22symbols%22:[%22BTC_USDT%22]}]&offset=0>" %}
Example API response for MEXC Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"mexc-futures","filters":[{"channel":"push.depth","symbols":["BTC_USDT"]}],"from":"2026-07-01","to":"2026-07-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.mexc.com/api-docs/futures/websocket-api>" %}
See MEXC Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [push.deal](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.deal%22}]) Recent futures trades stream
* [push.depth](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.depth%22,%22symbols%22:\[%22BTC_USDT%22]}]) Futures depth updates stream
* [push.depth.snapshot](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.depth.snapshot%22,%22symbols%22:\[%22BTC_USDT%22]}]) Generated futures order book snapshots from REST API, up to 5000 levels. Snapshot messages are marked with `"generated":true`.
* [push.ticker](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.ticker%22,%22symbols%22:\[%22BTC_USDT%22]}]) Perpetual contracts latest price, best bid/ask, and 24h volume stream
* [push.index.price](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.index.price%22,%22symbols%22:\[%22BTC_USDT%22]}]) Perpetual contracts index price stream
* [push.fair.price](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.fair.price%22,%22symbols%22:\[%22BTC_USDT%22]}]) Perpetual contracts fair price stream
* [push.funding.rate](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.funding.rate%22,%22symbols%22:\[%22BTC_USDT%22]}]) Perpetual contracts funding rate updates stream
* [push.contract](https://api.tardis.dev/v1/data-feeds/mexc-futures?from=2026-07-01\&filters=\[{%22channel%22:%22push.contract%22}]) Perpetual contracts metadata updates stream. This channel is available in raw exchange-native format only.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for MEXC Futures is located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://contract.mexc.com/edge`.

{% hint style="info" %}
MEXC Futures servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Crypto.com

Crypto.com exchange historical market data details - instruments, data coverage and data collection specifics

Crypto.com exchange historical data for **all its instruments** is available since **2022-06-01**.

{% embed url="<https://api.tardis.dev/v1/exchanges/crypto-com>" %}
See Crypto.com exchange historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol      | date       |                                                                                                                |
| --------------------- | ----------- | ---------- | -------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD-PERP | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/crypto-com/incremental_book_L2/2023/03/01/BTCUSD-PERP.csv.gz) |
| trades                | BTCUSD-PERP | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/crypto-com/trades/2023/03/01/BTCUSD-PERP.csv.gz)              |
| derivative\_ticker    | BTCUSD-PERP | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/crypto-com/derivative_ticker/2023/03/01/BTCUSD-PERP.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Crypto.com Exchange WebSocket **Market Data API v1** (<https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#websocket-subscriptions>) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="crypto-com",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="book", symbols=["BTCUSD-PERP"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Crypto.com exchange real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'crypto-com',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'book', symbols: ['BTCUSD-PERP'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01&filters=[{"channel":"book","symbols":["BTCUSD-PERP"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[%22BTCUSD-PERP%22]}]&offset=0>" %}
Example API response for Crypto.com exchange historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"crypto-com","filters":[{"channel":"book","symbols":["BTCUSD-PERP"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#websocket-subscriptions>" %}
See Crypto.com exchange docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Trade executions stream
* [book](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01\&filters=\[{%22channel%22:%22book%22}]) Order book snapshots and updates stream with 5s heartbeat when unchanged
* [ticker](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Best bid/ask, last price and 24h stats stream
* [index](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01\&filters=\[{%22channel%22:%22index%22}]) — available since **2022-11-02** Index price updates stream
* [mark](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01\&filters=\[{%22channel%22:%22mark%22}]) — available since **2022-11-02** Mark price updates stream
* [funding](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2024-01-01\&filters=\[{%22channel%22:%22funding%22}]) — available since **2022-11-01** Funding rate updates stream
* [estimatedfunding](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2025-01-01\&filters=\[{%22channel%22:%22estimatedfunding%22}]) Estimated funding rate updates stream
* [settlement](https://api.tardis.dev/v1/data-feeds/crypto-com?from=2025-01-01\&filters=\[{%22channel%22:%22settlement%22}]) — available since **2022-11-01** Settlement price and event updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Crypto.com exchange is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://stream.crypto.com/exchange/v1/market` (proxied via Cloudflare).

{% hint style="info" %}
Crypto.com exchange servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Bitstamp

Bitstamp historical market data details - currency pairs, data coverage and data collection specifics

Bitstamp historical data for **all its currency pairs** is available since **2019-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bitstamp>" %}
See Bitstamp historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                         |
| --------------------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/bitstamp/incremental_book_L2/2019/07/01/BTCUSD.csv.gz) |
| trades                | BTCUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/bitstamp/trades/2019/07/01/BTCUSD.csv.gz)              |
| quotes                | BTCUSD | 2019-07-01 | [Download sample](https://datasets.tardis.dev/v1/bitstamp/quotes/2019/07/01/BTCUSD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Bitstamp WebSocket **v2** with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bitstamp",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="diff_order_book", symbols=["btcusd"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bitstamp real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitstamp',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'diff_order_book', symbols: ['btcusd'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitstamp?from=2023-03-01&filters=[{"channel":"diff_order_book","symbols":["btcusd"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitstamp?from=2023-03-01&filters=[{%22channel%22:%22diff_order_book%22,%22symbols%22:[%22btcusd%22]}]&offset=0>" %}
Example API response for Bitstamp historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitstamp","filters":[{"channel":"diff_order_book","symbols":["btcusd"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.bitstamp.net/websocket/v2/>" %}
See Bitstamp WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [live\_trades](https://api.tardis.dev/v1/data-feeds/bitstamp?from=2024-01-01\&filters=\[{%22channel%22:%22live_trades%22}]) Public trade executions stream
* [diff\_order\_book](https://api.tardis.dev/v1/data-feeds/bitstamp?from=2024-01-01\&filters=\[{%22channel%22:%22diff_order_book%22}]) Order book delta stream
* [live\_orders](https://api.tardis.dev/v1/data-feeds/bitstamp?from=2024-01-01\&filters=\[{%22channel%22:%22live_orders%22}]) Level 3 live order events stream

Bitstamp real-time WebSocket API **does not provide initial full order book snapshots** for `diff_order_book` and `live_orders` channels subscriptions. To overcome this issue we fetch initial order book snapshots from REST API and store them together with the rest of the WebSocket messages. Such snapshot messages are marked with `"event": "snapshot"` and `"generated": true` fields for respective channels.

### Market data collection details

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

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.bitstamp.net`.

{% hint style="info" %}
Bitstamp servers are located in AWS eu-central-1 region (Frankfurt, Germany).
{% endhint %}


# Bitget Futures

Bitget Futures historical market data details - currency pairs, data coverage and data collection specifics

Bitget Futures historical data is available since **2024-11-08**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bitget-futures>" %}
See Bitget Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                                |
| --------------------- | ------- | ---------- | -------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSDT | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitget-futures/incremental_book_L2/2024/12/01/BTCUSDT.csv.gz) |
| trades                | BTCUSDT | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitget-futures/trades/2024/12/01/BTCUSDT.csv.gz)              |
| derivative\_ticker    | BTCUSDT | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitget-futures/derivative_ticker/2024/12/01/BTCUSDT.csv.gz)   |
| book\_ticker          | BTCUSDT | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/bitget-futures/book_ticker/2025/01/01/BTCUSDT.csv.gz)         |
| liquidations          | BTCUSDT | 2026-05-01 | [Download sample](https://datasets.tardis.dev/v1/bitget-futures/liquidations/2026/05/01/BTCUSDT.csv.gz)        |

### API Access and data format

Historical data format is the same as provided by real-time Bitget Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bitget-futures",
        from_date="2026-05-01",
        to_date="2026-05-02",
        filters=[Channel(name="books", symbols=["BTCUSDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bitget Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitget-futures',
  from: '2026-05-01',
  to: '2026-05-02',
  filters: [{ channel: 'books', symbols: ['BTCUSDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2026-05-01&filters=[{"channel":"books","symbols":["BTCUSDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2026-05-01&filters=[{%22channel%22:%22books%22,%22symbols%22:[%22BTCUSDT%22]}]&offset=0>" %}
Example API response for Bitget Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitget-futures","filters":[{"channel":"books","symbols":["BTCUSDT"]}],"from":"2026-05-01","to":"2026-05-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.bitget.com/api-doc/uta/websocket/public/Order-Book-Channel>" %}
See Bitget Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v3, since 2026-04-28):**

* [publicTrade](https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2026-05-01\&filters=\[{%22channel%22:%22publicTrade%22,%22symbols%22:\[%22BTCUSDT%22]}]) Futures public trade executions stream
* [books](https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2026-05-01\&filters=\[{%22channel%22:%22books%22,%22symbols%22:\[%22BTCUSDT%22]}]) Full-depth futures order book snapshots and incremental updates stream, pushed every 50ms. During data collection, order book integrity is validated using Bitget `seq` and `pseq` fields.
* [books1](https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2026-05-01\&filters=\[{%22channel%22:%22books1%22,%22symbols%22:\[%22BTCUSDT%22]}]) Futures best bid and ask snapshots stream. Since 2026-04-28 collected through Bitget WebSocket API v3 at 1ms; before that, collected through API v2 at 10ms.
* [ticker](https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2026-05-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22BTCUSDT%22]}]) Futures ticker with funding rate, open interest, mark price and index price. Since 2026-04-28 collected through Bitget WebSocket API v3 at 300ms; before that, collected through API v2 at 150ms.
* [liquidation](https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2026-05-01\&filters=\[{%22channel%22:%22liquidation%22}]) — available since **2026-04-28** Futures liquidation events stream, pushed every 20s or when 10,000 liquidation records are accumulated.

**Legacy channels (API v2, until 2026-04-28):**

* [trade](https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2025-01-01\&filters=\[{%22channel%22:%22trade%22}]) Futures public trade executions stream
* [books15](https://api.tardis.dev/v1/data-feeds/bitget-futures?from=2025-01-01\&filters=\[{%22channel%22:%22books15%22,%22symbols%22:\[%22BTCUSDT%22]}]) Futures order book snapshots at depth 15, pushed every 150ms

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Bitget Futures is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.bitget.com/v3/ws/public` from 2026-04-28. Before that date, data was captured from Bitget WebSocket API v2 at `wss://ws.bitget.com/v2/ws/public`.

{% hint style="info" %}
Bitget Futures servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Bitget Spot

Bitget historical market data details - currency pairs, data coverage and data collection specifics

Bitget historical data is available since **2024-11-08**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bitget>" %}
See Bitget historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type          | symbol  | date       |                                                                                                     |
| ------------------ | ------- | ---------- | --------------------------------------------------------------------------------------------------- |
| trades             | BTCUSDT | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitget/trades/2024/12/01/BTCUSDT.csv.gz)           |
| quotes             | BTCUSDT | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitget/quotes/2024/12/01/BTCUSDT.csv.gz)           |
| book\_snapshot\_25 | BTCUSDT | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/bitget/book_snapshot_25/2024/12/01/BTCUSDT.csv.gz) |
| book\_ticker       | BTCUSDT | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/bitget/book_ticker/2025/01/01/BTCUSDT.csv.gz)      |

### API Access and data format

Historical data format is the same as provided by real-time Bitget WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bitget",
        from_date="2026-05-01",
        to_date="2026-05-02",
        filters=[Channel(name="books", symbols=["BTCUSDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bitget real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitget',
  from: '2026-05-01',
  to: '2026-05-02',
  filters: [{ channel: 'books', symbols: ['BTCUSDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitget?from=2026-05-01&filters=[{"channel":"books","symbols":["BTCUSDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitget?from=2026-05-01&filters=[{%22channel%22:%22books%22,%22symbols%22:[%22BTCUSDT%22]}]&offset=0>" %}
Example API response for Bitget historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitget","filters":[{"channel":"books","symbols":["BTCUSDT"]}],"from":"2026-05-01","to":"2026-05-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.bitget.com/api-doc/uta/websocket/public/Order-Book-Channel>" %}
See Bitget WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v3, since 2026-04-28):**

* [publicTrade](https://api.tardis.dev/v1/data-feeds/bitget?from=2026-05-01\&filters=\[{%22channel%22:%22publicTrade%22,%22symbols%22:\[%22BTCUSDT%22]}]) Spot public trade executions stream
* [books](https://api.tardis.dev/v1/data-feeds/bitget?from=2026-05-01\&filters=\[{%22channel%22:%22books%22,%22symbols%22:\[%22BTCUSDT%22]}]) Full-depth spot order book snapshots and incremental updates stream, pushed every 50ms. During data collection, order book integrity is validated using Bitget `seq` and `pseq` fields.
* [books1](https://api.tardis.dev/v1/data-feeds/bitget?from=2026-05-01\&filters=\[{%22channel%22:%22books1%22,%22symbols%22:\[%22BTCUSDT%22]}]) Spot best bid and ask snapshots stream. Since 2026-04-28 collected through Bitget WebSocket API v3 at 1ms; before that, collected through API v2 at 10ms.

**Legacy channels (API v2, until 2026-04-28):**

* [trade](https://api.tardis.dev/v1/data-feeds/bitget?from=2025-01-01\&filters=\[{%22channel%22:%22trade%22}]) Spot public trade executions stream
* [books15](https://api.tardis.dev/v1/data-feeds/bitget?from=2025-01-01\&filters=\[{%22channel%22:%22books15%22,%22symbols%22:\[%22BTCUSDT%22]}]) Spot order book snapshots at depth 15, pushed every 200ms

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Bitget is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.bitget.com/v3/ws/public` from 2026-04-28. Before that date, data was captured from Bitget WebSocket API v2 at `wss://ws.bitget.com/v2/ws/public`.

{% hint style="info" %}
Bitget Spot servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Gate.io Futures

Gate.io Futures historical market data details - available instruments, data coverage and data collection specifics

Gate.io Futures historical data for **all its instruments** is available since **2020-07-01**.

{% embed url="<https://api.tardis.dev/v1/exchanges/gate-io-futures>" %}
See Gate.io Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol    | date       |                                                                                                                  |
| --------------------- | --------- | ---------- | ---------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC\_USDT | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/gate-io-futures/incremental_book_L2/2020/07/01/BTC_USDT.csv.gz) |
| trades                | BTC\_USDT | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/gate-io-futures/trades/2020/07/01/BTC_USDT.csv.gz)              |
| derivative\_ticker    | BTC\_USDT | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/gate-io-futures/derivative_ticker/2020/07/01/BTC_USDT.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Gate.io Futures **WebSocket v4 API** with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="gate-io-futures",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="order_book", symbols=["BTC_USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Gate.io Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'gate-io-futures',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'order_book', symbols: ['BTC_USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/gate-io-futures?from=2024-01-01&filters=[{"channel":"order_book","symbols":["BTC_USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/gate-io-futures?from=2024-01-01&filters=[{%22channel%22:%22order_book%22,%22symbols%22:[%22BTC_USDT%22]}]&offset=0>" %}
Example API response for Gate.io Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"gate-io-futures","filters":[{"channel":"order_book","symbols":["BTC_USDT"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.gate.com/docs/developers/futures/ws/en/>" %}
See Gate.io Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/gate-io-futures?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Trade executions stream
* [order\_book](https://api.tardis.dev/v1/data-feeds/gate-io-futures?from=2024-01-01\&filters=\[{%22channel%22:%22order_book%22}]) Legacy order book channel providing full depth snapshots. Subscribed with payload \[symbol, "20", "0"] (limit=20, interval=0). Delivers full order book snapshots approximately every 100ms.
* [book\_ticker](https://api.tardis.dev/v1/data-feeds/gate-io-futures?from=2024-01-01\&filters=\[{%22channel%22:%22book_ticker%22}]) — available since **2022-03-17** Best bid and ask price updates stream
* [tickers](https://api.tardis.dev/v1/data-feeds/gate-io-futures?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22}]) Contract ticker with highest, lowest, last trade price and daily volume

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Gate.io Futures is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://fx-ws.gateio.ws/v4/ws`.

{% hint style="info" %}
Gate.io Futures servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Gate.io

Gate.io historical market data details - currency pairs, data coverage and data collection specifics

Gate.io historical data for **high caps currency pairs** is available since **2020-07-01**, data for all currency pairs is available since **2022-06-09.**

{% embed url="<https://api.tardis.dev/v1/exchanges/gate-io>" %}
See Gate.io historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol    | date       |                                                                                                          |
| --------------------- | --------- | ---------- | -------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC\_USDT | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/gate-io/incremental_book_L2/2020/07/01/BTC_USDT.csv.gz) |
| trades                | BTC\_USDT | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/gate-io/trades/2020/07/01/BTC_USDT.csv.gz)              |
| quotes                | BTC\_USDT | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/gate-io/quotes/2020/07/01/BTC_USDT.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Gate.io **WebSocket v4 API** (v3 API for data before 2023-04-29) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="gate-io",
        from_date="2025-09-01",
        to_date="2025-09-02",
        filters=[Channel(name="obu", symbols=["BTC_USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Gate.io real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'gate-io',
  from: '2025-09-01',
  to: '2025-09-02',
  filters: [{ channel: 'obu', symbols: ['BTC_USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/gate-io?from=2025-09-01&filters=[{"channel":"obu","symbols":["BTC_USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/gate-io?from=2025-09-01&filters=[{%22channel%22:%22obu%22,%22symbols%22:[%22BTC_USDT%22]}]&offset=0>" %}
Example API response for Gate.io historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"gate-io","filters":[{"channel":"obu","symbols":["BTC_USDT"]}],"from":"2025-09-01","to":"2025-09-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.gate.com/docs/developers/apiv4/ws/en/>" %}
See Gate.io WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**Current channels (API v4, since 2023-04-29):**

* [trades](https://api.tardis.dev/v1/data-feeds/gate-io?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Trade executions stream. Also collected under v3 API until 2023-04-29 with different message format: v3 used method-based params array (trades.update), v4 uses channel-based result object (spot.trades)
* [order\_book\_update](https://api.tardis.dev/v1/data-feeds/gate-io?from=2024-01-01\&filters=\[{%22channel%22:%22order_book_update%22}]) — available since **2023-04-29**, until **2025-08-01** Order book incremental updates stream for local book management. Includes generated initial order book snapshots from REST API (/spot/order\_book). Snapshot messages are marked as "event":"snapshot", "channel":"spot.order\_book\_update" and "generated":true.
* [obu](https://api.tardis.dev/v1/data-feeds/gate-io?from=2025-08-01\&filters=\[{%22channel%22:%22obu%22}]) — available since **2025-08-01** Order book incremental updates with snapshots via WebSocket
* [book\_ticker](https://api.tardis.dev/v1/data-feeds/gate-io?from=2024-01-01\&filters=\[{%22channel%22:%22book_ticker%22}]) — available since **2023-04-29** Best bid and ask price and amount updates stream

**Legacy channels (API v3, until 2023-04-29):**

* [depth](https://api.tardis.dev/v1/data-feeds/gate-io?from=2020-07-01\&filters=\[{%22channel%22:%22depth%22}]) — available until **2023-04-29** Order book snapshots and deltas stream (level 30, interval 0)
* [ticker](https://api.tardis.dev/v1/data-feeds/gate-io?from=2020-07-01\&filters=\[{%22channel%22:%22ticker%22}]) — available until **2023-04-29** Market ticker with 24h stats, best bid/ask and volume

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Gate.io is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://api.gateio.ws/ws/v4`. Until 2023-04-29, data was collected via `wss://ws.gate.io/v3` (API v3).

{% hint style="info" %}
Gate.io servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# HTX Coin-M Futures

HTX Coin-M Futures historical market data details - instruments, data coverage and data collection specifics

HTX Coin-M Futures historical data for **all its instruments** is available since **2019-11-19**.

{% embed url="<https://api.tardis.dev/v1/exchanges/huobi-dm>" %}
See HTX Coin-M Futures historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Derivative ticker datasets are available since 2020-06-24.
{% endhint %}

| data type             | symbol  | date       |                                                                                                         |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC\_CQ | 2020-02-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm/incremental_book_L2/2020/02/01/BTC_CQ.csv.gz) |
| trades                | BTC\_CQ | 2020-02-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm/trades/2020/02/01/BTC_CQ.csv.gz)              |
| derivative\_ticker    | BTC\_CQ | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm/derivative_ticker/2020/07/01/BTC_CQ.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time HTX Coin-M Futures WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="huobi-dm",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="depth", symbols=["BTC_CW"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by HTX Coin-M Futures real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'huobi-dm',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'depth', symbols: ['BTC_CW'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01&filters=[{"channel":"depth","symbols":["BTC_CW"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22BTC_CW%22]}]&offset=0>" %}
Example API response for HTX Coin-M Futures historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"huobi-dm","filters":[{"channel":"depth","symbols":["BTC_CW"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.htx.com/en-us/opend/newApiPages/?id=447>" %}
See HTX Coin-M Futures WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22depth%22}]) Order book snapshots and incremental updates stream. Order book integrity is validated using sequence numbers (`version` field) — on missed message the WebSocket connection is restarted. **See also details below regarding depth channel data collection details.**
* [bbo](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22bbo%22}]) — available since **2020-06-23** Best bid and ask quote updates stream
* [liquidation\_orders](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22liquidation_orders%22}]) — available since **2020-06-23** Liquidation events stream
* [contract\_info](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22contract_info%22}]) — available since **2020-06-23** Contract definition and status updates stream
* [basis](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22basis%22}]) — available since **2020-06-23** Basis and index price updates stream
* [open\_interest](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22open_interest%22}]) — generated channel, available since **2020-06-23** Generated open interest snapshots from REST endpoint every 4-6 seconds per instrument. Messages are marked with `"ch":"market.<symbol>.open_interest"` and `"generated":true` fields and `data` field has the same format as REST API response data.
* [detail](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22detail%22}]) 24h contract statistics stream
* [elite\_account\_ratio](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22elite_account_ratio%22}]) — generated channel, available since **2020-10-29** Generated elite account long/short ratio snapshots from REST endpoint using 5min period buckets.
* [elite\_position\_ratio](https://api.tardis.dev/v1/data-feeds/huobi-dm?from=2024-01-01\&filters=\[{%22channel%22:%22elite_position_ratio%22}]) — generated channel, available since **2020-10-29** Generated elite position long/short ratio snapshots from REST endpoint using 5min period buckets.

**Up until 2020-01-31** `depth` channel was collected with `step0` aggregation level (no aggregation) which produces full order book snapshots for each book change which is very inefficient to store. To circumvent this issue we stored only initial book snapshots and then incremental updates instead - incremental updates were calculated by diffing two subsequent book snapshots and provided in the same format as other `depth` messages, except having additional **`update: true`** flag set as in snippet below. Update with amount (second value in array) set to 0 means such level should be deleted, otherwise price level should be updated with new amount value.

```javascript
{
  "ch": "market.ETC_CW.depth.step0",
  "ts": 1572652860024,
  "update": true,
  "tick": {
    "mrid": 24660973159,
    "id": 1572652860,
    "bids": [
      [
        4.869,
        1175
      ]
    ],
    "asks": [],
    "ts": 1572652860013,
    "version": 1572652860,
    "ch": "market.ETC_CW.depth.step0"
  }
}
```

**On 2020-01-31** we've switched to `depth.size_150.high_freq` channel instead when collecting data and which natively provides incremental order book updates without workarounds described above.

Unfortunately it means that when requesting data for **`depth`** channel it may return slightly different format depending for which time period request was made. It's only slightly different and boils down to the way order book update messages are marked vs order book snapshots. In `depth.size_150.high_freq` order book message has `event` field always present with value `update` or `snapshot`, for example:

```javascript
{
  "ch": "market.LTC_CW.depth.size_150.high_freq",
  "tick": {
   ...
    "event": "update",
   ...
  }
}
```

For messages before **2020-01-31** we used the `depth.step0` channel for collecting order book data, which means an order book update message has the `update` flag set to `true`; if it's a snapshot, it doesn't have that flag at all, for example:

```javascript
{
  "ch": "market.ETC_CW.depth.step0",
  "update": true,
  "tick": {
   ...
  }
}
```

All other fields are the same (tick.bids, tick.asks, etc.).

Please feel free to [contact us](https://tardis.dev/#contact) if it's confusing in any way.

We also provide a normalization layer that handles those differences transparently via our [client libs](/api/quickstart).

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for HTX Coin-M Futures is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://api.hbdm.vn/ws` (proxied via Cloudflare).

{% hint style="info" %}
HTX servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# HTX Coin-M Perpetual

HTX Coin-M Perpetual historical market data details - instruments, data coverage and data collection specifics

HTX Coin-M Perpetual historical data for **all its instruments** is available since **2020-03-28**.

{% embed url="<https://api.tardis.dev/v1/exchanges/huobi-dm-swap>" %}
See HTX Coin-M Perpetual historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Derivative ticker datasets are available since 2020-06-24.
{% endhint %}

| data type             | symbol  | date       |                                                                                                               |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD | 2020-04-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-swap/incremental_book_L2/2020/04/01/BTC-USD.csv.gz) |
| trades                | BTC-USD | 2020-04-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-swap/trades/2020/04/01/BTC-USD.csv.gz)              |
| derivative\_ticker    | BTC-USD | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-swap/derivative_ticker/2020/07/01/BTC-USD.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time HTX Coin-M Perpetual WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="huobi-dm-swap",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="depth", symbols=["BTC-USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by HTX Coin-M Perpetual real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'huobi-dm-swap',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'depth', symbols: ['BTC-USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01&filters=[{"channel":"depth","symbols":["BTC-USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22BTC-USD%22]}]&offset=0>" %}
Example API response for HTX Coin-M Perpetual historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"huobi-dm-swap","filters":[{"channel":"depth","symbols":["BTC-USD"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.htx.com/en-us/opend/newApiPages/?id=485>" %}
See HTX Coin-M Perpetual WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22depth%22}]) Order book snapshots and incremental updates stream (depth.size\_150.high\_freq). Order book integrity is validated using sequence numbers (`version` field) — on missed message the WebSocket connection is restarted.
* [bbo](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22bbo%22}]) — available since **2020-08-17** Best bid and ask quote updates stream
* [liquidation\_orders](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22liquidation_orders%22}]) — available since **2020-06-23** Liquidation events stream
* [basis](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22basis%22}]) — available since **2020-06-23** Basis and index price updates stream
* [funding\_rate](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22funding_rate%22}]) — available since **2020-06-23** Funding rate updates stream
* [open\_interest](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22open_interest%22}]) — available since **2020-06-23** — generated channel Generated open interest snapshots from REST endpoint every 4-6 seconds per instrument. Messages marked as `"ch":"market.<symbol>.open_interest"` and `"generated":true` with data field in the same format as REST API response.
* [detail](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22detail%22}]) 24h contract statistics stream
* [contract\_info](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22contract_info%22}]) — available since **2020-06-23** Contract definition and status updates stream
* [elite\_account\_ratio](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22elite_account_ratio%22}]) — available since **2020-10-29** — generated channel Generated elite account long/short ratio snapshots from REST endpoint using 5min period buckets.
* [elite\_position\_ratio](https://api.tardis.dev/v1/data-feeds/huobi-dm-swap?from=2024-01-01\&filters=\[{%22channel%22:%22elite_position_ratio%22}]) — available since **2020-10-29** — generated channel Generated elite position long/short ratio snapshots from REST endpoint using 5min period buckets.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for HTX Coin-M Perpetual is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://api.hbdm.vn/swap-ws` (proxied via Cloudflare).

{% hint style="info" %}
HTX servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# HTX USDT-M Contracts

HTX USDT-M Contracts historical market data details - instruments, data coverage and data collection specifics

HTX USDT-M Contracts historical data for **all its instruments** is available since **2020-10-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/huobi-dm-linear-swap>" %}
See HTX USDT-M Contracts historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol   | date       |                                                                                                                       |
| --------------------- | -------- | ---------- | --------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USDT | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-linear-swap/incremental_book_L2/2023/03/01/BTC-USDT.csv.gz) |
| trades                | BTC-USDT | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-linear-swap/trades/2023/03/01/BTC-USDT.csv.gz)              |
| derivative\_ticker    | BTC-USDT | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-linear-swap/derivative_ticker/2023/03/01/BTC-USDT.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time HTX USDT-M Contracts WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="huobi-dm-linear-swap",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="depth", symbols=["BTC-USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by HTX USDT-M Contracts real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'huobi-dm-linear-swap',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'depth', symbols: ['BTC-USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01&filters=[{"channel":"depth","symbols":["BTC-USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22BTC-USDT%22]}]&offset=0>" %}
Example API response for HTX USDT-M Contracts historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"huobi-dm-linear-swap","filters":[{"channel":"depth","symbols":["BTC-USDT"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.htx.com/en-us/opend/newApiPages/?id=524>" %}
See HTX USDT-M Contracts WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22depth%22}]) Order book snapshots and incremental updates stream. Order book integrity is validated using sequence numbers (`version` field) — on missed message the WebSocket connection is restarted. Uses `depth.size_150.high_freq` which natively provides incremental updates with `"event":"update"|"snapshot"` field.
* [bbo](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22bbo%22}]) Best bid and ask quote updates stream
* [liquidation\_orders](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22liquidation_orders%22}]) Liquidation events stream
* [basis](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22basis%22}]) Basis and index price updates stream
* [funding\_rate](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22funding_rate%22}]) Funding rate updates stream
* [open\_interest](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22open_interest%22}]) — generated channel Generated open interest snapshots from REST endpoint every 4-6 seconds per instrument. Messages marked as `"ch":"market.<symbol>.open_interest"` and `"generated":true` with `data` field in the same format as REST API response.
* [detail](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22detail%22}]) 24h contract statistics stream
* [contract\_info](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22contract_info%22}]) Contract definition and status updates stream
* [elite\_account\_ratio](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22elite_account_ratio%22}]) — generated channel Generated elite account long/short ratio snapshots from REST endpoint using 5min period buckets.
* [elite\_position\_ratio](https://api.tardis.dev/v1/data-feeds/huobi-dm-linear-swap?from=2024-01-01\&filters=\[{%22channel%22:%22elite_position_ratio%22}]) — generated channel Generated elite position long/short ratio snapshots from REST endpoint using 5min period buckets.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for HTX USDT-M Contracts is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://api.hbdm.vn/linear-swap-ws` (proxied via Cloudflare).

{% hint style="info" %}
HTX servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# HTX Spot

HTX Spot historical market data details - currency pairs, data coverage and data collection specifics

HTX Spot historical data for **high caps currency pairs** is available since **2019-11-19,** data for all currency pairs is available since **2022-06-09**.

{% embed url="<https://api.tardis.dev/v1/exchanges/huobi>" %}
See HTX Spot historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                       |
| --------------------- | ------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSDT | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/huobi/incremental_book_L2/2019/12/01/BTCUSDT.csv.gz) |
| trades                | BTCUSDT | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/huobi/trades/2019/12/01/BTCUSDT.csv.gz)              |
| quotes                | BTCUSDT | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/huobi/quotes/2019/12/01/BTCUSDT.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time HTX Spot WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="huobi",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="mbp", symbols=["btcusdt"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by HTX Spot real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'huobi',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'mbp', symbols: ['btcusdt'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/huobi?from=2024-01-01&filters=[{"channel":"mbp","symbols":["btcusdt"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/huobi?from=2024-01-01&filters=[{%22channel%22:%22mbp%22,%22symbols%22:[%22btcusdt%22]}]&offset=0>" %}
Example API response for HTX Spot historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"huobi","filters":[{"channel":"mbp","symbols":["btcusdt"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.htx.com/en-us/opend/newApiPages/?id=662>" %}
See HTX Spot WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/huobi?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22,%22symbols%22:\[%22btcusdt%22]}]) Trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/huobi?from=2020-12-01\&filters=\[{%22channel%22:%22depth%22,%22symbols%22:\[%22btcusdt%22]}]) — available **until 2020-12-10** Legacy full depth snapshots stream replaced by mbp. Collected with `step0` aggregation level. Publishes full order book snapshots which are stored as initial snapshot plus incremental updates (calculated by diffing subsequent snapshots, marked with `"update": true` flag).
* [mbp](https://api.tardis.dev/v1/data-feeds/huobi?from=2024-01-01\&filters=\[{%22channel%22:%22mbp%22,%22symbols%22:\[%22btcusdt%22]}]) — available since **2020-07-03** Market by price incremental updates stream. Subscribed as mbp.150 (150-level) until 2021-08-26, after that as mbp.400 (400-level). MBP feed is based on snapshots at 100ms interval via /feed endpoint. Initial order book snapshot is fetched via "req" request on the same WebSocket connection. During data collection integrity of incremental updates is validated using sequence numbers (seqNum and prevSeqNum) — on sequence gap a new snapshot is requested automatically.
* [mbp.20](https://api.tardis.dev/v1/data-feeds/huobi?from=2024-01-01\&filters=\[{%22channel%22:%22mbp.20%22,%22symbols%22:\[%22btcusdt%22]}]) — available since **2022-05-27** Market by price 20-level incremental updates stream. Tick by tick feed via /feed endpoint. Only collected for select high-cap symbols. Initial order book snapshot is fetched via "req" request.
* [bbo](https://api.tardis.dev/v1/data-feeds/huobi?from=2024-01-01\&filters=\[{%22channel%22:%22bbo%22,%22symbols%22:\[%22btcusdt%22]}]) Best bid and ask quote updates stream
* [detail](https://api.tardis.dev/v1/data-feeds/huobi?from=2024-01-01\&filters=\[{%22channel%22:%22detail%22,%22symbols%22:\[%22btcusdt%22]}]) 24h market statistics stream
* [etp](https://api.tardis.dev/v1/data-feeds/huobi?from=2022-11-01\&filters=\[{%22channel%22:%22etp%22}]) — available since **2020-08-17**, available **until 2022-11-22** Leveraged token NAV and premium updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for HTX Spot is located in GCP asia-northeast1 region (Tokyo, Japan). Before **2020-06-19** it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://api-aws.huobi.pro/ws`.

{% hint style="info" %}
HTX servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Gemini

Gemini historical market data details - instruments, data coverage and data collection specifics

Gemini exchange historical data for **all its supported instruments** is available since **2019-08-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/gemini>" %}
See Gemini historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                       |
| --------------------- | ------ | ---------- | ----------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/gemini/incremental_book_L2/2020/01/01/BTCUSD.csv.gz) |
| trades                | BTCUSD | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/gemini/trades/2020/01/01/BTCUSD.csv.gz)              |
| quotes                | BTCUSD | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/gemini/quotes/2020/01/01/BTCUSD.csv.gz)              |
| book\_ticker          | BTCUSD | 2026-08-01 | [Download sample](https://datasets.tardis.dev/v1/gemini/book_ticker/2026/08/01/BTCUSD.csv.gz)         |

### API Access and data format

Historical data uses the exchange-native Gemini WebSocket format with the addition of local timestamps. Data recorded before **2026-07-24** UTC uses Gemini **Market Data Version 2**; data recorded from **2026-07-24** UTC uses Gemini WebSocket API **v3**.

Gemini v3 raw payloads use lowercase symbols, for example `btcusd`. For backward compatibility with Gemini v2, whose raw payloads used uppercase symbols, Tardis symbol IDs and normalized messages remain uppercase. Gemini symbol filters are case-insensitive, so existing filters such as `BTCUSD` continue to match v3 messages for `btcusd`.

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

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="gemini",
        from_date="2026-08-01",
        to_date="2026-08-02",
        filters=[Channel(name="depth", symbols=["BTCUSD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Gemini real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'gemini',
  from: '2026-08-01',
  to: '2026-08-02',
  filters: [{ channel: 'depth', symbols: ['BTCUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/gemini?from=2026-08-01&filters=[{"channel":"depth","symbols":["BTCUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/gemini?from=2026-08-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22BTCUSD%22]}]&offset=0>" %}
Example API response for Gemini historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"gemini","filters":[{"channel":"depth","symbols":["BTCUSD"]}],"from":"2026-08-01","to":"2026-08-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://developer.gemini.com/websocket/streams>" %}
See Gemini WebSocket API docs for current channel formats
{% endembed %}

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

**Current channels (API v3, since 2026-07-24):**

* [trade](https://api.tardis.dev/v1/data-feeds/gemini?from=2026-08-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/gemini?from=2026-08-01\&filters=\[{%22channel%22:%22depth%22}]) Incremental level 2 order book updates captured from Gemini's `{symbol}@depth@100ms` stream. Collection uses `snapshot=-1`, so the first `depthUpdate` for each symbol and connection is a full order book snapshot; subsequent messages are incremental updates.
* [bookTicker](https://api.tardis.dev/v1/data-feeds/gemini?from=2026-08-01\&filters=\[{%22channel%22:%22bookTicker%22}]) Best bid and ask price and quantity updates

**Legacy channels (API v2, until 2026-07-24):**

Legacy v2 message formats are documented in the [archived Gemini Market Data Version 2 documentation](https://web.archive.org/web/20250130160317/https://docs.gemini.com/websocket-api/#market-data-version-2).

* [trade](https://api.tardis.dev/v1/data-feeds/gemini?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [l2\_updates](https://api.tardis.dev/v1/data-feeds/gemini?from=2024-01-01\&filters=\[{%22channel%22:%22l2_updates%22}]) Level 2 order book deltas stream
* [auction\_open](https://api.tardis.dev/v1/data-feeds/gemini?from=2024-01-01\&filters=\[{%22channel%22:%22auction_open%22}]) Auction open events stream
* [auction\_indicative](https://api.tardis.dev/v1/data-feeds/gemini?from=2024-01-01\&filters=\[{%22channel%22:%22auction_indicative%22}]) Auction indicative price and quantity updates
* [auction\_result](https://api.tardis.dev/v1/data-feeds/gemini?from=2024-01-01\&filters=\[{%22channel%22:%22auction_result%22}]) Auction result events stream

### Market data collection details

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

Real-time market data is captured via **multiple WebSocket connections** to Gemini WebSocket API v3 at `wss://ws.gemini.com?snapshot=-1`. Before **2026-07-24**, data was captured from API v2 at `wss://api.gemini.com/v2/marketdata`.

{% hint style="info" %}
Gemini exchange servers are located in AWS us-east-1 region (N. Virginia, North America).
{% endhint %}


# WOO X

WOO X historical market data details - instruments, data coverage and data collection specifics

WOO X exchange historical data for **all its instruments** is available since **2023-01-20**.

{% embed url="<https://api.tardis.dev/v1/exchanges/woo-x>" %}
See WOO X historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol          | date       |                                                                                                             |
| --------------------- | --------------- | ---------- | ----------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | SPOT\_BTC\_USDT | 2023-02-01 | [Download sample](https://datasets.tardis.dev/v1/woo-x/incremental_book_L2/2023/02/01/SPOT_BTC_USDT.csv.gz) |
| trades                | SPOT\_BTC\_USDT | 2023-02-01 | [Download sample](https://datasets.tardis.dev/v1/woo-x/trades/2023/02/01/SPOT_BTC_USDT.csv.gz)              |
| derivative\_ticker    | PERP\_BTC\_USDT | 2023-02-01 | [Download sample](https://datasets.tardis.dev/v1/woo-x/derivative_ticker/2023/02/01/PERP_BTC_USDT.csv.gz)   |

### API Access and data format

For data since **2026-06-29 22:00 UTC**, historical data format is the same as provided by real-time WOO X WebSocket **Market Data API v3** (<wss://wss.woox.io/v3/public>) with addition of local timestamps. Before that, WOO X data was captured from **Market Data API v2** (<wss://wss.woo.org/ws/stream>). Public Tardis channel names stayed the same, but native message payloads follow the WOO X API version used at the replay timestamp. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="woo-x",
        from_date="2026-07-01",
        to_date="2026-07-02",
        filters=[Channel(name="orderbook", symbols=["PERP_BTC_USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by WOO X real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'woo-x',
  from: '2026-07-01',
  to: '2026-07-02',
  filters: [{ channel: 'orderbook', symbols: ['PERP_BTC_USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01&filters=[{"channel":"orderbook","symbols":["PERP_BTC_USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01&filters=[{%22channel%22:%22orderbook%22,%22symbols%22:[%22PERP_BTC_USDT%22]}]&offset=0>" %}
Example API response for Woo X historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"woo-x","filters":[{"channel":"orderbook","symbols":["PERP_BTC_USDT"]}],"from":"2026-07-01","to":"2026-07-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://developer.woox.io/api-reference/websocket_introduction>" %}
See WOO X WebSocket v3 API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [orderbook](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22orderbook%22}]) — generated channel Initial order book snapshots from REST API used to bootstrap `orderbookupdate` stream. Since **2026-06-29 22:00 UTC**, snapshots are fetched from WOO X V3 public orderbook API with `maxLevel=50` and stored as V3-like messages with `topic:"orderbook@<symbol>@50"`, `generated:true`, `data` from the REST response and `ts` from the REST response timestamp. Before that, generated snapshots used the legacy WebSocket order book request flow. <https://developer.woox.io/api-reference/endpoint/public_data/orderbook>
* [orderbookupdate](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22orderbookupdate%22}]) Order book incremental updates. Since **2026-06-29 22:00 UTC**, collected from WOO X V3 `orderbookupdate@{symbol}@50` at `50ms`; before that, WOO X V2 provided this channel at `200ms`.
* [bbo](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22bbo%22}]) Best bid and ask updates
* [indexprice](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22indexprice%22}]) Index price updates
* [markprice](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22markprice%22}]) Mark price updates
* [openinterest](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22openinterest%22}]) Open interest updates. Since **2026-06-29 22:00 UTC**, WOO X V3 pushes every `1s` when open interest changes and forces an update every `10s` when unchanged; before that, WOO X V2 frequency was `10s`.
* [estfundingrate](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22estfundingrate%22}]) Estimated funding rate updates
* [ticker](https://api.tardis.dev/v1/data-feeds/woo-x?from=2026-07-01\&filters=\[{%22channel%22:%22ticker%22}]) 24h ticker updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for WOO X is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://wss.woox.io/v3/public`. Before **2026-06-29 22:00 UTC**, data was captured from WOO X Market Data API v2 at `wss://wss.woo.org/ws/stream`.

{% hint style="info" %}
WOO X servers are located in GCP asia-northeast1 (Tokyo, Japan).
{% endhint %}


# Upbit

Upbit historical market data details - currency pairs, data coverage and data collection specifics

Upbit exchange historical data for **all its currency pairs** is available since **2021-03-03**.

{% embed url="<https://api.tardis.dev/v1/exchanges/upbit>" %}
See Upbit historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                       |
| --------------------- | ------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | KRW-BTC | 2021-09-01 | [Download sample](https://datasets.tardis.dev/v1/upbit/incremental_book_L2/2021/09/01/KRW-BTC.csv.gz) |
| trades                | KRW-BTC | 2021-09-01 | [Download sample](https://datasets.tardis.dev/v1/upbit/trades/2021/09/01/KRW-BTC.csv.gz)              |
| quotes                | KRW-BTC | 2021-09-01 | [Download sample](https://datasets.tardis.dev/v1/upbit/quotes/2021/09/01/KRW-BTC.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Upbit WebSocket **Market Data API v1** (<wss://api.upbit.com/websocket/v1>) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="upbit",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="orderbook", symbols=["KRW-BTC"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Upbit real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'upbit',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'orderbook', symbols: ['KRW-BTC'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/upbit?from=2024-01-01&filters=[{"channel":"orderbook","symbols":["KRW-BTC"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/upbit?from=2024-01-01&filters=[{%22channel%22:%22orderbook%22,%22symbols%22:[%22KRW-BTC%22]}]&offset=0>" %}
Example API response for Upbit historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"upbit","filters":[{"channel":"orderbook","symbols":["KRW-BTC"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.upbit.com/kr/reference/websocket-guide>" %}
See Upbit WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/upbit?from=2024-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [orderbook](https://api.tardis.dev/v1/data-feeds/upbit?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook%22}]) Order book snapshots and unit updates
* [ticker](https://api.tardis.dev/v1/data-feeds/upbit?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) 24h ticker updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Upbit is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to <wss://api.upbit.com/websocket/v1>.

{% hint style="info" %}
Upbit servers are located in AWS ap-northeast-2 region (Seoul, South Korea).
{% endhint %}


# Phemex

Phemex historical market data details - available instruments, data coverage and data collection specifics

Phemex historical data for **all its derivative instruments** is available since **2020-03-17** (for spot markets since 2020-06-04).

{% embed url="<https://api.tardis.dev/v1/exchanges/phemex>" %}
See Phemex historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                       |
| --------------------- | ------ | ---------- | ----------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD | 2020-04-01 | [Download sample](https://datasets.tardis.dev/v1/phemex/incremental_book_L2/2020/04/01/BTCUSD.csv.gz) |
| trades                | BTCUSD | 2020-04-01 | [Download sample](https://datasets.tardis.dev/v1/phemex/trades/2020/04/01/BTCUSD.csv.gz)              |
| derivative\_ticker    | BTCUSD | 2020-04-01 | [Download sample](https://datasets.tardis.dev/v1/phemex/derivative_ticker/2020/04/01/BTCUSD.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Phemex WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

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

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'phemex',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'book', symbols: ['BTCUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01&filters=[{"channel":"book","symbols":["BTCUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[%22BTCUSD%22]}]&offset=0>" %}
Example API response for Phemex historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"phemex","filters":[{"channel":"book","symbols":["BTCUSD"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://github.com/phemex/phemex-api-docs>" %}
See Phemex WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public trade executions stream
* [trades\_p](https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01\&filters=\[{%22channel%22:%22trades_p%22}]) — available since **2022-11-23** Public perpetual trade executions stream
* [book](https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01\&filters=\[{%22channel%22:%22book%22}]) Order book snapshots and incremental updates
* [orderbook\_p](https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01\&filters=\[{%22channel%22:%22orderbook_p%22}]) — available since **2022-11-23** Perpetual order book snapshots and incremental updates
* [market24h](https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01\&filters=\[{%22channel%22:%22market24h%22}]) 24h market statistics updates
* [perp\_market24h\_pack\_p](https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01\&filters=\[{%22channel%22:%22perp_market24h_pack_p%22}]) — available since **2022-11-23** Perpetual 24h market statistics batch updates
* [spot\_market24h](https://api.tardis.dev/v1/data-feeds/phemex?from=2024-01-01\&filters=\[{%22channel%22:%22spot_market24h%22}]) — available since **2020-06-04** Spot 24h market statistics updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Phemex **since 2020-06-04** is located in GCP asia-northeast1 (Tokyo, Japan), before that it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://vapi.phemex.com/ws`.

{% hint style="info" %}
Phemex servers are located in AWS ap-southeast-1 region (Singapore, Asia Pacific).
{% endhint %}


# Delta Exchange

Delta Exchange historical market data details - available instruments, data coverage and data collection specifics

Delta Exchange historical data for **all its instruments** is available since **2020-03-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/delta>" %}
See Delta Exchange historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                      |
| --------------------- | ------ | ---------- | ---------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD | 2020-06-01 | [Download sample](https://datasets.tardis.dev/v1/delta/incremental_book_L2/2020/06/01/BTCUSD.csv.gz) |
| trades                | BTCUSD | 2020-06-01 | [Download sample](https://datasets.tardis.dev/v1/delta/trades/2020/06/01/BTCUSD.csv.gz)              |
| derivative\_ticker    | BTCUSD | 2020-06-01 | [Download sample](https://datasets.tardis.dev/v1/delta/derivative_ticker/2020/06/01/BTCUSD.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Delta Exchange WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="delta",
        from_date="2023-01-01",
        to_date="2023-01-02",
        filters=[Channel(name="l2_orderbook", symbols=["BTCUSDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Delta Exchange real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'delta',
  from: '2023-01-01',
  to: '2023-01-02',
  filters: [{ channel: 'l2_orderbook', symbols: ['BTCUSDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/delta?from=2023-01-01&filters=[{"channel":"l2_orderbook","symbols":["BTCUSDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/delta?from=2023-01-01&filters=[{%22channel%22:%22l2_orderbook%22,%22symbols%22:[%22BTCUSDT%22]}]&offset=0>" %}
Example API response for Delta Exchange historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"delta","filters":[{"channel":"l2_orderbook","symbols":["BTCUSDT"]}],"from":"2023-01-01","to":"2023-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.delta.exchange/#websocket-feed>" %}
See Delta Exchange WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [recent\_trade](https://api.tardis.dev/v1/data-feeds/delta?from=2020-10-01\&filters=\[{%22channel%22:%22recent_trade%22}]) — available **until 2020-10-14** Legacy trade updates stream replaced by all\_trades. After that date trades are available via `all_trades` channel, this is due to change in Delta Exchange API which discontinued `recent_trade` channel support, see <https://docs.delta.exchange/#new-socket-channels>
* [all\_trades](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22all_trades%22}]) — available since **2020-10-14** Trade executions stream
* [l2\_orderbook](https://api.tardis.dev/v1/data-feeds/delta?from=2023-04-01\&filters=\[{%22channel%22:%22l2_orderbook%22}]) Order book snapshots and incremental updates stream
* [l2\_updates](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22l2_updates%22}]) — available since **2023-04-01** Incremental level 2 order book updates stream
* [l1\_orderbook](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22l1_orderbook%22}]) — available since **2023-04-01** Top of book snapshots stream
* [mark\_price](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22mark_price%22}]) Mark price updates stream
* [funding\_rate](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22funding_rate%22}]) Funding rate updates stream
* [spot\_price](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22spot_price%22}]) Spot index price updates stream
* [product\_updates](https://api.tardis.dev/v1/data-feeds/delta?from=2020-10-01\&filters=\[{%22channel%22:%22product_updates%22}]) — available **until 2020-10-14** Instrument definition and status updates stream
* [announcements](https://api.tardis.dev/v1/data-feeds/delta?from=2020-10-01\&filters=\[{%22channel%22:%22announcements%22}]) — available **until 2020-10-14** Exchange announcements stream
* [v2/ticker](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22v2/ticker%22}]) — available since **2020-10-14** Best bid/ask, last price and 24h market stats stream
* [spot\_30mtwap\_price](https://api.tardis.dev/v1/data-feeds/delta?from=2024-01-01\&filters=\[{%22channel%22:%22spot_30mtwap_price%22}]) — available since **2023-04-01** 30 minute TWAP spot price updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Delta Exchange is located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://socket.delta.exchange`.

{% hint style="info" %}
Delta Exchange servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Blockchain.com

Blockchain.com Exchange historical market data details - instruments, data coverage and data collection specifics

Blockchain.com exchange historical data for **all its currency pairs** is available since **2023-02-23**.

{% embed url="<https://api.tardis.dev/v1/exchanges/blockchain-com>" %}
See Blockchain.com exchange historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                                |
| --------------------- | ------- | ---------- | -------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/blockchain-com/incremental_book_L2/2023/03/01/BTC-USD.csv.gz) |
| trades                | BTC-USD | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/blockchain-com/trades/2023/03/01/BTC-USD.csv.gz)              |
| quotes                | BTC-USD | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/blockchain-com/quotes/2023/03/01/BTC-USD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Blockchain.com Exchange WebSocket **Market Data API v1** (<https://exchange.blockchain.com/api/#websocket-api>) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="blockchain-com",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="l2", symbols=["BTC-USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Blockchain.com exchange real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'blockchain-com',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'l2', symbols: ['BTC-USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/blockchain-com?from=2023-03-01&filters=[{"channel":"l2","symbols":["BTC-USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/blockchain-com?from=2023-03-01&filters=[{%22channel%22:%22l2%22,%22symbols%22:[%22BTC-USD%22]}]&offset=0>" %}
Example API response for Blockchain.com exchange historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"blockchain-com","filters":[{"channel":"l2","symbols":["BTC-USD"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://exchange.blockchain.com/api/#websocket-api>" %}
See Blockchain.com exchange docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/blockchain-com?from=2025-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public trade executions stream
* [l2](https://api.tardis.dev/v1/data-feeds/blockchain-com?from=2024-01-01\&filters=\[{%22channel%22:%22l2%22}]) Level 2 order book snapshots and deltas
* [l3](https://api.tardis.dev/v1/data-feeds/blockchain-com?from=2024-01-01\&filters=\[{%22channel%22:%22l3%22}]) Level 3 order book updates stream
* [ticker](https://api.tardis.dev/v1/data-feeds/blockchain-com?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Ticker updates with best bid and ask plus 24h stats

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Blockchain.com exchange is located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.blockchain.info/mercury-gateway/v1/ws`.

{% hint style="info" %}
Blockchain.com exchange public APIs are proxied through Cloudflare.
{% endhint %}


# Bitnomial

Bitnomial historical market data details - instruments, data coverage and data collection specifics

Bitnomial exchange historical data for **all its instruments** is available since **2023-01-13**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bitnomial>" %}
See Bitnomial exchange historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                          |
| --------------------- | ------ | ---------- | -------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BUIH23 | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/bitnomial/incremental_book_L2/2023/03/01/BUIH23.csv.gz) |
| trades                | BUIH23 | 2023-02-01 | [Download sample](https://datasets.tardis.dev/v1/bitnomial/trades/2023/02/01/BUIH23.csv.gz)              |
| quotes                | BUIH23 | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/bitnomial/quotes/2023/03/01/BUIH23.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Bitnomial WebSocket **Market Data API** with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

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

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitnomial',
  from: '2023-05-01',
  to: '2023-05-02',
  filters: [{ channel: 'book', symbols: [] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitnomial?from=2023-05-01&filters=[{"channel":"book","symbols":[]}]&offset=1000'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitnomial?from=2023-05-01&filters=[{%22channel%22:%22book%22,%22symbols%22:[]}]&offset=1000>" %}
Example API response for Bitnomial exchange historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitnomial","filters":[{"channel":"book","symbols":[]}],"from":"2023-05-01","to":"2023-05-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://bitnomial.com/exchange/docs/api/websocket/overview/>" %}
See Bitnomial WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/bitnomial?from=2023-05-01\&filters=\[{%22channel%22:%22trade%22}]\&offset=1000) Trade executions stream
* [level](https://api.tardis.dev/v1/data-feeds/bitnomial?from=2023-05-01\&filters=\[{%22channel%22:%22level%22}]\&offset=1000) Price level order book updates stream
* [book](https://api.tardis.dev/v1/data-feeds/bitnomial?from=2023-05-01\&filters=\[{%22channel%22:%22book%22}]\&offset=1000) — available since **2023-04-07** Order book snapshots stream
* [block](https://api.tardis.dev/v1/data-feeds/bitnomial?from=2023-05-01\&filters=\[{%22channel%22:%22block%22}]\&offset=1000) Block trade updates stream
* [status](https://api.tardis.dev/v1/data-feeds/bitnomial?from=2023-05-01\&filters=\[{%22channel%22:%22status%22}]\&offset=1000) Market status and trading state updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Bitnomial exchange is located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://bitnomial.com/exchange/ws`.

{% hint style="info" %}
Bitnomial servers are located in AWS us-east-2 region (US East, Ohio, USA).
{% endhint %}


# bitFlyer

bitFlyer historical market data details - available instruments, data coverage and data collection specifics

bitFlyer historical data for **all its instruments** is available since **2019-08-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bitflyer>" %}
See bitFlyer historical data coverage: available symbols, channels, date ranges and incidents
{% endembed %}

{% hint style="warning" %}
Real-time market data provided by bitFlyer exchange isn't always the most reliable and clean, especially during market volatility periods (crossed order books, delayed trade data).
{% endhint %}

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

| data type             | symbol       | date       |                                                                                                             |
| --------------------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | FX\_BTC\_JPY | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/bitflyer/incremental_book_L2/2020/01/01/FX_BTC_JPY.csv.gz) |
| trades                | FX\_BTC\_JPY | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/bitflyer/trades/2020/01/01/FX_BTC_JPY.csv.gz)              |
| quotes                | FX\_BTC\_JPY | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/bitflyer/quotes/2020/01/01/FX_BTC_JPY.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time bitFlyer **lightning** **JSON-RPC 2.0 over WebSocket** API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bitflyer",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="lightning_board", symbols=["FX_BTC_JPY"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by bitFlyer real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bitflyer',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'lightning_board', symbols: ['FX_BTC_JPY'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bitflyer?from=2023-03-01&filters=[{"channel":"lightning_board","symbols":["FX_BTC_JPY"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bitflyer?from=2023-03-01&filters=[{%22channel%22:%22lightning_board%22,%22symbols%22:[%22FX_BTC_JPY%22]}]&offset=0>" %}
Example API response for bitFlyer historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bitflyer","filters":[{"channel":"lightning_board","symbols":["FX_BTC_JPY"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://lightning.bitflyer.com/docs?lang=en#json-rpc-2.0-over-websocket>" %}
See bitFlyer WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [lightning\_executions](https://api.tardis.dev/v1/data-feeds/bitflyer?from=2024-01-01\&filters=\[{%22channel%22:%22lightning_executions%22}]) Trade executions stream
* [lightning\_board\_snapshot](https://api.tardis.dev/v1/data-feeds/bitflyer?from=2024-01-01\&filters=\[{%22channel%22:%22lightning_board_snapshot%22}]) — **generated** Generated initial order book snapshot stream used for order book bootstrap
* [lightning\_board](https://api.tardis.dev/v1/data-feeds/bitflyer?from=2024-01-01\&filters=\[{%22channel%22:%22lightning_board%22}]) Order book snapshots and updates stream
* [lightning\_ticker](https://api.tardis.dev/v1/data-feeds/bitflyer?from=2024-01-01\&filters=\[{%22channel%22:%22lightning_ticker%22}]) Best bid/ask, last price and 24h stats stream. Docs state delivery frequency is throttled but do not specify interval.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for bitFlyer **since 2020-05-28** is located in GCP asia-northeast1 (Tokyo, Japan), before that it was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **single WebSocket connection** to `wss://ws.lightstream.bitflyer.com/json-rpc`.

{% hint style="info" %}
bitFlyer servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# HitBTC

HitBTC historical market data details - currency pairs, data coverage and data collection specifics

HitBTC historical data for **high caps currency pairs** is available since **2019-11-19**.

{% embed url="<https://api.tardis.dev/v1/exchanges/hitbtc>" %}
See HitBTC historical data coverage: available symbols, channels, date ranges and incidents
{% endembed %}

### Downloadable **CSV** files

Not available.

### API Access and data format

Historical data format is the same as provided by real-time HitBTC WebSocket **v2** API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="hitbtc",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="updateOrderbook", symbols=["BTCUSD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by HitBTC real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'hitbtc',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'updateOrderbook', symbols: ['BTCUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/hitbtc?from=2024-01-01&filters=[{"channel":"updateOrderbook","symbols":["BTCUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/hitbtc?from=2024-01-01&filters=[{%22channel%22:%22updateOrderbook%22,%22symbols%22:[%22BTCUSD%22]}]&offset=0>" %}
Example API response for HitBTC historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"hitbtc","filters":[{"channel":"updateOrderbook","symbols":["BTCUSD"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://api.hitbtc.com/#socket-market-data>" %}
See HitBTC WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [updateTrades](https://api.tardis.dev/v1/data-feeds/hitbtc?from=2024-01-01\&filters=\[{%22channel%22:%22updateTrades%22}]) Incremental trade updates stream
* [snapshotOrderbook](https://api.tardis.dev/v1/data-feeds/hitbtc?from=2024-01-01\&filters=\[{%22channel%22:%22snapshotOrderbook%22}]) Full order book snapshot on subscription
* [updateOrderbook](https://api.tardis.dev/v1/data-feeds/hitbtc?from=2024-01-01\&filters=\[{%22channel%22:%22updateOrderbook%22}]) Order book incremental updates stream
* [snapshotTrades](https://api.tardis.dev/v1/data-feeds/hitbtc?from=2024-01-01\&filters=\[{%22channel%22:%22snapshotTrades%22}]) Initial trade snapshot on subscription

### Market data collection details

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

Real-time market data is captured via **single WebSocket connection** to `wss://api.hitbtc.com/api/2/ws/public`.

{% hint style="info" %}
HitBTC servers are located in Equinix ld4 (Slough, Europe).
{% endhint %}


# Poloniex

Poloniex historical market data details - currency pairs, data coverage and data collection specifics

Poloniex exchange historical data for **all its currency pairs** is available since **2020-07-01.**

{% embed url="<https://api.tardis.dev/v1/exchanges/poloniex>" %}
See Poloniex historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol    | date       |                                                                                                           |
| --------------------- | --------- | ---------- | --------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | USDT\_BTC | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/poloniex/incremental_book_L2/2020/07/01/USDT_BTC.csv.gz) |
| trades                | USDT\_BTC | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/poloniex/trades/2020/07/01/USDT_BTC.csv.gz)              |
| quotes                | USDT\_BTC | 2020-07-01 | [Download sample](https://datasets.tardis.dev/v1/poloniex/quotes/2020/07/01/USDT_BTC.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Poloniex WebSocket **v2** API with addition of local timestamps and **also with addition of symbol at the end of each message** which allows us providing filtering for the data server-side. If you'd like to work with normalized data format instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="poloniex",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="book_lv2", symbols=["BTC_USDT"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Poloniex real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'poloniex',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'book_lv2', symbols: ['BTC_USDT'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/poloniex?from=2024-01-01&filters=[{"channel":"book_lv2","symbols":["BTC_USDT"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/poloniex?from=2024-01-01&filters=[{%22channel%22:%22book_lv2%22,%22symbols%22:[%22BTC_USDT%22]}]&offset=0>" %}
Example API response for Poloniex historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"poloniex","filters":[{"channel":"book_lv2","symbols":["BTC_USDT"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.poloniex.com/#websocket-api>" %}
See Poloniex WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [price\_aggregated\_book](https://api.tardis.dev/v1/data-feeds/poloniex?from=2020-07-01\&filters=\[{%22channel%22:%22price_aggregated_book%22}]) — available to **2022-08-02** Order book snapshots and deltas with embedded trades, sequence validated. During data collection integrity of order book incremental updates is being **validated** using [sequence numbers](https://docs.poloniex.com/#price-aggregated-book) provided by real-time feed - in case of detecting missed message WebSocket connection is being restarted.
* [trades](https://api.tardis.dev/v1/data-feeds/poloniex?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) — available since **2022-08-02** Public trade executions stream
* [book\_lv2](https://api.tardis.dev/v1/data-feeds/poloniex?from=2024-01-01\&filters=\[{%22channel%22:%22book_lv2%22}]) — available since **2022-08-02** Level 2 order book updates
* [ticker](https://api.tardis.dev/v1/data-feeds/poloniex?from=2024-01-01\&filters=\[{%22channel%22:%22ticker%22}]) — available since **2022-08-02** 24h ticker updates

{% hint style="info" %}
Each collected Poloniex real-time data message has appended symbol at the end of array - this allows us providing data filtering via API.
{% endhint %}

### Market data collection details

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

Real-time market data is captured via **multiple WebSocket connections** to `wss://ws.poloniex.com/ws/public`.

{% hint style="info" %}
Poloniex servers are located in AWS eu-west-1 region (Dublin, Ireland). All its public APIs are proxied through Cloudflare.
{% endhint %}


# Hyperliquid

Hyperliquid historical market data details - currency pairs, data coverage and data collection specifics

Hyperliquid historical data is available since **2024-10-29**.

{% embed url="<https://api.tardis.dev/v1/exchanges/hyperliquid>" %}
See Hyperliquid historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                         |
| --------------------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC    | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/hyperliquid/incremental_book_L2/2024/12/01/BTC.csv.gz) |
| trades                | BTC    | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/hyperliquid/trades/2024/12/01/BTC.csv.gz)              |
| derivative\_ticker    | BTC    | 2024-12-01 | [Download sample](https://datasets.tardis.dev/v1/hyperliquid/derivative_ticker/2024/12/01/BTC.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time Hyperliquid WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="hyperliquid",
        from_date="2024-11-01",
        to_date="2024-11-02",
        filters=[Channel(name="l2Book", symbols=["BTC"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Hyperliquid real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'hyperliquid',
  from: '2024-11-01',
  to: '2024-11-02',
  filters: [{ channel: 'l2Book', symbols: ['BTC'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2024-11-01&filters=[{"channel":"l2Book","symbols":["BTC"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2024-11-01&filters=[{%22channel%22:%22l2Book%22,%22symbols%22:[%22BTC%22]}]&offset=0>" %}
Example API response for Hyperliquid historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"hyperliquid","filters":[{"channel":"l2Book","symbols":["BTC"]}],"from":"2024-11-01","to":"2024-11-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions>" %}
See Hyperliquid WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2025-01-01\&filters=\[{%22channel%22:%22trades%22,%22symbols%22:\[%22BTC%22]}]) Trade executions stream
* [l2Book](https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2025-01-01\&filters=\[{%22channel%22:%22l2Book%22,%22symbols%22:\[%22BTC%22]}]) Regular 20-level order book snapshots stream, currently observed around every 5.4s.
* [fastBook](https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2026-07-01\&filters=\[{%22channel%22:%22fastBook%22,%22symbols%22:\[%22BTC%22]}]) — available since **2026-06-17** Fast 5-level raw order book snapshots stream, currently observed around every 500ms. This is Hyperliquid `l2Book` with `fast: true`, exposed as raw channel `fastBook`.

  Node.js client `tardis-dev` `18.1.0` or newer uses `fastBook` for real-time normalization and for historical data recorded from `2026-06-17` onward. The normalized `book_snapshot_5` and `book_snapshot_25` CSV datasets use the same cutoff; from that date, both are derived from the 5-level `fastBook` snapshots. Earlier historical data continues to use `l2Book`.
* [bbo](https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2025-07-01\&filters=\[{%22channel%22:%22bbo%22,%22symbols%22:\[%22BTC%22]}]) — available since **2025-06-26** Best bid and offer updates stream. Sent only if the BBO changes on a block.
* [activeAssetCtx](https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2025-01-01\&filters=\[{%22channel%22:%22activeAssetCtx%22}]) Perpetual asset context updates stream with funding, open interest and mark price
* [activeSpotAssetCtx](https://api.tardis.dev/v1/data-feeds/hyperliquid?from=2025-01-01\&filters=\[{%22channel%22:%22activeSpotAssetCtx%22}]) Spot asset context updates stream. Uses the same activeAssetCtx subscription type — returns WsActiveSpotAssetCtx for spot coins.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Hyperliquid is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://api.hyperliquid.xyz/ws`.


# Lighter

Lighter historical market data details - currency pairs, data coverage and data collection specifics

Lighter historical data is available since **2026-04-17**.

{% embed url="<https://api.tardis.dev/v1/exchanges/lighter>" %}
See Lighter historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Lighter data collection started after the April 2026 monthly sample date. Public monthly sample links will be available from the next first-day dataset.
{% endhint %}

### API Access and data format

Historical data format is the same as provided by real-time Lighter WebSocket API with addition of local timestamps. Lighter symbols in Tardis.dev APIs are numeric market ids, for example `1` for a perpetual market and `2048` for a spot market. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="lighter",
        from_date="2026-04-17",
        to_date="2026-04-18",
        filters=[Channel(name="order_book", symbols=["1"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Lighter real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'lighter',
  from: '2026-04-17',
  to: '2026-04-18',
  filters: [{ channel: 'order_book', symbols: ['1'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/lighter?from=2026-05-01&filters=[{"channel":"order_book","symbols":["1"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/lighter?from=2026-05-01&filters=[{%22channel%22:%22order_book%22,%22symbols%22:[%221%22]}]&offset=0>" %}
Example API response for Lighter historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"lighter","filters":[{"channel":"order_book","symbols":["1"]}],"from":"2026-04-17","to":"2026-04-18"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://apidocs.lighter.xyz/docs/websocket-reference>" %}
See Lighter WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [order\_book](https://api.tardis.dev/v1/data-feeds/lighter?from=2026-05-01\&filters=\[{%22channel%22:%22order_book%22,%22symbols%22:\[%221%22]}]) Order book snapshots and incremental updates stream
* [trade](https://api.tardis.dev/v1/data-feeds/lighter?from=2026-05-01\&filters=\[{%22channel%22:%22trade%22,%22symbols%22:\[%221%22]}]) Trade executions stream including liquidation trades
* [ticker](https://api.tardis.dev/v1/data-feeds/lighter?from=2026-05-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%221%22]}]) Best bid and offer updates stream
* [market\_stats](https://api.tardis.dev/v1/data-feeds/lighter?from=2026-05-01\&filters=\[{%22channel%22:%22market_stats%22}]) Perpetual market stats updates stream with mark price, index price, funding rate and open interest. Subscribed as `market_stats/all`.
* [spot\_market\_stats](https://api.tardis.dev/v1/data-feeds/lighter?from=2026-05-01\&filters=\[{%22channel%22:%22spot_market_stats%22}]) Spot market stats updates stream with index price, mid price, last trade price and 24h stats. Subscribed as `spot_market_stats/all`.

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Lighter is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://mainnet.zklighter.elliot.ai/stream`.


# Polymarket

Polymarket historical market data details - prediction market assets, data coverage and data collection specifics

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

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) or official [client libs](/api/quickstart) 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).
{% 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).
{% 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).
{% 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) 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) that provides data only in minute by minute slices.

See [tardis-machine](/tardis-machine/quickstart) 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#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#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`.


# Bullish

Bullish historical market data details - instruments, data coverage and data collection specifics

Bullish historical data for **all its instruments** is available since **2026-04-29**.

{% embed url="<https://api.tardis.dev/v1/exchanges/bullish>" %}
See Bullish historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol     | date       |                                                                                                          |
| --------------------- | ---------- | ---------- | -------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCUSD     | 2026-05-01 | [Download sample](https://datasets.tardis.dev/v1/bullish/incremental_book_L2/2026/05/01/BTCUSD.csv.gz)   |
| trades                | BTCUSD     | 2026-05-01 | [Download sample](https://datasets.tardis.dev/v1/bullish/trades/2026/05/01/BTCUSD.csv.gz)                |
| quotes                | BTCUSD     | 2026-05-01 | [Download sample](https://datasets.tardis.dev/v1/bullish/quotes/2026/05/01/BTCUSD.csv.gz)                |
| book\_ticker          | BTCUSD     | 2026-05-01 | [Download sample](https://datasets.tardis.dev/v1/bullish/book_ticker/2026/05/01/BTCUSD.csv.gz)           |
| derivative\_ticker    | PERPETUALS | 2026-05-01 | [Download sample](https://datasets.tardis.dev/v1/bullish/derivative_ticker/2026/05/01/PERPETUALS.csv.gz) |
| options\_chain        | OPTIONS    | 2026-05-01 | [Download sample](https://datasets.tardis.dev/v1/bullish/options_chain/2026/05/01/OPTIONS.csv.gz)        |

### API Access and data format

Historical data format is the same as provided by real-time Bullish WebSocket API v1 with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="bullish",
        from_date="2026-05-01",
        to_date="2026-05-02",
        filters=[Channel(name="V1TALevel2", symbols=["BTCUSD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Bullish real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'bullish',
  from: '2026-05-01',
  to: '2026-05-02',
  filters: [{ channel: 'V1TALevel2', symbols: ['BTCUSD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/bullish?from=2026-05-01&filters=[{"channel":"V1TALevel2","symbols":["BTCUSD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/bullish?from=2026-05-01&filters=%5B%7B%22channel%22%3A%22V1TALevel2%22%2C%22symbols%22%3A%5B%22BTCUSD%22%5D%7D%5D&offset=0>" %}
Example API response for Bullish historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"bullish","filters":[{"channel":"V1TALevel2","symbols":["BTCUSD"]}],"from":"2026-05-01","to":"2026-05-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.exchange.bullish.com/websocket/protocol/messages>" %}
See Bullish WebSocket API docs providing documentation for captured channel message format
{% endembed %}

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

* [V1TALevel2](https://api.tardis.dev/v1/data-feeds/bullish?from=2026-05-01\&filters=%5B%7B%22channel%22%3A%22V1TALevel2%22%2C%22symbols%22%3A%5B%22BTCUSD%22%5D%7D%5D) Level 2 order book snapshots and updates stream
* [V1TALevel1](https://api.tardis.dev/v1/data-feeds/bullish?from=2026-05-01\&filters=%5B%7B%22channel%22%3A%22V1TALevel1%22%2C%22symbols%22%3A%5B%22BTCUSD%22%5D%7D%5D) Level 1 top-of-book updates stream
* [V1TAAnonymousTradeUpdate](https://api.tardis.dev/v1/data-feeds/bullish?from=2026-05-01\&filters=%5B%7B%22channel%22%3A%22V1TAAnonymousTradeUpdate%22%2C%22symbols%22%3A%5B%22BTCUSD%22%5D%7D%5D) Public anonymous trade executions stream
* [V1TATickerResponse](https://api.tardis.dev/v1/data-feeds/bullish?from=2026-05-01\&filters=%5B%7B%22channel%22%3A%22V1TATickerResponse%22%2C%22symbols%22%3A%5B%22BTCUSD%22%5D%7D%5D) Best bid, best ask, last price, 24h stats, derivative and option fields stream
* [V1TAIndexPrice](https://api.tardis.dev/v1/data-feeds/bullish?from=2026-05-01\&filters=%5B%7B%22channel%22%3A%22V1TAIndexPrice%22%2C%22symbols%22%3A%5B%22BTC%22%5D%7D%5D) Index price updates stream

### Market data collection details

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

Real-time market data is captured via **multiple WebSocket connections** to `wss://registered.api.exchange.bullish.com`.


# dYdX v4

dYdX v4 historical market data details - available instruments, data coverage and data collection specifics

dYdX v4 historical data for **all its instruments** is available since **2024-08-23**.

{% embed url="<https://api.tardis.dev/v1/exchanges/dydx-v4>" %}
See dYdX v4 historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                         |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/dydx-v4/incremental_book_L2/2025/01/01/BTC-USD.csv.gz) |
| trades                | BTC-USD | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/dydx-v4/trades/2025/01/01/BTC-USD.csv.gz)              |
| derivative\_ticker    | BTC-USD | 2025-01-01 | [Download sample](https://datasets.tardis.dev/v1/dydx-v4/derivative_ticker/2025/01/01/BTC-USD.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time dYdX v4 WebSocket API (<wss://indexer.dydx.trade/v4/ws>) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="dydx-v4",
        from_date="2024-09-01",
        to_date="2024-09-02",
        filters=[Channel(name="v4_orderbook", symbols=["BTC-USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by dYdX v4 real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'dydx-v4',
  from: '2024-09-01',
  to: '2024-09-02',
  filters: [{ channel: 'v4_orderbook', symbols: ['BTC-USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/dydx-v4?from=2024-09-01&filters=[{"channel":"v4_orderbook","symbols":["BTC-USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/dydx-v4?from=2024-09-01&filters=[{%22channel%22:%22v4_orderbook%22,%22symbols%22:[%22BTC-USD%22]}]&offset=0>" %}
Example API response for dYdX v4 historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"dydx-v4","filters":[{"channel":"v4_orderbook","symbols":["BTC-USD"]}],"from":"2024-09-01","to":"2024-09-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.dydx.xyz/indexer-client/websockets>" %}
See dYdX v4 WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [v4\_trades](https://api.tardis.dev/v1/data-feeds/dydx-v4?from=2025-01-01\&filters=\[{%22channel%22:%22v4_trades%22}]) Trade executions stream including liquidation info
* [v4\_orderbook](https://api.tardis.dev/v1/data-feeds/dydx-v4?from=2025-01-01\&filters=\[{%22channel%22:%22v4_orderbook%22,%22symbols%22:\[%22BTC-USD%22]}]) Order book snapshots and incremental updates stream
* [v4\_markets](https://api.tardis.dev/v1/data-feeds/dydx-v4?from=2025-01-01\&filters=\[{%22channel%22:%22v4_markets%22}]) Market metadata, oracle prices, funding rate and status updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for dYdX v4 is located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://indexer.dydx.trade/v4/ws` (proxied via Cloudflare).

{% hint style="info" %}
dYdX v4 servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# FTX

FTX historical market data details - available instruments, data coverage and data collection specifics

FTX historical data for **all its instruments** is available since **2019-08-01** until **2022-11-13**.

{% embed url="<https://api.tardis.dev/v1/exchanges/ftx>" %}
See FTX historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Derivative ticker datasets are available since 2020-05-13 - date since we've started collecting that data via FTX REST API ([instrument channel](#captured-real-time-channels)).
{% endhint %}

| data type             | symbol   | date       |                                                                                                      |
| --------------------- | -------- | ---------- | ---------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-PERP | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/ftx/incremental_book_L2/2020/01/01/BTC-PERP.csv.gz) |
| trades                | BTC-PERP | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/ftx/trades/2020/01/01/BTC-PERP.csv.gz)              |
| derivative\_ticker    | BTC-PERP | 2020-06-01 | [Download sample](https://datasets.tardis.dev/v1/ftx/derivative_ticker/2020/06/01/BTC-PERP.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time FTX WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="ftx",
        from_date="2022-01-01",
        to_date="2022-01-02",
        filters=[Channel(name="orderbook", symbols=["BTC-PERP"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by FTX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'ftx',
  from: '2022-01-01',
  to: '2022-01-02',
  filters: [{ channel: 'orderbook', symbols: ['BTC-PERP'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01&filters=[{"channel":"orderbook","symbols":["BTC-PERP"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01&filters=[{%22channel%22:%22orderbook%22,%22symbols%22:[%22BTC-PERP%22]}]&offset=0>" %}
Example API response for FTX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"ftx","filters":[{"channel":"orderbook","symbols":["BTC-PERP"]}],"from":"2022-01-01","to":"2022-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://docs.ftx.com/#websocket-api>" %}
See FTX WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22trades%22}]) Trade executions stream
* [orderbook](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22orderbook%22,%22symbols%22:\[%22BTC-PERP%22]}]) Order book snapshots and updates stream (best 100 orders on each side)
* [ticker](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22BTC-PERP%22]}]) Best bid/ask and last price stream
* [instrument](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22instrument%22}]) — generated channel, available since **2020-05-13** Data fetched from REST `/futures` and `/futures/{market_name}/stats` endpoints every 3-5 seconds per derivative instrument. Messages marked with `"channel":"instrument"` and `"generated":true`; data matches REST response format.
* [markets](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22markets%22}]) — available since **2020-05-22** Market metadata and status updates stream
* [orderbookGrouped](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22orderbookGrouped%22,%22symbols%22:\[%22BTC-PERP%22]}]) — available since **2020-07-21** Grouped order book snapshots and updates stream with higher depth than orderbook channel. The `orderbook` channel provides only the best 100 orders on either side; this channel supplies grouped (collapsed) prices with `grouping` set to instrument `priceIncrement` multiplied by 10.
* [lendingRate](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22lendingRate%22}]) — generated channel Margin lending rate snapshots from authenticated REST endpoint polled about every minute
* [borrowRate](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22borrowRate%22}]) — generated channel Margin borrow rate snapshots from authenticated REST endpoint polled about every minute
* [borrowSummary](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22borrowSummary%22}]) — generated channel Margin borrow summary snapshots from authenticated REST endpoint polled about every minute
* [leveragedTokenInfo](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-01-01\&filters=\[{%22channel%22:%22leveragedTokenInfo%22}]) — generated channel Leveraged token NAV and basket snapshots from REST endpoint polled about every 10 seconds
* [busy](https://api.tardis.dev/v1/data-feeds/ftx?from=2022-06-01\&filters=\[{%22channel%22:%22busy%22}]) — generated channel Exchange busy status snapshots from REST endpoint polled at high frequency

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for FTX was located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data was captured via **multiple WebSocket connections** to `wss://ftx.com/ws`.

{% hint style="info" %}
FTX servers were located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# FTX US

FTX US historical market data details - available currency pairs, data coverage and data collection specifics

FTX US historical data for **all its currency pairs** is available since **2020-05-22** until **2022-11-13**.

{% embed url="<https://api.tardis.dev/v1/exchanges/ftx-us>" %}
See FTX US historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                        |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------ |
| incremental\_book\_L2 | BTC-USD | 2020-06-01 | [Download sample](https://datasets.tardis.dev/v1/ftx-us/incremental_book_L2/2020/06/01/BTC-USD.csv.gz) |
| trades                | BTC-USD | 2020-06-01 | [Download sample](https://datasets.tardis.dev/v1/ftx-us/trades/2020/06/01/BTC-USD.csv.gz)              |
| quotes                | BTC-USD | 2020-06-01 | [Download sample](https://datasets.tardis.dev/v1/ftx-us/quotes/2020/06/01/BTC-USD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time FTX US WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="ftx-us",
        from_date="2022-01-01",
        to_date="2022-01-02",
        filters=[Channel(name="orderbook", symbols=["BTC/USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by FTX US real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'ftx-us',
  from: '2022-01-01',
  to: '2022-01-02',
  filters: [{ channel: 'orderbook', symbols: ['BTC/USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/ftx-us?from=2022-01-01&filters=[{"channel":"orderbook","symbols":["BTC/USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/ftx-us?from=2022-01-01&filters=[{%22channel%22:%22orderbook%22,%22symbols%22:[%22BTC/USD%22]}]&offset=0>" %}
Example API response for FTX US historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"ftx-us","filters":[{"channel":"orderbook","symbols":["BTC/USD"]}],"from":"2022-01-01","to":"2022-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://web.archive.org/web/20221005111641/https://docs.ftx.us/#websocket-api>" %}
See FTX US WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/ftx-us?from=2022-01-01\&filters=\[{%22channel%22:%22trades%22,%22symbols%22:\[%22BTC/USD%22]}]) Trade executions stream
* [orderbook](https://api.tardis.dev/v1/data-feeds/ftx-us?from=2022-01-01\&filters=\[{%22channel%22:%22orderbook%22,%22symbols%22:\[%22BTC/USD%22]}]) Order book snapshots and updates stream (best 100 orders on each side)
* [ticker](https://api.tardis.dev/v1/data-feeds/ftx-us?from=2022-01-01\&filters=\[{%22channel%22:%22ticker%22,%22symbols%22:\[%22BTC/USD%22]}]) Best bid/ask and last price stream
* [markets](https://api.tardis.dev/v1/data-feeds/ftx-us?from=2021-01-01\&filters=\[{%22channel%22:%22markets%22}]) — available since **2020-06-17** Market metadata and status updates stream. Sends full snapshot on subscription and once per minute, plus update messages on market listings/delistings/changes
* [orderbookGrouped](https://api.tardis.dev/v1/data-feeds/ftx-us?from=2022-01-01\&filters=\[{%22channel%22:%22orderbookGrouped%22,%22symbols%22:\[%22BTC/USD%22]}]) — available since **2020-07-20** Grouped order book snapshots and updates stream with higher depth than orderbook channel

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for FTX US was located in GCP europe-west2 region (London, UK).

Real-time market data was captured via **multiple WebSocket connections** to `wss://ftx.us/ws`.

{% hint style="info" %}
FTX US servers were located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# OKCoin

OKCoin historical market data details - available instruments, data coverage and data collection specifics

OKCoin historical data for **all its currency pairs** is available since **2019-11-19** until **2025-10-01**.

{% embed url="<https://api.tardis.dev/v1/exchanges/okcoin>" %}
See OKCoin historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol  | date       |                                                                                                        |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------ |
| incremental\_book\_L2 | BTC-USD | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okcoin/incremental_book_L2/2020/01/01/BTC-USD.csv.gz) |
| trades                | BTC-USD | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okcoin/trades/2020/01/01/BTC-USD.csv.gz)              |
| quotes                | BTC-USD | 2020-01-01 | [Download sample](https://datasets.tardis.dev/v1/okcoin/quotes/2020/01/01/BTC-USD.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time OKCoin WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="okcoin",
        from_date="2024-01-01",
        to_date="2024-01-02",
        filters=[Channel(name="books", symbols=["BTC-USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by OKCoin real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'okcoin',
  from: '2024-01-01',
  to: '2024-01-02',
  filters: [{ channel: 'books', symbols: ['BTC-USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/okcoin?from=2024-01-01&filters=[{"channel":"books","symbols":["BTC-USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/okcoin?from=2024-01-01&filters=[{%22channel%22:%22books%22,%22symbols%22:[%22BTC-USD%22]}]&offset=0>" %}
Example API response for OKCoin historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"okcoin","filters":[{"channel":"books","symbols":["BTC-USD"]}],"from":"2024-01-01","to":"2024-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://www.okcoin.com/docs-v5/en/>" %}
See OKCoin WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

**v5 API channels (since 2023-04-27):**

* [trades](https://api.tardis.dev/v1/data-feeds/okcoin?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22,%22symbols%22:\[%22BTC-USD%22]}]) — available since **2023-04-27** Public spot trade executions stream
* [books](https://api.tardis.dev/v1/data-feeds/okcoin?from=2024-01-01\&filters=\[{%22channel%22:%22books%22,%22symbols%22:\[%22BTC-USD%22]}]) — available since **2023-04-27** Incremental spot order book depth updates
* [bbo-tbt](https://api.tardis.dev/v1/data-feeds/okcoin?from=2024-01-01\&filters=\[{%22channel%22:%22bbo-tbt%22,%22symbols%22:\[%22BTC-USD%22]}]) — available since **2023-04-27** Tick-by-tick best bid and offer updates
* [tickers](https://api.tardis.dev/v1/data-feeds/okcoin?from=2024-01-01\&filters=\[{%22channel%22:%22tickers%22,%22symbols%22:\[%22BTC-USD%22]}]) — available since **2023-04-27** 24h spot ticker updates

**v3 API channels (until 2023-04-27):**

* [spot/trade](https://api.tardis.dev/v1/data-feeds/okcoin?from=2020-01-01\&filters=\[{%22channel%22:%22spot/trade%22,%22symbols%22:\[]}]) — available until **2023-04-27** Public spot trade executions stream
* [spot/depth](https://api.tardis.dev/v1/data-feeds/okcoin?from=2020-01-01\&filters=\[{%22channel%22:%22spot/depth%22,%22symbols%22:\[]}]) — available until **2020-02-18** Incremental spot order book updates stream (legacy depth channel)
* [spot/depth\_l2\_tbt](https://api.tardis.dev/v1/data-feeds/okcoin?from=2020-03-01\&filters=\[{%22channel%22:%22spot/depth_l2_tbt%22,%22symbols%22:\[]}]) — available since **2020-02-12**, until **2023-04-27** Tick-by-tick L2 spot order book updates with sequencing
* [spot/ticker](https://api.tardis.dev/v1/data-feeds/okcoin?from=2020-01-01\&filters=\[{%22channel%22:%22spot/ticker%22,%22symbols%22:\[]}]) — available until **2023-04-27** Spot ticker updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for OKCoin **since 2020-05-15** was located in GCP asia-northeast1 (Tokyo, Japan), before that it was located in GCP europe-west2 region (London, UK).

Real-time market data was captured via **multiple WebSocket connections** to `wss://real.okcoin.com:8443/ws/v5/public`.

{% hint style="info" %}
OKCoin servers are located in Alibaba Cloud cn-hongkong region (Hong Kong, China).
{% endhint %}


# AscendEX (BitMax)

AscendEX historical market data details - available instruments, data coverage and data collection specifics

AscendEX historical data for **all its instruments** is available since **2021-03-28** until **2026-07-07**.

{% embed url="<https://api.tardis.dev/v1/exchanges/ascendex>" %}
See AscendEX historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol   | date       |                                                                                                           |
| --------------------- | -------- | ---------- | --------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-PERP | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/ascendex/incremental_book_L2/2023/03/01/BTC-PERP.csv.gz) |
| trades                | BTC-PERP | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/ascendex/trades/2023/03/01/BTC-PERP.csv.gz)              |
| derivative\_ticker    | BTC-PERP | 2023-03-01 | [Download sample](https://datasets.tardis.dev/v1/ascendex/derivative_ticker/2023/03/01/BTC-PERP.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time AscendEX Exchange WebSocket API v2 (<https://ascendex.github.io/ascendex-futures-pro-api-v2/#websocket>) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="ascendex",
        from_date="2023-03-01",
        to_date="2023-03-02",
        filters=[Channel(name="depth-realtime", symbols=["BTC-PERP"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Ascendex real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'ascendex',
  from: '2023-03-01',
  to: '2023-03-02',
  filters: [{ channel: 'depth-realtime', symbols: ['BTC-PERP'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/ascendex?from=2023-03-01&filters=[{"channel":"depth-realtime","symbols":["BTC-PERP"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/ascendex?from=2023-03-01&filters=[{%22channel%22:%22depth-realtime%22,%22symbols%22:[%22BTC-PERP%22]}]&offset=0>" %}
Example API response for Ascendex exchange historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"ascendex","filters":[{"channel":"depth-realtime","symbols":["BTC-PERP"]}],"from":"2023-03-01","to":"2023-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://ascendex.github.io/ascendex-futures-pro-api-v2/#websocket>" %}
See AscendEX Exchange WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/ascendex?from=2024-01-01\&filters=\[{%22channel%22:%22trades%22}]) Public trade executions stream
* [depth-realtime](https://api.tardis.dev/v1/data-feeds/ascendex?from=2024-01-01\&filters=\[{%22channel%22:%22depth-realtime%22}]) Order book incremental updates stream
* [depth-snapshot-realtime](https://api.tardis.dev/v1/data-feeds/ascendex?from=2024-01-01\&filters=\[{%22channel%22:%22depth-snapshot-realtime%22}]) Order book snapshots followed by real-time deltas
* [bbo](https://api.tardis.dev/v1/data-feeds/ascendex?from=2024-01-01\&filters=\[{%22channel%22:%22bbo%22}]) Best bid and ask updates stream
* [futures-pricing-data](https://api.tardis.dev/v1/data-feeds/ascendex?from=2024-01-01\&filters=\[{%22channel%22:%22futures-pricing-data%22}]) Futures mark price, index price and funding related updates

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for AscendEX is located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **multiple WebSocket connections** to `wss://ascendex.com/api/pro/v2/stream`.

{% hint style="info" %}
AscendEX servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# CoinFLEX

CoinFLEX 2.0 historical market data details - instruments, data coverage and data collection specifics

CoinFLEX historical data for **all its instruments** is available since **2020-07-14** until **2023-04-07**.

{% embed url="<https://api.tardis.dev/v1/exchanges/coinflex>" %}
See CoinFLEX historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol           | date       |                                                                                                                   |
| --------------------- | ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD-SWAP-LIN | 2020-08-01 | [Download sample](https://datasets.tardis.dev/v1/coinflex/incremental_book_L2/2020/08/01/BTC-USD-SWAP-LIN.csv.gz) |
| trades                | BTC-USD-SWAP-LIN | 2020-08-01 | [Download sample](https://datasets.tardis.dev/v1/coinflex/trades/2020/08/01/BTC-USD-SWAP-LIN.csv.gz)              |
| derivative\_ticker    | BTC-USD-SWAP-LIN | 2020-08-01 | [Download sample](https://datasets.tardis.dev/v1/coinflex/derivative_ticker/2020/08/01/BTC-USD-SWAP-LIN.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time CoinFLEX **WebSocket v2 API** with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="coinflex",
        from_date="2020-08-01",
        to_date="2020-08-02",
        filters=[Channel(name="futures/depth", symbols=["BTC-USD-SWAP-LIN"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by CoinFLEX 2.0 real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'coinflex',
  from: '2020-08-01',
  to: '2020-08-02',
  filters: [{ channel: 'futures/depth', symbols: ['BTC-USD-SWAP-LIN'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/coinflex?from=2020-08-01&filters=[{"channel":"futures/depth","symbols":["BTC-USD-SWAP-LIN"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/coinflex?from=2020-08-01&filters=[{%22channel%22:%22futures/depth%22,%22symbols%22:[%22BTC-USD-SWAP-LIN%22]}]&offset=0>" %}
Example API response for CoinFLEX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"coinflex","filters":[{"channel":"futures/depth","symbols":["BTC-USD-SWAP-LIN"]}],"from":"2020-08-01","to":"2020-08-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://web.archive.org/web/20220301000000/https://docs.coinflex.com/v2/#websocket-api>" %}
See CoinFLEX 2.0 WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/coinflex?from=2022-01-01\&filters=\[{%22channel%22:%22trade%22}]) — available until **2023-02-11** Trade executions stream
* [futures/depth](https://api.tardis.dev/v1/data-feeds/coinflex?from=2022-01-01\&filters=\[{%22channel%22:%22futures/depth%22}]) Order book snapshots and updates stream
* [ticker](https://api.tardis.dev/v1/data-feeds/coinflex?from=2022-01-01\&filters=\[{%22channel%22:%22ticker%22}]) Best bid/ask, last price and 24h stats stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for CoinFLEX 2.0 was located in GCP asia-northeast1 (Tokyo, Japan).

Real-time market data is captured via **single WebSocket connection** to `wss://v2api.coinflex.com/v2/websocket`.

{% hint style="info" %}
CoinFLEX 2.0 servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Binance Jersey

Binance Jersey historical market data details - currency pairs, data coverage and data collection specifics

Binance Jersey exchange historical data for **all its currency pairs** is available since **2019-10-30** until **2020-11-10.**

{% embed url="<https://api.tardis.dev/v1/exchanges/binance-jersey>" %}
See Binance Jersey historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol | date       |                                                                                                               |
| --------------------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTCEUR | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance-jersey/incremental_book_L2/2019/12/01/BTCEUR.csv.gz) |
| trades                | BTCEUR | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance-jersey/trades/2019/12/01/BTCEUR.csv.gz)              |
| quotes                | BTCEUR | 2019-12-01 | [Download sample](https://datasets.tardis.dev/v1/binance-jersey/quotes/2019/12/01/BTCEUR.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Binance Jersey WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="binance-jersey",
        from_date="2020-01-01",
        to_date="2020-01-02",
        filters=[Channel(name="depth", symbols=["btceur"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Binance Jersey real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'binance-jersey',
  from: '2020-01-01',
  to: '2020-01-02',
  filters: [{ channel: 'depth', symbols: ['btceur'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-01-01&filters=[{"channel":"depth","symbols":["btceur"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-01-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22btceur%22]}]&offset=0>" %}
Example API response for Binance Jersey historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance-jersey","filters":[{"channel":"depth","symbols":["btceur"]}],"from":"2020-01-01","to":"2020-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://github.com/binance-jersey/binance-official-api-docs>" %}
See Binance Jersey WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-03-01\&filters=\[{%22channel%22:%22trade%22}]) — available since **2020-01-30**, available until **2020-11-03** Public spot trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-06-01\&filters=\[{%22channel%22:%22depth%22}]) Incremental order book updates stream subscribed as @depth\@100ms
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-06-01\&filters=\[{%22channel%22:%22depthSnapshot%22}]) — *generated* Generated full order book snapshots stream

  Binance Jersey real-time WebSocket API did not provide initial order book snapshots. To overcome this issue we fetched initial order book snapshots from REST API and stored them together with the rest of the WebSocket messages (top 1000 levels). Snapshot messages were marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true`.

  During data collection, integrity of incremental order book updates was validated using sequence numbers from the real-time feed (`U` and `u` fields). If a missed message was detected, the WebSocket connection was restarted. Initial book snapshots fetched from REST API were also validated for overlap with received `depth` messages.
* [aggTrade](https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-03-01\&filters=\[{%22channel%22:%22aggTrade%22}]) — available since **2020-01-30**, available until **2020-11-03** Aggregated spot trade executions stream
* [ticker](https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-06-01\&filters=\[{%22channel%22:%22ticker%22}]) 24h spot ticker updates stream
* [bookTicker](https://api.tardis.dev/v1/data-feeds/binance-jersey?from=2020-06-01\&filters=\[{%22channel%22:%22bookTicker%22}]) Best bid and best ask updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Binance Jersey was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **single WebSocket connection** to `wss://stream.binance.je:9443`.

{% hint style="info" %}
Binance Jersey servers were located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Binance DEX

Binance DEX  historical market data details - currency pairs, data coverage and data collection specifics

Binance DEX exchange historical data for **all its currency pairs** is available since **2019-06-04** until **2022-10-04**.

{% embed url="<https://api.tardis.dev/v1/exchanges/binance-dex>" %}
See Binance DEX historical data coverage: available symbols, channels, date ranges and incidents
{% endembed %}

### Downloadable **CSV** files

Not available.

### API Access and data format

Historical data format is the same as provided by real-time Binance DEX WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="binance-dex",
        from_date="2020-01-01",
        to_date="2020-01-02",
        filters=[Channel(name="marketDiff", symbols=["BTCB-1DE_BUSD-BD1"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Binance DEX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'binance-dex',
  from: '2020-01-01',
  to: '2020-01-02',
  filters: [{ channel: 'marketDiff', symbols: ['BTCB-1DE_BUSD-BD1'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/binance-dex?from=2020-01-01&filters=[{"channel":"marketDiff","symbols":["BTCB-1DE_BUSD-BD1"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/binance-dex?from=2020-01-01&filters=[{%22channel%22:%22marketDiff%22,%22symbols%22:[%22BTCB-1DE_BUSD-BD1%22]}]&offset=0>" %}
Example API response for Binance DEX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"binance-dex","filters":[{"channel":"marketDiff","symbols":["BTCB-1DE_BUSD-BD1"]}],"from":"2020-01-01","to":"2020-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://github.com/thaaddeus/binance-dex-docs-site/blob/master/docs/api-reference/dex-api/ws-streams.md>" %}
See Binance DEX WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trades](https://api.tardis.dev/v1/data-feeds/binance-dex?from=2020-06-01\&filters=\[{%22channel%22:%22trades%22}]\&offset=1) Public spot trade executions stream
* [marketDiff](https://api.tardis.dev/v1/data-feeds/binance-dex?from=2020-06-01\&filters=\[{%22channel%22:%22marketDiff%22}]) Incremental order book updates stream
* [depthSnapshot](https://api.tardis.dev/v1/data-feeds/binance-dex?from=2020-06-01\&filters=\[{%22channel%22:%22depthSnapshot%22}]) — *generated* Generated full order book snapshots stream

  Binance DEX WebSocket API does not provide initial order book snapshots. To overcome this issue we fetch initial order book snapshots from REST API and store them together with the rest of the WebSocket messages (top 1000 levels). Snapshot messages are marked with `"stream":"<symbol>@depthSnapshot"` and `"generated":true`.

  During data collection, order book integrity is validated using sequence numbers from the real-time feed. If a missed message is detected, the WebSocket connection is restarted. Initial book snapshots fetched from REST API are also validated for overlap with received depth messages.
* [ticker](https://api.tardis.dev/v1/data-feeds/binance-dex?from=2019-07-01\&filters=\[{%22channel%22:%22ticker%22}]) 24h ticker updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Binance DEX was located in GCP europe-west2 region (London, UK).

Real-time market data is captured via **multiple WebSocket connections** to `wss://dex-european.binance.org/api/ws`.


# HTX Options

HTX Options (formerly Huobi Options) historical market data details - available instruments, data coverage and data collection specifics

HTX Options historical data for **all its instruments** is available since **2021-02-01** until **2021-06-26**.

{% embed url="<https://api.tardis.dev/v1/exchanges/huobi-dm-options>" %}
See HTX Options historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol                  | date       |                                                                                                                                  |
| --------------------- | ----------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USDT-210326-C-32000 | 2021-03-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-options/incremental_book_L2/2021/03/01/BTC-USDT-210326-C-32000.csv.gz) |
| trades                | OPTIONS                 | 2021-03-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-options/trades/2021/03/01/OPTIONS.csv.gz)                              |
| options\_chain        | OPTIONS                 | 2021-03-01 | [Download sample](https://datasets.tardis.dev/v1/huobi-dm-options/options_chain/2021/03/01/OPTIONS.csv.gz)                       |

### API Access and data format

Historical data format is the same as provided by real-time HTX Options WebSocket API with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="huobi-dm-options",
        from_date="2021-03-01",
        to_date="2021-03-02",
        filters=[Channel(name="depth", symbols=["BTC-USDT-210326-C-32000"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by HTX Options real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'huobi-dm-options',
  from: '2021-03-01',
  to: '2021-03-02',
  filters: [{ channel: 'depth', symbols: ['BTC-USDT-210326-C-32000'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01&filters=[{"channel":"depth","symbols":["BTC-USDT-210326-C-32000"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01&filters=[{%22channel%22:%22depth%22,%22symbols%22:[%22BTC-USDT-210326-C-32000%22]}]&offset=0>" %}
Example API response for HTX Options historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"huobi-dm-options","filters":[{"channel":"depth","symbols":["BTC-USDT-210326-C-32000"]}],"from":"2021-03-01","to":"2021-03-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://web.archive.org/web/20210625000000/https://huobiapi.github.io/docs/option/v1/en/>" %}
See HTX Options WebSocket API docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-04-01\&filters=\[{%22channel%22:%22trade%22}]) Trade executions stream
* [depth](https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01\&filters=\[{%22channel%22:%22depth%22}]) Order book snapshots and incremental updates stream (30ms frequency). Order book integrity is validated using sequence numbers (version field) -- on missed message the WebSocket connection is restarted. Uses `depth.size_150.high_freq` which natively provides incremental updates with `"event":"update"|"snapshot"` field.
* [open\_interest](https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01\&filters=\[{%22channel%22:%22open_interest%22}]) -- generated channel Generated open interest snapshots from REST endpoint every 4-6 seconds per instrument
* [option\_market\_index](https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01\&filters=\[{%22channel%22:%22option_market_index%22}]) -- generated channel Generated option market index snapshots from REST endpoint
* [option\_index](https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01\&filters=\[{%22channel%22:%22option_index%22}]) -- generated channel Generated option underlying index snapshots from REST endpoint
* [detail](https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01\&filters=\[{%22channel%22:%22detail%22}]) 24h option statistics stream (500ms frequency)
* [bbo](https://api.tardis.dev/v1/data-feeds/huobi-dm-options?from=2021-03-01\&filters=\[{%22channel%22:%22bbo%22}]) Best bid and ask quote updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for HTX Options was located in GCP asia-northeast1 region (Tokyo, Japan).

Real-time market data was captured via **multiple WebSocket connections** to `wss://api.hbdm.com/option-ws` (proxied via Cloudflare).

{% hint style="info" %}
HTX Options servers were located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# dYdX

dYdX historical market data details - currency pairs, data coverage and data collection specifics

dYdX exchange historical data for **all its instruments** is available since **2021-04-06** until **2024-10-30**.

{% embed url="<https://api.tardis.dev/v1/exchanges/dydx>" %}
See dYdX historical data coverage: available symbols, channels, date ranges and incidents
{% endembed %}

{% hint style="info" %}

* Currently there's a problem with occasional order book crossed state (best bid>=best ask) when reconstructing the book from dYdX WS updates, it's something [dYdX team is aware](https://discord.com/channels/724804754382782534/724806126859976754) of and working on a fix.
* `nextFundingRate` published via `v3_markets` channel does not exactly match the funding rates that dYdX ends up paying for open positions, it's also something [dYdX team is aware](https://discord.com/channels/724804754382782534/724806126859976754) of and working on a fix.
  {% endhint %}

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

| data type             | symbol  | date       |                                                                                                      |
| --------------------- | ------- | ---------- | ---------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | BTC-USD | 2021-09-01 | [Download sample](https://datasets.tardis.dev/v1/dydx/incremental_book_L2/2021/09/01/BTC-USD.csv.gz) |
| trades                | BTC-USD | 2021-09-01 | [Download sample](https://datasets.tardis.dev/v1/dydx/trades/2021/09/01/BTC-USD.csv.gz)              |
| derivative\_ticker    | BTC-USD | 2021-09-01 | [Download sample](https://datasets.tardis.dev/v1/dydx/derivative_ticker/2021/09/01/BTC-USD.csv.gz)   |

### API Access and data format

Historical data format is the same as provided by real-time dYdX WebSocket **Market Data API v3** (<wss://api.dydx.exchange/v3/ws>) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="dydx",
        from_date="2022-01-01",
        to_date="2022-01-02",
        filters=[Channel(name="v3_orderbook", symbols=["BTC-USD"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by dYdX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'dydx',
  from: '2022-01-01',
  to: '2022-01-02',
  filters: [{ channel: 'v3_orderbook', symbols: ['BTC-USD'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/dydx?from=2022-01-01&filters=[{"channel":"v3_orderbook","symbols":["BTC-USD"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/dydx?from=2022-01-01&filters=[{%22channel%22:%22v3_orderbook%22,%22symbols%22:[%22BTC-USD%22]}]&offset=0>" %}
Example API response for dYdX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"dydx","filters":[{"channel":"v3_orderbook","symbols":["BTC-USD"]}],"from":"2022-01-01","to":"2022-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://dydxprotocol.github.io/v3-teacher/#v3-websocket-api>" %}
See dYdX WebSocket v3 API docs providing documentation for each captured channel's format
{% endembed %}

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

* [v3\_trades](https://api.tardis.dev/v1/data-feeds/dydx?from=2024-01-01\&filters=\[{%22channel%22:%22v3_trades%22}]) Trade executions stream
* [v3\_orderbook](https://api.tardis.dev/v1/data-feeds/dydx?from=2024-01-01\&filters=\[{%22channel%22:%22v3_orderbook%22}]) Order book snapshots and incremental updates stream
* [v3\_markets](https://api.tardis.dev/v1/data-feeds/dydx?from=2024-01-01\&filters=\[{%22channel%22:%22v3_markets%22}]) Market metadata, funding rate and index price updates stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for dYdX was located in GCP europe-west2 region (London, UK).

Real-time market data was captured via **multiple WebSocket connections** to `wss://api.dydx.exchange/v3/ws`.

{% hint style="info" %}
dYdX servers are located in AWS ap-northeast-1 region (Tokyo, Japan).
{% endhint %}


# Serum DEX

Serum DEX historical market data details - available instruments, data coverage and data collection specifics

Serum DEX historical data for **all its instruments** is available since **2021-06-23** until **2022-11-13**.

{% embed url="<https://api.tardis.dev/v1/exchanges/serum>" %}
See Serum DEX historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol   | date       |                                                                                                          |
| --------------------- | -------- | ---------- | -------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | SOL/USDC | 2022-01-01 | [Download sample](https://datasets.tardis.dev/v1/serum/incremental_book_L2/2022/01/01/SOL%2FUSDC.csv.gz) |
| trades                | SOL/USDC | 2022-01-01 | [Download sample](https://datasets.tardis.dev/v1/serum/trades/2022/01/01/SOL%2FUSDC.csv.gz)              |
| quotes                | SOL/USDC | 2022-01-01 | [Download sample](https://datasets.tardis.dev/v1/serum/quotes/2022/01/01/SOL%2FUSDC.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Serum DEX WebSocket API (via [serum-vial](https://github.com/tardis-dev/serum-vial)) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="serum",
        from_date="2022-01-01",
        to_date="2022-01-02",
        filters=[Channel(name="l2snapshot", symbols=["BTC/USDC"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Serum DEX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'serum',
  from: '2022-01-01',
  to: '2022-01-02',
  filters: [{ channel: 'l2snapshot', symbols: ['BTC/USDC'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01&filters=[{"channel":"l2snapshot","symbols":["BTC/USDC"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01&filters=[{%22channel%22:%22l2snapshot%22,%22symbols%22:[%22BTC/USDC%22]}]&offset=0>" %}
Example API response for Serum DEX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"serum","filters":[{"channel":"l2snapshot","symbols":["BTC/USDC"]}],"from":"2022-01-01","to":"2022-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://github.com/tardis-dev/serum-vial>" %}
See serum-vial docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [l2snapshot](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22l2snapshot%22}]) Level 2 order book snapshots
* [l2update](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22l2update%22}]) Level 2 order book incremental updates
* [quote](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22quote%22}]) Best bid and ask quote updates
* [recent\_trades](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22recent_trades%22}]) Recent trades snapshot stream
* [l3snapshot](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22l3snapshot%22}]) Level 3 order book snapshots
* [open](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22open%22}]) Order open events
* [fill](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22fill%22}]) Order fill events
* [change](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22change%22}]) Order change events
* [done](https://api.tardis.dev/v1/data-feeds/serum?from=2022-01-01\&filters=\[{%22channel%22:%22done%22}]) Order done events

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Serum DEX was located in GCP europe-west2 region (London, UK).

Real-time market data was captured via **WebSocket connection** to `wss://api.serum-vial.dev/v1/ws`.

{% hint style="info" %}
Serum DEX was a Solana-based decentralized exchange with no centralized server infrastructure.
{% endhint %}


# Mango Markets DEX

Mango Markets DEX historical market data details - available instruments, data coverage and data collection specifics

Mango Markets DEX historical data for **all its instruments** is available since **2022-01-19** until **2022-10-14**.

{% embed url="<https://api.tardis.dev/v1/exchanges/mango>" %}
See Mango Markets DEX historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

| data type             | symbol    | date       |                                                                                                         |
| --------------------- | --------- | ---------- | ------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | MNGO-PERP | 2022-03-01 | [Download sample](https://datasets.tardis.dev/v1/mango/incremental_book_L2/2022/03/01/MNGO-PERP.csv.gz) |
| trades                | MNGO-PERP | 2022-03-01 | [Download sample](https://datasets.tardis.dev/v1/mango/trades/2022/03/01/MNGO-PERP.csv.gz)              |
| quotes                | MNGO-PERP | 2022-03-01 | [Download sample](https://datasets.tardis.dev/v1/mango/quotes/2022/03/01/MNGO-PERP.csv.gz)              |

### API Access and data format

Historical data format is the same as provided by real-time Mango Markets DEX WebSocket API (via [mango-bowl](https://github.com/tardis-dev/mango-bowl)) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="mango",
        from_date="2022-02-01",
        to_date="2022-02-02",
        filters=[Channel(name="l2snapshot", symbols=["BTC-PERP"])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Mango Markets DEX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'mango',
  from: '2022-02-01',
  to: '2022-02-02',
  filters: [{ channel: 'l2snapshot', symbols: ['BTC-PERP'] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/mango?from=2022-02-01&filters=[{"channel":"l2snapshot","symbols":["BTC-PERP"]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/mango?from=2022-02-01&filters=[{%22channel%22:%22l2snapshot%22,%22symbols%22:[%22BTC-PERP%22]}]&offset=0>" %}
Example API response for Mango Markets DEX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"mango","filters":[{"channel":"l2snapshot","symbols":["BTC-PERP"]}],"from":"2022-02-01","to":"2022-02-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://github.com/tardis-dev/mango-bowl>" %}
See mango-bowl docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22trade%22}]) Trade executions stream
* [l2snapshot](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22l2snapshot%22}]) Level 2 order book snapshots stream
* [l2update](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22l2update%22}]) Level 2 order book incremental updates stream
* [quote](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22quote%22}]) Best bid and ask quote updates stream
* [recent\_trades](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22recent_trades%22}]) Recent trades snapshot stream
* [l3snapshot](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22l3snapshot%22}]) Level 3 order book snapshots stream
* [open](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22open%22}]) Order open events stream
* [fill](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22fill%22}]) Order fill events stream
* [change](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22change%22}]) Order change events stream
* [done](https://api.tardis.dev/v1/data-feeds/mango?from=2022-03-01\&filters=\[{%22channel%22:%22done%22}]) Order done events stream

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Mango Markets DEX was located in GCP europe-west2 region (London, UK).

Real-time market data was captured via **WebSocket connection** to `ws://static.93.79.119.168.clients.your-server.de/v1/ws`.

{% hint style="info" %}
Mango Markets DEX was a Solana-based decentralized exchange with no centralized server infrastructure.
{% endhint %}


# Star Atlas DEX

Star Atlas DEX historical market data details - available instruments, data coverage and data collection specifics

Star Atlas DEX historical data for **all its instruments** is available since **2021-10-09** until **2022-09-05**.

{% embed url="<https://api.tardis.dev/v1/exchanges/star-atlas>" %}
See Star Atlas DEX historical data coverage: available symbols, channels, date ranges and incidents
{% 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).

{% hint style="info" %}
Star Atlas DEX symbols are Solana market addresses (e.g., `AYXTVTTPFHYMN3JRYX5XBRJWPK2M9445MBN2ILYRD6NQ`). See the [exchange metadata endpoint](https://api.tardis.dev/v1/exchanges/star-atlas) for full symbol list.
{% endhint %}

| data type             | symbol      | date       |                                                                                                                                                 |
| --------------------- | ----------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| incremental\_book\_L2 | AYXT...D6NQ | 2022-01-01 | [Download sample](https://datasets.tardis.dev/v1/star-atlas/incremental_book_L2/2022/01/01/AYXTVTTPFHYMN3JRYX5XBRJWPK2M9445MBN2ILYRD6NQ.csv.gz) |
| quotes                | AYXT...D6NQ | 2022-01-01 | [Download sample](https://datasets.tardis.dev/v1/star-atlas/quotes/2022/01/01/AYXTVTTPFHYMN3JRYX5XBRJWPK2M9445MBN2ILYRD6NQ.csv.gz)              |
| book\_ticker          | AYXT...D6NQ | 2022-01-01 | [Download sample](https://datasets.tardis.dev/v1/star-atlas/book_ticker/2022/01/01/AYXTVTTPFHYMN3JRYX5XBRJWPK2M9445MBN2ILYRD6NQ.csv.gz)         |

### API Access and data format

Historical data format is the same as provided by real-time Star Atlas DEX WebSocket API (via [serum-vial](https://github.com/tardis-dev/serum-vial)) with addition of local timestamps. If you'd like to work with **normalized data format** instead (same format for each exchange) see [downloadable CSV files](/downloadable-csv-files/overview) or official [client libs](/api/quickstart) that can perform data normalization client-side.

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

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

async def main():
    async for local_timestamp, message in replay(
        exchange="star-atlas",
        from_date="2022-01-01",
        to_date="2022-01-02",
        filters=[Channel(name="l2snapshot", symbols=[])],
        api_key="YOUR_API_KEY",
    ):
        # messages as provided by Star Atlas DEX real-time stream
        print(message)

asyncio.run(main())
```

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

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

```javascript
// npm install tardis-dev
import { replay } from 'tardis-dev';

const messages = replay({
  exchange: 'star-atlas',
  from: '2022-01-01',
  to: '2022-01-02',
  filters: [{ channel: 'l2snapshot', symbols: [] }],
  apiKey: 'YOUR_API_KEY'
});

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

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

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

```bash
curl --compressed -g 'https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01&filters=[{"channel":"l2snapshot","symbols":[]}]&offset=0'
```

{% embed url="<https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01&filters=[{%22channel%22:%22l2snapshot%22,%22symbols%22:[]}]&offset=0>" %}
Example API response for Star Atlas DEX historical market data request
{% endembed %}

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

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

```bash
curl -g 'localhost:8000/replay?options={"exchange":"star-atlas","filters":[{"channel":"l2snapshot","symbols":[]}],"from":"2022-01-01","to":"2022-01-02"}'
```

[Tardis-machine](/tardis-machine/quickstart) 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) that provides data only in minute by minute slices.

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

### Captured real-time channels

{% embed url="<https://github.com/tardis-dev/serum-vial>" %}
See serum-vial docs providing documentation for each captured channel's format
{% endembed %}

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

* [trade](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22trade%22}]) Public trade executions stream
* [l2snapshot](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22l2snapshot%22}]) Level 2 order book snapshots
* [l2update](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22l2update%22}]) Level 2 order book incremental updates
* [quote](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22quote%22}]) Best bid and ask quote updates
* [recent\_trades](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22recent_trades%22}]) Recent trades snapshot stream
* [l3snapshot](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22l3snapshot%22}]) Level 3 order book snapshots
* [open](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22open%22}]) Order open events
* [fill](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22fill%22}]) Order fill events
* [change](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22change%22}]) Order change events
* [done](https://api.tardis.dev/v1/data-feeds/star-atlas?from=2022-01-01\&filters=\[{%22channel%22:%22done%22}]) Order done events

### Market data collection details

[Market data collection infrastructure](/faq/general#what-is-your-infrastructure-setup) for Star Atlas DEX was located in GCP europe-west2 region (London, UK).

Real-time market data was captured via **WebSocket connection** to `wss://serum-vial.tardis.staratlas.one/v1/ws`.

{% hint style="info" %}
Star Atlas DEX was a Solana-based decentralized exchange with no centralized server infrastructure.
{% endhint %}


# Privacy Policy

Tardis.dev privacy policy — what data we collect, how we collect it and what we do with this data

Last updated: 2026-06-25

This Privacy Policy explains how Tardis.dev ("us", "we", "our" or "Tardis.dev") collects, uses, discloses and otherwise processes Personal Information about customers, prospective customers and other users of our websites ([https://tardis.dev](https://tardis.dev/) and [https://docs.tardis.dev](https://docs.tardis.dev/)), services, tools, related applications, materials and software, including research and marketing activities (the "Services"). It also explains your choices regarding access, storage and correction of Personal Information. This Privacy Policy does not apply to employees, applicants or other personnel.

By using the Services or agreeing to our [Terms of Service](/legal/terms-of-service), you acknowledge that we collect, use, store and disclose information as described in this Privacy Policy.

Our Services may contain links to other websites or services. Those websites and services are governed by their own privacy statements.

### What information do we collect? <a href="#what-information-do-we-collect" id="what-information-do-we-collect"></a>

We collect and process the following information and use the following service providers:

* To manage checkout, payments, taxes, invoices, chargebacks, subscriptions and payment-related refunds, we use Paddle ([https://paddle.com](https://paddle.com/)) as our Merchant of Record and authorised reseller. Paddle may process payment, billing, transaction and tax information needed to complete and manage your purchase. See Paddle's Privacy Policy: <https://www.paddle.com/legal/privacy>
* We track and store usage behavior, such as clicked links and API endpoint usage statistics, to improve the Services. We use Google Analytics with anonymized IP enabled for this purpose. See Google's Privacy Policy: <https://www.google.com/policies/privacy/>
* We use Crisp to provide livechat support functionality. See Crisp's Privacy Policy: <https://crisp.chat/en/privacy/>
* When you contact us for support or other customer service requests, we may keep records of the request, including information you provide, and respond with relevant service information. We may also obtain Personal Information about you from publicly accessible sources such as LinkedIn, Facebook and Twitter.
* We may use your Personal Information to send marketing or promotional communications about Tardis.dev. You can opt out at any time by using the unsubscribe link in an email or contacting <privacy@tardis.dev>. We will process opt-out requests promptly and in any event within two (2) business days.
* To keep track of which users should have access to paid versions of our services and to handle API authentication and authorization, we store user details such as email address, name, subscription details and IP address in Cloudflare data store (encrypted at rest). See Cloudflare's Privacy Statement: <https://www.cloudflare.com/privacypolicy>
* Where required by market data licensors, exchanges or data providers such as Coinbase, we may share limited account, subscription, contact and usage information needed for reporting, audit, compliance, licence enforcement or similar purposes.

Unless stated otherwise, information requested by Tardis.dev is mandatory where needed to provide the Services. If a website field is marked optional, you may leave it blank without affecting the availability or functioning of the Services. Contact <privacy@tardis.dev> if you are unsure which information is required.

We may publicly display aggregated anonymous data to help communicate what we know about how our services are typically used.

### Legal bases and consent <a href="#legal-bases-and-consent" id="legal-bases-and-consent"></a>

We process Personal Information as needed to perform our contract with you, comply with legal obligations, and pursue legitimate interests in operating, securing, supporting and enforcing the Services. This includes subscriptions, accounts, API keys, support, billing, payments, fraud prevention, compliance, market data licensor reporting and legal claims. Where applicable law requires consent for a specific use, we rely on consent for that use.

If we ask for your Personal Information so that we can send you marketing communications in the future, we will either ask you directly for your consent or provide you with an opportunity to opt out.

### Privacy choices <a href="#privacy-choices" id="privacy-choices"></a>

If you wish to withdraw consent where consent is the applicable basis for processing, opt out of marketing communications, or exercise privacy rights available to you under applicable law, please contact us at <privacy@tardis.dev>.

### Disclosure <a href="#disclosure" id="disclosure"></a>

We may disclose your personal information if we are required by law to do so, if disclosure is reasonably necessary to provide or secure the Services, manage payments, comply with market data licensor or data provider requirements, enforce our [Terms of Service](/legal/terms-of-service), investigate abuse or security issues, or establish, exercise or defend legal claims.

### Third-party services <a href="#third-party-services" id="third-party-services"></a>

Third-party providers collect, use and disclose your information only to the extent needed to provide services to us. They have their own privacy policies for the information we provide to them.

Some providers may be located in a different jurisdiction than you or us. Your information may be subject to the laws of those jurisdictions.

### Links <a href="#links" id="links"></a>

When you click on links that appear in any of the content we provide to you, those links may direct you to third party sites. We are not responsible for the privacy practices of other sites and encourage you to read their privacy statements.

### Security <a href="#security" id="security"></a>

To protect your personal information, we take reasonable precautions to make sure it is not inappropriately lost, misused, accessed, disclosed, altered or destroyed.

### Cookies <a href="#cookies" id="cookies"></a>

Our website uses [cookies](https://cookiesandyou.com/) to track anonymized usage behavior and to personalize content.

### Retention of Personal Information

We retain personal information for as long as reasonably necessary to provide the Services, manage accounts and subscriptions, comply with legal, tax, accounting, market data licensor and data provider obligations, resolve disputes, enforce our agreements, maintain security and prevent abuse.

### Age of consent <a href="#age-of-consent" id="age-of-consent"></a>

By using Tardis.dev websites and services, you represent that you are legally able to use them and provide Personal Information to us.

### Changes to this privacy policy <a href="#changes-to-this-privacy-policy" id="changes-to-this-privacy-policy"></a>

We may modify this privacy policy at any time. Changes take effect when posted on the website. If we make material changes, we will update this page so you can see what changed.

If we are acquired or merged with another company, your information may be transferred to the new owners.

### Questions and contact information <a href="#questions-and-contact-information" id="questions-and-contact-information"></a>

To access, correct, amend or delete personal information we have about you, register a complaint, or ask for more information, email <privacy@tardis.dev>.


# Terms of Service

Terms you are agreeing to when you use Tardis.dev website and its services

Last modification date: 2026-06-25

## General conditions

Throughout the page, the terms “we”, “us” and “our” refer to Tardis.dev.

These Terms of Service ("Terms") govern your use of the Tardis.dev websites ([https://tardis.dev](https://tardis.dev/) and [https://docs.tardis.dev](https://docs.tardis.dev/)), including any customer portal or interactive customer website, and the services, tools, related applications, materials and software we make available, including research and marketing activities (the "Services"). By accessing or using the Services, or purchasing a subscription, you agree to these Terms, including the additional terms and [policies](/legal/privacy-policy) referenced in them.

New features and tools are also subject to these Terms. You can review the current version on this page. Subject to Clause 20, continued use of the Services after changes are posted constitutes acceptance of those changes.

The Services are intended primarily for business, professional, research, institutional and other non-consumer use. If you use or purchase the Services as a consumer, nothing in these Terms of Service limits any mandatory consumer rights that cannot be excluded or limited under applicable law or Paddle's Buyer Terms.

If you purchase or use the Services on behalf of a company, institution, fund, partnership or other organisation, you represent that you have authority to bind that organisation to these Terms of Service.

By agreeing to these Terms of Service, you represent that you are legally able to enter into a binding agreement.

A breach or violation of any of the Terms may result in suspension or immediate termination of the Services.

We reserve the right to refuse, suspend or terminate service to anyone for any reason at any time, subject to Clause 13.

We reserve the right at any time to modify or discontinue the Services, or any part of them, without notice.

We shall not be liable to you or to any third party for any modification, price change, suspension or discontinuance of the Services.

You agree to indemnify, defend and hold harmless Tardis.dev and our affiliates, officers, directors, contractors and employees from any claim or demand, including reasonable attorneys' fees, made by any third party due to or arising out of your breach of these Terms of Service or the documents they incorporate by reference, or your violation of any law or the rights of a third party.

In the event that any provision of these Terms of Service is determined to be unlawful, void or unenforceable, such provision shall nonetheless be enforceable to the fullest extent permitted by applicable law, and the unenforceable portion shall be deemed to be severed from these Terms of Service, such determination shall not affect the validity and enforceability of any other remaining provisions.

You must not use the Services:

1. for any unlawful purpose;
2. to solicit others to perform or participate in unlawful acts;
3. to violate any applicable law, regulation, rule or ordinance;
4. to infringe or violate our intellectual property rights or the intellectual property rights of others;
5. to harass, abuse, insult, harm, defame, slander, disparage, intimidate or discriminate based on gender, sexual orientation, religion, ethnicity, race, age, national origin or disability;
6. to submit false or misleading information;
7. to upload or transmit viruses or other malicious code;
8. to collect or track the personal information of others;
9. to spam, phish, pharm or pretext;
10. for any obscene or immoral purpose; or
11. to interfere with or circumvent security features of the Services or any related website.

We reserve the right to terminate your use of the Services or any related website for violating any prohibited use.

The failure of us to exercise or enforce any right or provision of these Terms of Service shall not constitute a waiver of such right or provision.

These Terms of Service and any policies or operating rules posted by us on this site or in respect of the Services constitute the entire agreement and understanding between you and us and govern your use of the Services, superseding any prior or contemporaneous agreements, communications and proposals, whether oral or written, between you and us (including, but not limited to, any prior versions of the Terms of Service).

Any ambiguities in the interpretation of these Terms of Service shall not be construed against the drafting party.

## Payments

Our order process is conducted by our online reseller [Paddle.com](https://www.paddle.com/legal/buyer-terms). Paddle.com is the Merchant of Record and authorised reseller for paid subscriptions, which means that payment collection, taxes, invoices, chargebacks and payment-related refunds are processed by Paddle under Paddle's Buyer Terms. Your licence to access and use the Services remains governed by this Agreement between you and Tardis.dev.

By agreeing to these Terms of Service you also agree to Paddle's Buyer Terms (<https://www.paddle.com/legal/buyer-terms>).

Paddle.com handles payment-related returns and payment support. Tardis.dev handles service access, API keys, data, documentation and product support.

## **Licence Agreement**

By purchasing the Services provided by Tardis.dev (“**the Supplier**”), you (the “**Customer**”) agree to this Licence Agreement (“**Agreement**”). This Agreement includes the Supplier’s [Privacy Policy](/legal/privacy-policy) and any additional terms or policies that the Supplier tells the Customer about.

### 1. Interpretation

1.1 The definitions and rules of interpretation in this clause apply in this Agreement and in any other agreement between the parties.

**Authorised Person**: means in relation to either party: (i) any director, officer, employee or professional advisor of that party to whom the disclosure of Confidential Information is necessary in order to enable that party to perform obligations or exercise rights pursuant to this Agreement; (ii) any body which regulates that party in any jurisdiction, if disclosure to that body is mandated by applicable law or relevant regulation; (iii) the insurers, brokers and auditors of that party; and (iv) any service providers providing administrative and similar support services to that party in the ordinary course of business in connection with the performance of obligations under this Agreement and to whom disclosure of Confidential Information is necessary to enable that party to perform obligations or exercise rights pursuant to this Agreement.

**Confidential Information**: all financial, business and technical and all other information (regardless of its form or the medium in which it is stored) concerning the business and affairs of a party or of a confidential nature that the other party obtains, receives or has access to, before or after the date of this Agreement, in connection with, or in the performance of, the Agreement.

**Customer System**: any information technology system or systems owned or operated by the Customer to which Data is delivered or within which Data is Distributed in accordance with this Agreement.

**Customer User**: the Customer, where the Customer is an individual, and any employee, officer, director, contractor or consultant of the Customer authorized by the Customer to access and use the Services (wholly or in part) under the Customer's subscription. Customer Users do not include Customer Affiliates, clients, customers, vendors or other third parties unless expressly approved in writing by Supplier.

**Customer Affiliate**: an entity that owns or controls, is owned or controlled by or is under common control or ownership with Customer, where control is defined as the possession, directly or indirectly, of the power to direct or cause the direction of the management and policies of an entity, whether through ownership of voting securities, by contract or otherwise;

**Customer Conduct Event**: means that Supplier reasonably determines that the Customer or any Customer User: (i) uses abusive, threatening, harassing, discriminatory, obscene or defamatory communications with Supplier, its contractors, Paddle or support providers; (ii) misuses support, billing, access, API, trial, refund or chargeback processes; (iii) creates a legal, security, payment or operational risk, or an unreasonable support burden, for Supplier or the Services; or (iv) repeatedly disregards reasonable written instructions about appropriate use of the Services or support channels. A good-faith complaint, honest negative feedback, a lawful refund request, a chargeback right or the exercise of a statutory right is not by itself a Customer Conduct Event.

**Customer User Restrictions:** the obligations set out in [Schedule 1](#schedule-1-customer-user-restrictions).

**Data:** the data or information, in whatever form including images, still and moving, and including financial and market research information, the provision of which comprises the Services (wholly or in part).

**Coinbase Data:** Data sourced from Coinbase markets and made available through the Services, including Coinbase and Coinbase International Exchange market data, and any related data or information to the extent Coinbase's market data terms or policy apply to it.

**Derived Data**: any output created by Manipulating Data that does not expose raw market data records, messages, event-level data or substantially similar market data, cannot reasonably be used as a substitute for the Data or the Services, and cannot reasonably be reverse-engineered to reconstruct the Data. Derived Data does not include Data that has merely been reformatted, filtered, sampled or transmitted in a way that preserves raw or substantially similar market data.

**Distribute:** to make Data accessible (including the provision of access through a database or other application populated with the Data, transferring or disclosing the Data) by any means, including any electronic means, to any Customer User.

**Effective Date:** date of acceptance of the Agreement by the Customer.

**Fees:** fees specified on the Website and in the purchase invoice.

**Force Majeure Event**: means an event beyond a Party's reasonable control (but in each case only to the extent actually beyond the control of the Party seeking to rely on that event as a Force Majeure Event), including: (i) extreme abnormal weather conditions; (ii) nuclear, chemical or biological contamination; (iii) war, civil commotion or terrorist attack; (iv) interruption or failure of a utility service including electric power, gas or water; (v) acts of God, floods or earthquakes; (vi) pandemic (excluding COVID-19); or (vii) the imposition of a sanction, embargo or breaking off of diplomatic relations, but excluding in each case strikes or other forms of industrial action by the employees, agents or subcontractors of that Party, or any change in applicable law or relevant regulation.

**Initial Period:** the period commencing on the Effective Date that is specified in the purchase invoice.

**Insolvency Event**: (i) any procedure commenced with a view to the winding-up or re-organisation of such party; (ii) any step taken or any procedure is commenced with a view to the appointment of an administrator, receiver, administrative receiver or trustee in bankruptcy in relation to such party or all or substantially all of its assets; (iii) the holder of any security over all or substantially all of the assets of such party takes any step to enforce that security; (iv) all or substantially all of the assets of such party is subject to attachment, sequestration, execution or any similar process; (v) such party is unable to pay its debts as they fall due; (vi) such party enters into, or any step is taken, whether by the board of directors of such party or otherwise, towards entering into a composition or arrangement with its creditors or any class of them, including a company voluntary arrangement or a deed of arrangement; or (vii) such party enters into, or any step is taken, whether by the board of directors of such party or otherwise, towards any analogous procedure under the laws of any jurisdiction to the procedures set out in (i) to (vi) above.

**Intellectual Property Rights:** means: (i) rights in, and in relation to, any patents, registered designs, design rights, trade marks, trade and business names (including goodwill associated with any trade marks or trade and business names), copyright and related rights, moral rights, databases, domain names, semi-conductor and other topography rights and utility models, and including registrations and applications for, and renewals or extensions of, such rights, and similar or equivalent rights or forms of protection in any part of the world; (ii) rights in the nature of unfair competition rights and to sue for passing off and for past infringement; and (iii) trade secrets, confidentiality and other proprietary rights, including rights to know how and other technical information.

**Licence:** the licence granted in Clause 9.

**Manipulate:** to combine or aggregate the Data (wholly or in part) with other data or information or to adapt the Data (wholly or in part).

**Manipulated Data:** any Data which has been Manipulated. Manipulated Data includes any Derived Data.

**Mark:** means the trade marks, trade names, product or service names, logos, slogans, typefaces, brand or other proprietary words or symbols used by the Supplier from time to time.

**Materials:** any documents or software supplied by the Supplier under this Agreement.

**Permitted Use:** internal business, research, educational or personal use by the Customer and Customer Users only. It does not include use for the benefit of any Customer Affiliate, client, customer, vendor or other third party, except for redistribution or resale of Derived Data expressly permitted under Clause 9.2 or use expressly permitted in writing by Supplier.

**Release:** generally available upgrades and enhancements to the Data.

**Services:** the services to be supplied by the Supplier under this Agreement, including the supply of any Data, Materials, or Support.

**Software**: any software provided by the Supplier to enable the Services to be used including any Releases.

**Support**: the support to be supplied by the Supplier including reasonable efforts to assist the Customer to access the Data. Any support response times, availability figures or operational performance figures stated on the Website or in the documentation are targets or historical observations only, and are not service levels, warranties or guarantees unless expressly stated in a separate written agreement.

**Term:** the Initial Period and any Renewal Periods.

**Website**: means any webpage of the Supplier, including but not limited to [Tardis.dev](https://tardis.dev/).

1.2 The headings in this Agreement are inserted for convenience only and shall not affect its construction.

1.3 A person includes a natural person, corporate or unincorporated body (whether or not having separate legal personality).

1.4 The schedules form part of this Agreement and shall have effect as if set out in full in the body of this Agreement. Any reference to this Agreement includes the schedules.

1.5 A reference to a company shall include any company, corporation or other body corporate, wherever and however incorporated or established.

1.6 Unless the context otherwise requires, words in the singular shall include the plural and in the plural shall include the singular.

1.7 A reference to a particular law is a reference to it as it is in force for the time being taking account of any amendment, extension, or re-enactment and includes any subordinate legislation for the time being in force made under it.

1.8 References to clauses and schedules are to the clauses and schedules of this Agreement and references to paragraphs are to paragraphs of the relevant schedule.

1.9 Any words following the terms **including**, **include**, **in particular** or **for example** or any similar phrase shall be construed as illustrative and shall not limit the generality of the related general words.

1.10 If there is any uncertainty between any provision contained in the body of this Agreement and any provision contained in the Schedules or appendices, the provision in the body of this Agreement shall prevail.

### **2. Scope**

During the Term the Supplier shall supply the Services to the Customer and the Customer shall pay the Fees and use the Services.

### **3. Connection**

3.1 The Supplier shall use reasonable efforts to make connection to the Services available on the Effective Date.

3.2 The Customer shall ensure that it promptly complies with any minimum hardware configuration requirements specified by the Supplier to establish connectivity between the Customer System and the Services.

3.3 Each party shall bear its own costs of establishing that connectivity.

### **4. Services**

4.1 During the Term the Supplier shall supply the Services to the Customer.

4.2 The Supplier may change at any time, with as much prior notice to the Customer as is reasonably practicable:

1. the content, format or nature of the Data or the Services; and
2. the means of access to the Data or the Services.

4.3 The Supplier may suspend access to the Services, in whole or in part, with or without prior notice where Supplier reasonably considers suspension necessary to protect the Services, investigate a breach, comply with law or licensor requirements, address a security or payment risk, prevent abuse, or respond to a Customer Conduct Event.

### 5. Fees

5.1 Customer will pay, without offset or deduction, all fees due for the Services. Unless otherwise specified, all fees shall be due 14 days from the date of invoice and all fees are non-cancelable and non-refundable except where required by applicable law, required by Paddle's Buyer Terms, or expressly approved in writing by Supplier or Paddle. Cancellation, non-use, downgrade, loss of access caused by the Customer's breach, or termination caused by a Customer Conduct Event does not entitle the Customer to a refund.

5.2 The Supplier's online order process is conducted by Supplier's online reseller Paddle.com. Paddle.com is the Merchant of Record for paid subscription orders.

5.3 All Fees are exclusive of VAT or any other applicable sales tax, which shall be paid by the Customer at the rate and in the manner for the time being prescribed by law.

5.4 Any refund, credit, chargeback or payment adjustment that is approved or required will be processed through Paddle where the original payment was processed by Paddle.

### **6.** Confidentiality

6.1 The parties shall each, as a receiving party: (i) keep confidential all Confidential Information disclosed by the disclosing party; (ii) shall not use the Confidential Information disclosed by the disclosing party in any way contrary to this Agreement, including Schedule 1 and not otherwise for the benefit of any third party; and (iii) not disclose the Confidential Information disclosed by the disclosing party to any person save to an Authorised Person.

6.2 The parties shall each, as a receiving party, ensure that each Authorised Person complies with confidentiality provisions no less onerous than those contained in this Clause 6 and will remain liable for any disclosure of Confidential Information by each Authorised Person as if it had made such disclosure.

6.3 The parties shall each, on the other party’s request destroy, erase or deliver to the other party all the requesting party’s Confidential Information, save where the retention of such Confidential Information is necessary to comply with applicable law or relevant regulation or otherwise for the other party to exercise its rights or receive benefits due under the Agreement.

6.4 The parties agree that the provisions of Clauses 6.1, 6.2, and 6.3 shall not apply to any information which the receiving party can prove: (i) is or becomes public knowledge other than by breach of this Clause; (ii) was in the possession of the receiving party without restriction in relation to disclosure before the date of receipt from the disclosing party; (iii) is received from a third party who lawfully acquired it and who was under no obligation restricting its disclosure; or (iv) was independently developed without access to any Confidential Information disclosed by the disclosing party.

6.5 The parties agree that these provisions in this Clause 6 shall not apply so as to prevent disclosure of Confidential Information by the receiving party to the extent that such disclosure is required to be made by any authority of competent jurisdiction or by any applicable law or relevant regulation or for the purposes of defending itself in relation to actual or threatened proceedings, regardless of whether brought or threatened by the other party or any other person, provided in each case that where permissible the receiving party: (i) gives the disclosing party reasonable formal written notice (provided that this is not in contravention of applicable law or relevant regulation) prior to such disclosure to allow the disclosing party a reasonable opportunity to seek a protective order; and (ii) uses reasonable endeavours to obtain prior to the disclosures written assurance from the applicable entity that it will keep the Confidential Information confidential.

6.6 Each party reserves all rights in its Confidential Information. No rights or obligations in respect of a party’s Confidential Information, other than those expressly stated in this Agreement, are granted to the other party, or are to be implied from this Agreement.

6.7 The provisions of this Clause 6 shall survive any expiry or termination of the Agreement.

### **7.** Announcements

Neither party shall make, or permit any person to make, any public announcement concerning this Agreement without the prior written consent of the other party (such consent not to be unreasonably withheld or delayed), except as required by law, any governmental or regulatory authority (including any relevant securities exchange), any court or other authority of competent jurisdiction.

### **8. Security**

The Customer shall ensure that the Data and Materials are kept secure, and shall use security practices and systems consistent with standard industry practices and which will be applicable to the use of the Data and Materials to prevent, and take prompt and proper remedial action against, unauthorised access, copying, modification, storage, reproduction, display or distribution of the Data and the Materials.

### **9. Licence**

9.1 The Supplier grants to the Customer a non-exclusive, non-transferable, licence for the Permitted Use only, subject to the Customer User Restrictions, to:

1. access, view and Manipulate Data and create Derived Data;
2. store the Data and Manipulated Data on the Customer System;
3. Distribute Derived Data to Customer Users on the Customer System; and
4. use (but not modify) the Materials in support of the activities referred to in this Clause 9.1.

9.2 Except as expressly provided in this Agreement, the Customer shall not:

1. use the Services (wholly or in part) in its products or services; or
2. redistribute or resell the Data or the Services (wholly or in part), except for reselling or redistributing aggregated and calculated Derived Data, including OHLC or OHLCV candles, at a resolution of 10 minutes or longer, where no raw Data is exposed and the Data cannot reasonably be reconstructed, unless Clause 23 or applicable licensor terms prohibit that use.

The exception in Clause 9.2(2) does not apply to Coinbase Data except to the extent permitted under Clause 23.

9.3 The Customer shall comply with the Customer User Restrictions.

### **10. Intellectual property rights ownership**

10.1 The Customer acknowledges that:

1. all Intellectual Property Rights in the Data and the Materials are the property of the Supplier or its licensors, as the case may be;
2. it shall have no rights in or to the Data or the Materials other than the right to use them in accordance with the express terms of this Agreement;
3. the Supplier or its licensors has or have made and will continue to make substantial investment in the obtaining, verification, selection, coordination, development, presentation and supply of the Data;
4. it shall use the Supplier’s Mark strictly in accordance with the Supplier’s written instructions; and
5. any goodwill generated though the Customer’s use of the Supplier’s Mark shall belong only to the Supplier.

10.2 The Customer acknowledges that reference in any element of the Materials to trade names or proprietary products where no specific acknowledgement of such names or products is made does not imply that such names or products may be regarded by the Customer as free for general use, outside the scope of the use of the Materials authorised by this Agreement.

10.3 If any third-party claim is made, or in the Supplier's reasonable opinion is likely to be made, in relation to the use of the Data, the Supplier may at its sole option and expense:

1. procure for the Customer the right to continue using, developing, modifying or retaining the Data or the Materials (wholly or in part) in accordance with this Agreement;
2. modify the Data or the Materials (wholly or in part) so that they cease to be infringing;
3. replace the Data or the Materials (wholly or in part) with non-infringing items; or
4. terminate this Agreement immediately by notice in writing to the Customer.

10.4 Subject to Clause 12, Supplier shall defend the Customer against a third-party claim alleging that the Data or Materials, as supplied by Supplier and used by the Customer in accordance with this Agreement, infringe that third party's Intellectual Property Rights, and shall pay damages finally awarded by a court or agreed in a settlement approved by Supplier. This Clause 10.4 shall not apply to any claim arising from: (i) the Customer's breach of this Agreement; (ii) use of the Data or Materials outside the Permitted Use; (iii) modification, combination or redistribution by the Customer; (iv) use after Supplier has asked the Customer to stop using the relevant Data or Materials; or (v) materials, data, instructions or specifications provided by the Customer.

### **11. Warranties**

11.1 Except as expressly stated in this Agreement, all warranties, conditions and terms, whether express or implied by statute, common law or otherwise (including any implied warranties of satisfactory quality or fitness for a particular purpose or non-infringement) are hereby excluded to the extent permitted by law.

11.2 Without limiting the effect of Clause 11.1, the Supplier does not warrant or make any representations:

1. that the supply of the Data will be error-free, free from interruption, or operate without loss or corruption of data or technical malfunction;
2. that the Data is accurate, complete, reliable, secure, useful, fit for purpose or timely; or
3. that the Data has been tested for use by the Customer or any third party or that the Data will be suitable for or be capable of being used by the Customer or any third party; or
4. regarding the benefit the Customer or any third party will obtain from the Data.

### **12. Limitation of liability**

12.1 The Customer acknowledges that:

1. the use and interpretation of the Data requires specialist skill and knowledge of financial markets;
2. the Customer has that skill and knowledge and undertakes that it will exercise that skill and knowledge and appropriate judgment when using the Data;
3. the Customer shall be solely responsible, as against the Supplier, for any opinions, recommendations, forecasts or other conclusions made or actions taken by the Customer, any client of the Customer or any other third party based (wholly or in part) on the Data unless otherwise set out in this Clause 12; and
4. it is in the best position to ascertain any likely loss it may suffer in connection with this Agreement, that it is therefore responsible for making appropriate insurance arrangements to address the risk of any such loss and that the provisions of this Clause 12 are reasonable in these circumstances.

12.2 Neither party excludes or limits liability to the other party for:

1. fraud or fraudulent misrepresentation;
2. any matter which cannot be excluded by law.

12.3 Subject to Clause 12.2, each party shall not in any circumstances be liable whether in contract, tort (including for negligence and breach of statutory duty howsoever arising), misrepresentation (whether innocent or negligent), restitution or otherwise, for:

1. any loss (whether direct or indirect) of profits, business, business opportunities, revenue, turnover, reputation or goodwill;
2. any loss or corruption (whether direct or indirect) of data or information;
3. loss (whether direct or indirect) of anticipated savings or wasted expenditure (including management time); or
4. any loss or liability (whether direct or indirect) under or in relation to any other contract.

12.4 Subject to Clause 12.2, each party's total aggregate liability in contract, tort (including negligence and breach of statutory duty howsoever arising), misrepresentation (whether innocent or negligent), restitution or otherwise, arising in connection with the performance or contemplated performance of this Agreement or any collateral contract shall in all circumstances be limited to the total Fees paid by the Customer for the Services during the 12-month period immediately before the date on which the cause of action first arose or, if the cause of action arose during the Initial Period, in respect of the Initial Period.

12.5 The Supplier shall not be liable for any delay in delivery of the Services that is caused by an event within the scope of Clause 14, the Customer's failure to provide the Supplier with adequate delivery instructions or any other instructions that are relevant to the supply of the Services, or the Customer's failure to comply with Clause 3.2.

### **13. Term and termination**

13.1 This Agreement shall commence on the Effective Date. Unless terminated earlier in accordance with this Clause 13 or Clause 10.3, this Agreement shall continue for the Initial Period.

13.2 The Supplier may terminate this Agreement in respect of the Services (wholly or in part):

1. with immediate effect by giving written notice to the Customer if the Customer fails to pay any amount due under this Agreement on the due date for payment and remains in default not less than 30 days after being notified in writing to make that payment;
2. on written notice to the Customer at any time if the Supplier discontinues or withdraws, in whole or in part, its provision of the Services in question to all subscribers of such Services. The Supplier will use reasonable endeavours to give the Customer as much notice of the same as reasonably practicable, but any such termination will be without liability to the Supplier except for any refund or credit expressly provided under Clause 13.7;
3. on written notice to the Customer at any time if Supplier reasonably determines that continuing the customer relationship is not commercially or operationally reasonable, including because of repeated hostile, disruptive or unreasonable communications or requests;
4. with immediate effect by giving written notice to the Customer if a Customer Conduct Event occurs or if Supplier reasonably determines that continued provision of the Services to the Customer may expose Supplier, the Services, other customers, Paddle, licensors, suppliers or support providers to legal, security, payment or operational risk, or an unreasonable support burden.

13.3 Without prejudice to any rights that have accrued under this Agreement or any of its rights or remedies, either party may terminate this Agreement (or any part thereof) with immediate effect by giving written notice to the other party if:

1. the other party: (i) commits a material breach of this Agreement and (if that breach is remediable) fails to remedy that breach within a period of 30 days after being notified in writing to do so; or (ii) commits a series of breaches of this Agreement which when taken together have the impact or effect of or otherwise amount to a material breach;
2. a Force Majeure Event continues for a period exceeding two (2) months;
3. the other party becomes subject to an Insolvency Event; or
4. the party reasonably determines that it has become unlawful to perform its obligations under the Agreement.

13.4 Any provision of this Agreement that expressly or by implication is intended to come into or continue in force on or after termination of this Agreement shall remain in full force and effect.

13.5 Termination or expiry of this Agreement shall not affect any rights, remedies, obligations or liabilities of the parties that have accrued up to the date of termination or expiry, including the right to claim damages in respect of any breach of the Agreement which existed at or before the date of termination or expiry.

13.6 On any termination of this Agreement for any reason or expiry of the Term, the Customer shall:

1. immediately pay any outstanding amounts owed for the Services under this Agreement; and
2. within a reasonable period of termination or expiry ensure that there is no further use of the Services in any of the Customer's products, applications or services, provided that the Customer shall not be obliged to remove from its products, applications and services any Data or Derived Data incorporated into them in accordance with this Agreement before termination or expiry.

13.7 Except where required by applicable law, required by Paddle's Buyer Terms, or expressly approved in writing by Supplier or Paddle, termination, expiry, cancellation, non-use, downgrade or suspension of the Services does not entitle the Customer to any refund, credit or payment adjustment.

If Supplier terminates this Agreement under Clause 10.3, 13.2(2) or 13.2(3) and the Customer is not otherwise in breach, Supplier will approve a pro-rata refund or credit for the unused prepaid portion of the then-current subscription period after the effective termination date as the Customer's sole remedy, subject to Paddle's Buyer Terms where Paddle processed the original payment.

Supplier may, to the extent permitted by law, deduct discounts, taxes, third-party fees, chargeback costs, and any other amounts owed by the Customer from any refund or credit. If Supplier terminates or suspends this Agreement due to the Customer's breach, non-payment, fraud, misuse, or a Customer Conduct Event, the Customer shall not be entitled to any refund.

### **14. Force Majeure**

Neither party shall be responsible for any failure to fulfill any obligation for so long as, and to the extent to which, the fulfillment of such obligation is impeded by a Force Majeure Event, and the affected party:

1. has promptly notified the other party of any circumstances which may result in failure to perform its obligations;
2. uses its best endeavours to minimize the adverse consequences that any failure in performance of its obligations might have, and to return the performance of such obligations to normal as soon as possible.

### **15. Assignment**

15.1 This Agreement is personal to the Customer and it shall not assign, transfer, mortgage, charge, sub-contract, or otherwise transfer any of its rights and obligations under this Agreement, including to any Affiliate, without the prior written consent of the Supplier (which is not to be unreasonably withheld or delayed). For the purposes of this Agreement, the term “Affiliate” shall mean in respect of a party, any other entity that directly or indirectly controls, is controlled by or is under common control with, that party.

15.2 The Supplier may at any time assign, transfer, mortgage, charge, sub-contract, or otherwise transfer any of its rights and obligations under this Agreement without the consent of the Customer.

### **16. Waiver**

No failure or delay by a party to exercise any right or remedy provided under the Agreement or by law, or a single or partial exercise of such right or remedy, shall constitute a waiver of that or any other right or remedy, nor shall it preclude or restrict the further exercise of that or any other right or remedy.

### **17. Remedies**

Except as expressly provided in this Agreement, the rights and remedies provided under this Agreement are in addition to, and not exclusive of, any rights or remedies provided by law.

### **18. Notice**

All notices, demands and other communications provided for or permitted under this Agreement will be made in writing and sent by email. Notices to the Customer may be sent to the email address used for purchase, account access, support, billing or other communications with Supplier or Paddle. Notices to Supplier may be sent using the contact details published on the Website or otherwise notified by Supplier. Notices will be deemed received upon receipt of a delivery receipt or, if no delivery receipt is available, when sent unless the sender receives an automated delivery failure notice.

### **19. Entire Agreement**

19.1 This Agreement represents the entire agreement between the parties and supersedes all previous discussions, correspondence, negotiations, arrangements, understandings and agreements between them, whether written or oral, relating to its subject matter.

19.2 Each party acknowledges that in entering into this Agreement it does not rely on, and shall have no remedies in respect of, any representation or warranty (whether made innocently or negligently) that is not set out in this Agreement.

19.3 Each party agrees that it shall have no claim for innocent or negligent misrepresentation based on any statement in this agreement.

### **20. Variation**

20.1 The Supplier reserves the right to change this Agreement at any time by posting an updated version on the Website or otherwise notifying the Customer.

20.2 Unless an updated version states a later effective date, changes take effect when posted and apply to all access to and use of the Services after that time, including access under existing subscriptions and Renewal Periods, subject to any mandatory notice, consent or other requirements under applicable law or Paddle's Buyer Terms.

20.3 If the Customer does not agree to an updated Agreement, the Customer must stop using the Services and cancel any future renewal. Continued access to or use of the Services after the updated Agreement takes effect constitutes acceptance of the updated Agreement. Changes do not affect rights, remedies, obligations or liabilities that accrued before the updated Agreement took effect.

### **21. No partnership or agency**

Nothing in this agreement is intended to, or shall be deemed to, establish any partnership or joint venture between any of the parties, constitute any party the agent of another party, or authorise any party to make or enter into any commitments for or on behalf of any other party.

### **22. Third-party rights**

Except as expressly provided in this Agreement, a person who is not a party to this Agreement shall not have any rights under the Contracts (Rights of Third Parties) Act 1999 or otherwise to enforce any term of this Agreement.

### **23.** Coinbase market data license restrictions

Additional restrictions apply to Coinbase market data. Capitalized terms used in this Clause 23 and not defined in this Agreement have the meaning given in the [Coinbase Market Data Terms of Use](https://www.coinbase.com/legal/market_data). References to Derived Works in this Clause 23 use Coinbase's definition and are not limited by this Agreement's definition of Derived Data.

23.1 Customer shall not further disseminate Coinbase Data or Derived Works, or use or permit their use for any Prohibited Use. Prohibited Use includes:

1. use of Coinbase Data or Derived Works in violation of applicable law or this Agreement;
2. use of Coinbase Data to create Financial Products;
3. display or redistribution of any Coinbase Data or Derived Works:
   1. to any third party who is not a Customer; or
   2. by any Customer to any third party;
4. authorization of any Person to do any of the foregoing;
5. any other use not expressly permitted under this Agreement; and
6. any other use of Coinbase Data or Derived Works not expressly permitted under the [Coinbase Market Data Terms of Use](https://www.coinbase.com/legal/market_data).

23.2 Customer agrees that Coinbase may inspect Customer’s use of Coinbase Data or Derived Works by Customer and its agents upon ten (10) days' advance notice. Supplier may modify this Agreement, or any other agreement related to Coinbase Data or Derived Works, as required by Coinbase. Supplier may continue providing Coinbase Data or related Derived Works for up to ninety (90) days after receiving Coinbase's modification requirements. After that period, Supplier and Coinbase shall discontinue providing Coinbase Data or related Derived Works to any Customer that has not agreed to the modifications.

23.3 Customer agrees that Coinbase may require customer-specific information for reporting purposes, such as customer name or address, and that Supplier may report that information to Coinbase.

### **SCHEDULE 1 - CUSTOMER USER RESTRICTIONS**

1. The Customer shall:

(a) limit access to the Services to Customer Users only and not allow Customer Affiliates or any other third party to access or use the Services unless expressly approved in writing by Supplier;

(b) only make copies of the Data and the Materials to the extent reasonably necessary for the following purposes: back-up, mirroring (and similar availability enhancement techniques), security, disaster recovery and testing;

(c) comply with all applicable law and relevant regulations, and not use the Services for any purpose contrary to any applicable law or relevant regulation, or any regulatory code, guidance or request;

(d) not extract, reutilise, use, exploit, redistribute, resell, redisseminate, copy or store the Data or the Materials for any purpose not expressly permitted by this Agreement;

(e) not copy, modify, decompile, reverse engineer or create derivative works from the Software, except to the extent permitted by any applicable law; and

(f) not do anything which may damage the reputation of the Supplier, the Data or the Services, including by way of using the Data (wholly or in part) in any manner which is pornographic, racist or that incites religious hatred or violence.


