Complete Beginner's Guide to Bulk Downloading Historical Order Book Snapshots from Tardis.dev Using Python

Introduction: What Are Order Book Snapshots and Why Download Them?

As someone who spent three months manually copying order book data from exchange websites before discovering automation, I understand the pain firsthand. Order book snapshots are essentially photographs of the cryptocurrency market's supply and demand at any given moment—they show you all the bid (buy) and ask (sell) orders waiting in the queue, along with their quantities and prices.

In this hands-on tutorial, I will walk you through building a complete Python script that downloads historical order book data from Tardis.dev, a professional-grade market data provider. Whether you're building trading algorithms, conducting academic research, or analyzing market microstructure, this guide will save you countless hours of manual work.

What Is Tardis.dev?

Tardis.dev is a comprehensive market data API that provides historical and real-time cryptocurrency trading data from over 50 exchanges including Binance, Bybit, OKX, and Deribit. Their infrastructure handles billions of records and offers both REST APIs for historical queries and WebSocket streams for live data.

However, accessing this data requires understanding their API structure, authentication mechanisms, and pagination methods. That's exactly what this tutorial covers—step by step, from zero to working code.

Prerequisites: What You Need Before Starting

Before we write any code, let's ensure you have the necessary tools installed:

Understanding the Tardis.dev Order Book API

The Tardis.dev API follows REST conventions. For historical order book snapshots, you'll use their market data endpoints. Here's the core endpoint structure:

GET https://api.tardis.dev/v1/historical/order-books

To make this work, you need three key pieces of information:

Installing Required Python Packages

First, install the necessary libraries. Open your terminal and run:

pip install requests pandas python-dotenv tqdm

This installs four packages:

Step 1: Setting Up Your API Key Securely

NEVER hardcode your API key directly in your script. Create a separate .env file:

# Create a file named .env in your project folder
TARDIS_API_KEY=your_tardis_api_key_here

Then create a Python configuration module to load it safely:

import os
from dotenv import load_dotenv

load_dotenv()

Fetch API key from environment variable

TARDIS_API_KEY = os.getenv("TARDIS_API_KEY") if not TARDIS_API_KEY: raise ValueError("TARDIS_API_KEY not found in environment. Please check your .env file.")

Screenshot hint: Your project folder should look like this: [folder icon] my_orderbook_project/ → main.py, .env

Step 2: Understanding API Response Pagination

Tardis.dev returns data in pages. A typical response looks like this:

{
  "data": [...order book snapshots...],
  "meta": {
    "next_page_cursor": "eyJsYXN0X3RpbWVzdGFtcCI6MTcwNj...",
    "has_more": true
  }
}

You must loop through pages using the next_page_cursor until has_more becomes false.

Step 3: Building the Core Download Function

Here's the complete working function for fetching order book snapshots:

import requests
import time
from datetime import datetime, timedelta

def fetch_orderbook_snapshots(
    exchange: str,
    symbol: str,
    start_date: str,
    end_date: str,
    api_key: str
) -> list:
    """
    Fetch historical order book snapshots from Tardis.dev API.
    
    Args:
        exchange: Exchange name (e.g., 'binance', 'bybit')
        symbol: Trading pair (e.g., 'BTC-USDT')
        start_date: Start date in ISO format (e.g., '2024-01-01')
        end_date: End date in ISO format (e.g., '2024-01-02')
        api_key: Your Tardis.dev API key
    
    Returns:
        List of order book snapshot dictionaries
    """
    base_url = "https://api.tardis.dev/v1/historical/order-books"
    
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    all_snapshots = []
    cursor = None
    
    # Convert dates to timestamps
    start_ts = int(datetime.fromisoformat(start_date).timestamp() * 1000)
    end_ts = int(datetime.fromisoformat(end_date).timestamp() * 1000)
    
    params = {
        "exchange": exchange,
        "symbol": symbol,
        "from": start_ts,
        "to": end_ts,
        "limit": 1000  # Maximum records per request
    }
    
    print(f"Fetching {symbol} order books from {exchange}...")
    print(f"Date range: {start_date} to {end_date}")
    
    page_count = 0
    while True:
        page_count += 1
        
        if cursor:
            params["cursor"] = cursor
        
        try:
            response = requests.get(
                base_url,
                headers=headers,
                params=params,
                timeout=30
            )
            response.raise_for_status()
            
        except requests.exceptions.HTTPError as e:
            print(f"HTTP Error {e.response.status_code}: {e}")
            if e.response.status_code == 429:  # Rate limit
                print("Rate limited. Waiting 60 seconds...")
                time.sleep(60)
                continue
            break
            
        except requests.exceptions.RequestException as e:
            print(f"Request failed: {e}")
            break
        
        data = response.json()
        snapshots = data.get("data", [])
        all_snapshots.extend(snapshots)
        
        meta = data.get("meta", {})
        has_more = meta.get("has_more", False)
        cursor = meta.get("next_page_cursor")
        
        print(f"  Page {page_count}: Retrieved {