Thalex does not currently accept any applicants from Canada, the United States, Prohibited Jurisdictions, and other territories where dealing in cryptoassets may be subject to local registration. In addition, Thalex services may not be available for all client types in all jurisdictions, namely for UK consumers.

Historical Data

Fetch our historical market data

Historical data for Thalex is available through our REST API. Documentation can be found here. Below you will find some simple Python sample script that show how to use this API to get historical data.

Available Data

The Index Price Historical Data endpoint contains the index price data (open, high, low, close) within a specified resolution.

The Mark Price Historical Data endpoint contains market data for each tradable instrument within a specified resolution. The following data is provided:

  • Instrument Type (perpetual, future, combination, options)
  • Mark Price (open, high, low, close)
  • Implied Volatility for Options (open, high, low, close)
  • Accumulated funding for Perpetuals in each interval. This is the PNL for a long position of 1 Perpetual since the last interval. Summing up the accumulated funding for each interval in a trading day will result in that day’s funding payout (for a long position of 1 Perpetual). Note that the sign here is the opposite of the funding rate sign, as a positive funding rate means long pays short, resulting in a negative PNL for those with a long position.
  • Top of Book price and size at the start of each interval (top bid price, top bid size, top ask price, top ask size)

Code Snippets (Python)

The following code snippet prints the price of the specified index, in this case, BTCUSD.

python
import requests
from datetime import datetime, UTC

INDEX_NAME = "BTCUSD"
FROM_TIMESTAMP = int(datetime(2025, 6, 10, 8, 0, tzinfo=UTC).timestamp())
TO_TIMESTAMP = int(datetime(2025, 6, 24, 8, 0, tzinfo=UTC).timestamp())
RESOLUTION = "1m"

if __name__ == "__main__":
    result = requests.get(
        "https://thalex.com/api/v2/public/index_price_historical_data",
        params={
            "index_name": INDEX_NAME,
            "from": FROM_TIMESTAMP,
            "to": TO_TIMESTAMP,
            "resolution": RESOLUTION,
        },
    ).json()

    for row in result["result"]["index"][-5:]:
        dt = datetime.fromtimestamp(row[0], UTC)
        open = row[1]
        high = row[2]
        low = row[3]
        close = row[4]
        print(f"{dt} O:{open:.2f}, H:{high:.2f}, L:{low:.2f}, C:{close:.2f}")




The following code snippet prints the mark price of the specified instrument, in this case, BTC perpetual.

python
import requests
from datetime import datetime, UTC

INSTRUMENT_NAME = "BTC-PERPETUAL"
FROM_TIMESTAMP = int(datetime(2025, 6, 10, 8, 0, tzinfo=UTC).timestamp())
TO_TIMESTAMP = int(datetime(2025, 6, 24, 8, 0, tzinfo=UTC).timestamp())
RESOLUTION = "1m"

if __name__ == "__main__":
    result = requests.get(
        "https://thalex.com/api/v2/public/mark_price_historical_data",
        params={
            "instrument_name": INSTRUMENT_NAME,
            "from": FROM_TIMESTAMP,
            "to": TO_TIMESTAMP,
            "resolution": RESOLUTION,
        },
    ).json()

    for row in result["result"]["mark"][-5:]:
        dt = datetime.fromtimestamp(row[0], UTC)
        open = row[1]
        high = row[2]
        low = row[3]
        close = row[4]
        print(f"{dt} O:{open:.2f}, H:{high:.2f}, L:{low:.2f}, C:{close:.2f}")




The following code snippet prints the funding payment of the specified instrument, in this case, BTC perpetual.

python
import requests
from datetime import datetime, UTC

INSTRUMENT_NAME = "BTC-PERPETUAL"
FROM_TIMESTAMP = int(datetime(2025, 6, 10, 8, 0, tzinfo=UTC).timestamp())
TO_TIMESTAMP = int(datetime(2025, 6, 24, 8, 0, tzinfo=UTC).timestamp())
RESOLUTION = "1m"

if __name__ == "__main__":
    result = requests.get(
        "https://thalex.com/api/v2/public/mark_price_historical_data",
        params={
            "instrument_name": INSTRUMENT_NAME,
            "from": FROM_TIMESTAMP,
            "to": TO_TIMESTAMP,
            "resolution": RESOLUTION,
        },
    ).json()

    for row in result["result"]["mark"][-5:]:
        dt = datetime.fromtimestamp(row[0], UTC)
        funding_paid = row[5]
        print(f"{dt} Funding Paid: {funding_paid:.2f}")




The following code snippet prints the option IVs of the specific option, in this case, BTC-27JUN25-105000-C. For efficiency, we recommend you use a list of instruments and loop through them to print the prices for each instrument.

python
import requests
from datetime import datetime, UTC

INSTRUMENT_NAME = "BTC-27JUN25-105000-C"
FROM_TIMESTAMP = int(datetime(2025, 6, 10, 8, 0, tzinfo=UTC).timestamp())
TO_TIMESTAMP = int(datetime(2025, 6, 24, 8, 0, tzinfo=UTC).timestamp())
RESOLUTION = "1m"

if __name__ == "__main__":
    result = requests.get(
        "https://thalex.com/api/v2/public/mark_price_historical_data",
        params={
            "instrument_name": INSTRUMENT_NAME,
            "from": FROM_TIMESTAMP,
            "to": TO_TIMESTAMP,
            "resolution": RESOLUTION,
        },
    ).json()

    for row in result["result"]["mark"][-5:]:
        dt = datetime.fromtimestamp(row[0], UTC)
        iv_open = row[5]
        iv_high = row[6]
        iv_low = row[7]
        iv_close = row[8]
        print(f"{dt} IV_O:{iv_open:.2f}, IV_H:{iv_high:.2f}, IV_L:{iv_low:.2f}, IV_C:{iv_close:.2f}")




The following code snippet prints the top of book data for the specified instrument, in this case, BTC perpetual.

python
import requests
from datetime import datetime, UTC

INSTRUMENT_NAME = "BTC-PERPETUAL"
FROM_TIMESTAMP = int(datetime(2025, 6, 10, 8, 0, tzinfo=UTC).timestamp())
TO_TIMESTAMP = int(datetime(2025, 6, 24, 8, 0, tzinfo=UTC).timestamp())
RESOLUTION = "1m"

if __name__ == "__main__":
    result = requests.get(
        "https://thalex.com/api/v2/public/mark_price_historical_data",
        params={
            "instrument_name": INSTRUMENT_NAME,
            "from": FROM_TIMESTAMP,
            "to": TO_TIMESTAMP,
            "resolution": RESOLUTION,
        },
    ).json()

    for row in result["result"]["mark"][-5:]:
        dt = datetime.fromtimestamp(row[0], UTC)
        top_bid_price = row[-1][0]
        top_bid_size = row[-1][1]
        top_ask_price = row[-1][2]
        top_ask_size = row[-1][3]
        print(
            f"{dt} Top Bid: {top_bid_price}@{round(top_bid_size[0], 2) if top_bid_size and top_bid_size[0] is not None else 'N/A'}, Top Ask:  {top_ask_price}@{round(top_ask_size[0], 2) if top_ask_size and top_ask_size[0] is not None else 'N/A'}"
        )




Error Handling & Pagination

If you are fetching a large amount of data, you may need to paginate through the results. The following code snippet fetches the data in reverse chronological order until it reaches the from timestamp.

python
import requests
import time
from datetime import datetime, UTC

INDEX_NAME = "BTCUSD"
FROM_TIMESTAMP = int(datetime(2025, 6, 14, 8, 0, tzinfo=UTC).timestamp())
TO_TIMESTAMP = int(datetime(2025, 7, 14, 8, 0, tzinfo=UTC).timestamp())
RESOLUTION = "1m"

def fetch_historical_data(from_time, to_time, resolution):
    data = []
    params = {
        "index_name": INDEX_NAME,
        "from": from_time,
        "to": to_time,
        "resolution": resolution,
    }
    while True:
        response_json = requests.get(
            "https://thalex.com/api/v2/public/index_price_historical_data",
            params=params,
        ).json()

        if "error" in response_json:
            print(f"API Error: {response_json['error']}")
            break

        if response_json["result"].get("no_data", False):
            print("No data available in or before the specified range.")
            break

        response = response_json["result"]["index"]
        data = response + data

        if response[0][0] <= params["from"]:
            break

        params["to"] = response[0][0] - 1
        # Sleep for a moment to avoid getting throttled
        time.sleep(0.1)

    return data

if __name__ == "__main__":
    result = fetch_historical_data(FROM_TIMESTAMP, TO_TIMESTAMP, RESOLUTION)

    for row in result[-5:]:
        dt = datetime.fromtimestamp(row[0], UTC)
        open = row[1]
        high = row[2]
        low = row[3]
        close = row[4]
        print(f"{dt} O:{open:.2f}, H:{high:.2f}, L:{low:.2f}, C:{close:.2f}")