Trading API & SDK · SDK Setup & Authentication · 2/8
Reading Market Data
The Info Class
All read operations go through the Info class. No authentication required — anyone can read public market data.
from hyperliquid.info import Info
from hyperliquid.utils import constants
info = Info(base_url=constants.MAINNET_API_URL, skip_ws=True)
Fetching Market Metadata
# Get all available markets
meta = info.meta()
# meta["universe"] contains all perp markets
for asset in meta["universe"]:
print(f"{asset['name']}: max leverage {asset['maxLeverage']}x")
# As of October 2026: BTC 40x, ETH 25x, SOL 20x (these change; always read them live)
The metadata includes:
- Asset name (its position in
universeis the asset index used when signing orders) - Maximum leverage
szDecimals: how many decimals an order size may have- There is no explicit price increment field: perp prices may have up to 5 significant figures and at most
6 - szDecimalsdecimals (tick and lot size)
Order Book (L2 Data)
# Get the order book for BTC
book = info.l2_snapshot("BTC")
# book has "levels" with bids and asks (up to 20 levels per side)
bids = book["levels"][0] # [{"px": "...", "sz": "...", "n": orders}, ...]
asks = book["levels"][1]
best_bid = float(bids[0]["px"])
best_ask = float(asks[0]["px"])
spread = best_ask - best_bid
print(f"BTC: {best_bid} / {best_ask} (spread: {spread:.2f})")
User State
# Get account state (positions, margin, equity) for your main account address
state = info.user_state("0xYourAddress") # numbers come back as strings
# Account value
print(f"Account Value: ${state['marginSummary']['accountValue']}")
print(f"Total Margin: ${state['marginSummary']['totalMarginUsed']}")
# Open positions
for pos in state["assetPositions"]:
p = pos["position"]
print(f"{p['coin']}: {p['szi']} contracts @ {p['entryPx']}")
print(f" PnL: ${p['unrealizedPnl']}")
Funding Rates
# Current funding rates: metaAndAssetCtxs returns [meta, asset_contexts]
meta, ctxs = info.meta_and_asset_ctxs()
for asset, ctx in zip(meta["universe"], ctxs):
hourly = float(ctx["funding"]) * 100 # funding is paid every hour
annual = hourly * 24 * 365
print(f"{asset['name']}: {hourly:.4f}%/hr ({annual:.1f}% APR)")
Each context also carries markPx, oraclePx, openInterest, premium and dayNtlVlm.
Funding rates are critical for strategies like delta-neutral trading and funding rate arbitrage.
Historical Data
import time
# Get candle data (OHLCV); only the most recent 5000 candles are available
end_time = int(time.time() * 1000)
start_time = end_time - (24 * 60 * 60 * 1000) # 24 hours ago
candles = info.candles_snapshot("BTC", "1h", start_time, end_time)
for c in candles:
print(f"Open: {c['o']}, High: {c['h']}, Low: {c['l']}, Close: {c['c']}") # strings
HIP-3 Markets (Builder-Deployed Perps)
Besides the default perp dex, Hyperliquid hosts builder-deployed perp dexes (HIP-3), each run by its own deployer. Their coins carry a dex prefix, for example xyz:TSLA. The SDK only knows the dexes you list in perp_dexs ("" is the default dex), so pass them when creating Info (and Exchange):
info = Info(constants.MAINNET_API_URL, skip_ws=True, perp_dexs=["", "xyz"])
print(info.perp_dexs()) # [None, {"name": "xyz", ...}, ...]; None is the default dex
xyz_meta = info.meta(dex="xyz") # universe names look like "xyz:TSLA"
book = info.l2_snapshot("xyz:TSLA") # KeyError if "xyz" was not in perp_dexs
state = info.user_state("0xYourAddress", dex="xyz") # positions and margin are per dex
Orders use the same name; the SDK maps it to the asset ID 100000 + perp_dex_index * 10000 + index_in_meta (110001 for xyz:TSLA as of October 2026; see Asset IDs).