How to Pull Historical Data from Hyperliquid: API Methods
Data is the foundation of quantitative research. Whether you are backtesting a trading strategy, studying funding-rate behavior, or analyzing market microstructure, you need reliable and complete historical data. Source: Hyperliquid docs.
Hyperliquid, as an on-chain perpetuals exchange, provides a useful set of historical data endpoints through its REST API, including candles / OHLCV, funding history, fills, order-related execution data, and liquidation events. This guide walks through the main data types, request formats, pagination patterns, and local storage practices. For workflows that require authenticated user data, a OneKey hardware wallet can help keep signing safer by keeping private keys off your data-collection machine.
Key comparison table
Hyperliquid Historical Data API Overview
According to Hyperliquid’s official documentation, most historical data queries are sent to the POST /info endpoint. The request body uses the type field to specify what kind of data you want.
All timestamps are Unix timestamps in milliseconds, meaning 13-digit integers.
Fetching Candle Data / OHLCV
Request format
import requests
BASE_URL = "https://api.hyperliquid.xyz"
def fetch_candles(coin, interval, start_ms, end_ms):
"""
coin : Market symbol, such as "BTC"
interval : Candle interval, such as "1m", "5m", "1h", "1d"
start_ms : Start time in milliseconds
end_ms : End time in milliseconds
"""
payload = {
"type": "candleSnapshot",
"req": {
"coin": coin,
"interval": interval,
"startTime": start_ms,
"endTime": end_ms
}
}
resp = requests.post(f"{BASE_URL}/info", json=payload)
resp.raise_for_status()
return resp.json()
# Example: fetch BTC 1-hour candles for the last 7 days
import time
end_ms = int(time.time() * 1000)
start_ms = end_ms - 7 * 24 * 3600 * 1000
candles = fetch_candles("BTC", "1h", start_ms, end_ms)
Response fields
Each candle typically includes the following fields. Always check the latest official docs for the exact schema:
t: candle start time, in millisecondso: open priceh: high pricel: low pricec: close pricev: volumen: number of trades
Pagination strategy
A single request may have a maximum number of returned rows. For longer history, split the time range into smaller windows and pull them one by one.
import time
def fetch_candles_paginated(coin, interval, start_ms, end_ms, page_size_ms):
"""
Split the time range into smaller chunks, fetch each chunk,
and merge the results.
page_size_ms: chunk size in milliseconds. Adjust based on interval.
"""
all_candles = []
cursor = start_ms
while cursor < end_ms:
batch_end = min(cursor + page_size_ms, end_ms)
batch = fetch_candles(coin, interval, cursor, batch_end)
all_candles.extend(batch)
if not batch:
break
# Start the next page from the last candle timestamp + 1 ms
cursor = batch[-1]["t"] + 1
# Avoid hitting rate limits
time.sleep(0.2)
return all_candles
Funding Rate History
Funding rates are a core mechanism in perpetual futures. Historical funding data is useful for studying positioning pressure, market sentiment, and carry / arbitrage-style strategies.
def fetch_funding_history(coin, start_ms, end_ms):
payload = {
"type": "fundingHistory",
"req": {
"coin": coin,
"startTime": start_ms,
"endTime": end_ms
}
}
resp = requests.post(f"{BASE_URL}/info", json=payload)
resp.raise_for_status()
return resp.json()
The response contains funding values and timestamps for each settlement period. Funding history can be used to:
- Analyze changes in long / short pressure
- Identify extreme sentiment conditions
- Estimate the cost of holding a perpetual position over time
User Fills and Order History
Some user-specific endpoints require a wallet address, and certain private-data workflows may require signed authentication. A OneKey hardware wallet can provide safer signing for this type of request because the private key remains inside the hardware secure element and is not exposed to your scraping script or server.
def fetch_user_fills(address, start_ms, end_ms):
payload = {
"type": "userFills",
"req": {
"user": address,
"startTime": start_ms,
"endTime": end_ms
}
}
resp = requests.post(f"{BASE_URL}/info", json=payload)
resp.raise_for_status()
return resp.json()
Fill history usually includes fields such as order ID, side, fill price, size, and fees. This data is essential for calculating realized PnL, measuring execution quality, and comparing live results against a backtest.
Liquidation Records
Market-level liquidation data can help you study market structure, forced deleveraging, and behavior during volatile periods.
def fetch_liquidations(start_ms, end_ms):
payload = {
"type": "liquidations",
"req": {
"startTime": start_ms,
"endTime": end_ms
}
}
resp = requests.post(f"{BASE_URL}/info", json=payload)
resp.raise_for_status()
return resp.json()
Data Storage: CSV and Databases
Save to CSV
For quick prototypes, CSV is often the simplest option.
import csv
def save_candles_to_csv(candles, filepath):
if not candles:
return
fieldnames = ["t", "o", "h", "l", "c", "v", "n"]
with open(filepath, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for candle in candles:
writer.writerow({k: candle.get(k, "") for k in fieldnames})
Save to a database
For larger datasets or faster queries, use SQLite for local research or PostgreSQL for production-style pipelines.
import sqlite3
def init_db(db_path):
conn = sqlite3.connect(db_path)
conn.execute("""
CREATE TABLE IF NOT EXISTS candles (
coin TEXT,
interval TEXT,
t INTEGER,
o REAL,
h REAL,
l REAL,
c REAL,
v REAL,
n INTEGER,
PRIMARY KEY (coin, interval, t)
)
""")
conn.commit()
return conn
def insert_candles(conn, coin, interval, candles):
rows = [
(
coin,
interval,
c["t"],
c["o"],
c["h"],
c["l"],
c["c"],
c["v"],
c["n"]
)
for c in candles
]
conn.executemany(
"INSERT OR IGNORE INTO candles VALUES (?,?,?,?,?,?,?,?,?)",
rows
)
conn.commit()
The PRIMARY KEY (coin, interval, t) prevents duplicate inserts when you re-fetch overlapping ranges. This makes incremental updates much easier.
Rate Limits and Practical Notes
Hyperliquid applies API rate limits. Always refer to the latest official documentation for current limits and endpoint behavior.
Practical suggestions:
- Add a delay between looped requests, commonly around 200–500 ms
- Implement exponential backoff and retry when you receive HTTP 429 responses
- Run large historical backfills outside peak trading periods when possible
- Cache data locally so you do not repeatedly request the same time ranges
- Validate your data after ingestion, especially before using it for backtests
Comparing with Other Data Sources
The advantage of Hyperliquid’s native API is that it is the most direct source for Hyperliquid market data and is generally the best starting point for exchange-specific research.
For cross-exchange research, you may combine it with other sources. dYdX documentation and GMX documentation also provide historical-data interfaces. Their request formats differ from Hyperliquid’s, but the core concepts — candles, trades, funding, fills, and pagination — are similar.
FAQ
Q1: What is the smallest candle interval available?
Refer to the candleSnapshot section in Hyperliquid’s official documentation. It supports multiple intervals, including minute-level, hourly, and daily intervals. The exact supported interval values should be checked against the latest docs. If you pass an invalid interval, the API should return an error.
Q2: How far back can historical data go?
In principle, data since a given Hyperliquid market went live may be available through the API. The actual range depends on when that market launched and what the API returns for your request. If no data exists for a selected period, the API may return an empty array.
Q3: How long does it take to pull a large amount of history?
It depends on the date range, interval, pagination size, and rate-limit handling. For example, pulling full-history 1-hour candles may take anywhere from several minutes to tens of minutes once you account for throttling. A better workflow is to backfill once, store the data, and then run incremental updates.
Q4: What role does a OneKey wallet play in data collection?
Public market data such as candles and funding rates does not require authentication. User-specific data, such as historical fills or order records, may require signed verification depending on the endpoint and workflow. A OneKey hardware wallet can help sign these requests without exposing your private key to the server or script that collects the data.
Q5: How should I handle data gaps?
Network errors, API issues, or interrupted jobs can create missing time ranges. Log every requested time window when ingesting data, scan your database for missing intervals, and backfill gaps separately. For backtesting, gaps can distort signals and performance metrics, so always run an integrity check before relying on the dataset.
Conclusion
Hyperliquid’s historical data API gives quant researchers a practical base for building data pipelines. With a few Python functions, you can collect candles, funding history, user fills, and liquidation records, then store them locally for research and incremental updates.
If your workflow also involves live trading, OneKey Perps offers a practical bridge between research and execution. You can use historical data to build and validate your process, then access perpetuals trading through OneKey while keeping wallet security central to the workflow. Download or open OneKey, connect your wallet, and try OneKey Perps when you are ready to move from analysis to execution.
Risk warning: Historical data only reflects past market conditions and does not predict future performance. Quantitative strategies built on historical data can be overfit, and live results may differ significantly from backtests. Perpetual futures are high-risk products and can lead to loss of funds. This article is for technical education only and is not financial, legal, or investment advice.



