The simplest way to trade on Hyperliquid. One line to place orders, zero ceremony.
from hyperliquid_sdk import HyperliquidSDK
sdk = HyperliquidSDK(endpoint)
order = sdk.market_buy("BTC", notional=100) # Buy $100 of BTCThat's it. No build-sign-send ceremony. No manual hash signing. No nonce tracking. Just trading.
Community SDK — Not affiliated with Hyperliquid Foundation.
pip install hyperliquid-sdkEverything is included: trading, market data, WebSocket streaming, gRPC streaming, HyperCore blocks, and EVM.
export PRIVATE_KEY="0xYOUR_PRIVATE_KEY"from hyperliquid_sdk import HyperliquidSDK
sdk = HyperliquidSDK(endpoint)
# Market orders
order = sdk.market_buy("BTC", size=0.001)
order = sdk.market_sell("ETH", notional=100) # $100 worth
# Limit orders
order = sdk.buy("BTC", size=0.001, price=65000, tif="gtc")
# Check your order
print(order.status) # "filled" or "resting"
print(order.oid) # Order IDAll data APIs are accessed through the SDK instance.
You can create a Hyperliquid endpoint on Quicknode to get access to the data APIs.
50+ methods for account state, positions, market data, and metadata.
sdk = HyperliquidSDK(endpoint)
# Market data
sdk.info().all_mids() # All mid prices
sdk.info().l2_book("BTC") # Order book
sdk.info().recent_trades("BTC") # Recent trades
sdk.info().candles("BTC", "1h", start, end) # OHLCV candles
sdk.info().funding_history("BTC", start, end) # Funding history
sdk.info().predicted_fundings() # Predicted funding rates
# Metadata
sdk.info().meta() # Exchange metadata
sdk.info().spot_meta() # Spot metadata
sdk.info().exchange_status() # Exchange status
sdk.info().perp_dexs() # Perpetual DEX info
sdk.info().max_market_order_ntls() # Max market order notionals
# User data
sdk.info().clearinghouse_state("0x...") # Positions & margin
sdk.info().spot_clearinghouse_state("0x...") # Spot balances
sdk.info().open_orders("0x...") # Open orders
sdk.info().frontend_open_orders("0x...") # Enhanced open orders
sdk.info().order_status("0x...", oid) # Specific order status
sdk.info().historical_orders("0x...") # Order history
sdk.info().user_fills("0x...") # Trade history
sdk.info().user_fills_by_time("0x...", start) # Fills by time range
sdk.info().user_funding("0x...") # Funding payments
sdk.info().user_fees("0x...") # Fee structure
sdk.info().user_rate_limit("0x...") # Rate limit status
sdk.info().user_role("0x...") # Account type
sdk.info().portfolio("0x...") # Portfolio history
sdk.info().sub_accounts("0x...") # Sub-accounts
sdk.info().extra_agents("0x...") # API keys/agents
# TWAP
sdk.info().user_twap_slice_fills("0x...") # TWAP slice fills
# Batch queries
sdk.info().batch_clearinghouse_states(["0x...", "0x..."])
# Vaults
sdk.info().vault_summaries() # All vault summaries
sdk.info().vault_details("0x...") # Specific vault
sdk.info().user_vault_equities("0x...") # User's vault equities
sdk.info().leading_vaults("0x...") # Vaults user leads
# Delegation/Staking
sdk.info().delegations("0x...") # Active delegations
sdk.info().delegator_summary("0x...") # Delegation summary
sdk.info().delegator_history("0x...") # Delegation history
sdk.info().delegator_rewards("0x...") # Delegation rewards
# Tokens
sdk.info().token_details("token_id") # Token details
sdk.info().spot_deploy_state("0x...") # Spot deployment state
# Other
sdk.info().referral("0x...") # Referral info
sdk.info().max_builder_fee("0x...", "0x...") # Builder fee limits
sdk.info().approved_builders("0x...") # Approved builders
sdk.info().liquidatable() # Liquidatable positionsBlock data, trading operations, and real-time data via JSON-RPC.
sdk = HyperliquidSDK(endpoint)
# Block data
sdk.core().latest_block_number() # Latest block
sdk.core().get_block(12345) # Get specific block
sdk.core().get_batch_blocks(100, 110) # Get block range
sdk.core().latest_blocks(count=10) # Latest blocks
# Recent data
sdk.core().latest_trades(count=10) # Recent trades (all coins)
sdk.core().latest_trades(count=10, coin="BTC") # Recent BTC trades
sdk.core().latest_orders(count=10) # Recent order events
sdk.core().latest_book_updates(count=10) # Recent book updates
# Discovery
sdk.core().list_dexes() # All DEXes
sdk.core().list_markets() # All markets
sdk.core().list_markets(dex="hyperliquidity") # Markets by DEX
# Order queries
sdk.core().open_orders("0x...") # User's open orders
sdk.core().order_status("0x...", oid) # Specific order status
sdk.core().preflight(...) # Validate order before signing50+ Ethereum JSON-RPC methods for Hyperliquid's EVM chain (chain ID 999 mainnet, 998 testnet).
sdk = HyperliquidSDK(endpoint)
# Chain info
sdk.evm().block_number() # Latest block
sdk.evm().chain_id() # 999 mainnet, 998 testnet
sdk.evm().gas_price() # Current gas price
sdk.evm().max_priority_fee_per_gas() # Priority fee
sdk.evm().net_version() # Network version
sdk.evm().syncing() # Sync status
# Accounts
sdk.evm().get_balance("0x...") # Account balance
sdk.evm().get_transaction_count("0x...") # Nonce
sdk.evm().get_code("0x...") # Contract code
sdk.evm().get_storage_at("0x...", position) # Storage value
# Transactions
sdk.evm().call({"to": "0x...", "data": "0x..."})
sdk.evm().estimate_gas(tx)
sdk.evm().send_raw_transaction(signed_tx)
sdk.evm().get_transaction_by_hash("0x...")
sdk.evm().get_transaction_receipt("0x...")
# Blocks
sdk.evm().get_block_by_number(12345)
sdk.evm().get_block_by_hash("0x...")
sdk.evm().get_block_receipts(12345)
sdk.evm().get_block_transaction_count_by_number(12345)
# Logs
sdk.evm().get_logs({"address": "0x...", "topics": [...]})
# HyperEVM-specific
sdk.evm().big_block_gas_price() # Big block gas price
sdk.evm().using_big_blocks() # Is using big blocks?
sdk.evm().get_system_txs_by_block_number(12345)
# Debug/Trace
sdk.evm().debug_trace_transaction("0x...", {"tracer": "callTracer"})
sdk.evm().debug_trace_block_by_number(12345)
sdk.evm().trace_transaction("0x...")
sdk.evm().trace_block(12345)20+ subscription types for real-time data with automatic reconnection.
sdk = HyperliquidSDK(endpoint)
# Subscribe to trades
sdk.stream().trades(["BTC", "ETH"], lambda t: print(f"Trade: {t}"))
# Subscribe to book updates
sdk.stream().book_updates(["BTC"], lambda b: print(f"Book: {b}"))
# Subscribe to orders (your orders)
sdk.stream().orders(["BTC"], lambda o: print(f"Order: {o}"), users=["0x..."])
# Run in background
sdk.stream().start()
# ... do other work ...
sdk.stream().stop()
# Or run blocking
sdk.stream().run()Available streams:
Market Data:
trades(coins, callback)— Executed tradesbook_updates(coins, callback)— Order book changesl2_book(coin, callback)— L2 order book snapshotsall_mids(callback)— All mid price updatescandle(coin, interval, callback)— Candlestick databbo(coin, callback)— Best bid/offer updatesactive_asset_ctx(coin, callback)— Asset context (pricing, volume)
User Data:
orders(coins, callback, users=None)— Order lifecycle eventsopen_orders(user, callback)— User's open ordersorder_updates(user, callback)— Order status changesuser_events(user, callback)— All user eventsuser_fills(user, callback)— Trade fillsuser_fundings(user, callback)— Funding paymentsuser_non_funding_ledger(user, callback)— Ledger changesclearinghouse_state(user, callback)— Position updatesactive_asset_data(user, coin, callback)— Trading parameters
TWAP:
twap(coins, callback)— TWAP executiontwap_states(user, callback)— TWAP algorithm statesuser_twap_slice_fills(user, callback)— TWAP slice fillsuser_twap_history(user, callback)— TWAP history
System:
events(callback)— System events (funding, liquidations)notification(user, callback)— User notificationsweb_data_3(user, callback)— Aggregate user info
Lower latency streaming via gRPC for high-frequency applications.
sdk = HyperliquidSDK(endpoint)
# Subscribe to trades
sdk.grpc().trades(["BTC", "ETH"], lambda t: print(f"Trade: {t}"))
# Subscribe to L2 order book (aggregated by price level)
sdk.grpc().l2_book("BTC", lambda b: print(f"Book: {b}"), n_sig_figs=5)
# Subscribe to L4 order book (CRITICAL: individual orders with order IDs)
sdk.grpc().l4_book("BTC", lambda b: print(f"L4: {b}"))
# Subscribe to blocks
sdk.grpc().blocks(lambda b: print(f"Block: {b}"))
# Run in background
sdk.grpc().start()
# ... do other work ...
sdk.grpc().stop()
# Or run blocking
sdk.grpc().run()Available gRPC Streams:
| Method | Parameters | Description |
|---|---|---|
trades(coins, callback) |
coins: List[str] |
Executed trades with price, size, direction |
orders(coins, callback, users=None) |
coins: List[str], users: List[str] (optional) |
Order lifecycle events |
book_updates(coins, callback) |
coins: List[str] |
Order book changes (deltas) |
l2_book(coin, callback, n_sig_figs=None) |
coin: str, n_sig_figs: int (3-5) |
L2 order book (aggregated by price) |
l4_book(coin, callback) |
coin: str |
L4 order book (individual orders) |
blocks(callback) |
- | Block data |
twap(coins, callback) |
coins: List[str] |
TWAP execution updates |
events(callback) |
- | System events (funding, liquidations) |
L4 order book shows every individual order with its order ID. This is essential for:
- Market Making: Know your exact queue position
- Order Flow Analysis: Detect large orders and icebergs
- Optimal Execution: See exactly what you're crossing
- HFT: Lower latency than WebSocket
def on_l4_book(data):
"""
L4 book data structure:
{
"coin": "BTC",
"bids": [[price, size, order_id], ...],
"asks": [[price, size, order_id], ...]
}
"""
for bid in data.get("bids", [])[:3]:
px, sz, oid = bid[0], bid[1], bid[2]
print(f"Bid: ${float(px):,.2f} x {sz} (order: {oid})")
sdk = HyperliquidSDK(endpoint)
sdk.grpc().l4_book("BTC", on_l4_book)
sdk.grpc().run()| Feature | L2 Book | L4 Book |
|---|---|---|
| Aggregation | By price level | Individual orders |
| Order IDs | No | Yes |
| Queue Position | Unknown | Visible |
| Bandwidth | Lower | Higher |
| Protocol | WebSocket or gRPC | gRPC only |
| Use Case | Price monitoring | Market making, HFT |
# Market orders
sdk.market_buy("BTC", size=0.001)
sdk.market_sell("ETH", notional=100)
# Limit orders
sdk.buy("BTC", size=0.001, price=65000)
sdk.sell("ETH", size=0.5, price=4000, tif="gtc")
# Perp trader aliases
sdk.long("BTC", size=0.001, price=65000)
sdk.short("ETH", notional=500, tif="ioc")# Place, modify, cancel
order = sdk.buy("BTC", size=0.001, price=60000, tif="gtc")
order.modify(price=61000)
order.cancel()
# Cancel all
sdk.cancel_all()
sdk.cancel_all("BTC") # Just BTC orders
# Dead-man's switch
import time
sdk.schedule_cancel(int(time.time() * 1000) + 60000)sdk.close_position("BTC") # Close entire position# Get all open orders
result = sdk.open_orders()
print(f"Total open orders: {len(result['orders'])}")
# Order fields: coin, limitPx (price), sz (size), side, oid, timestamp,
# orderType, tif, cloid, reduceOnly
for order in result['orders']:
print(f"{order['coin']} {order['side']} {order['sz']}@{order['limitPx']}")
# Filter by trading pair
btc_orders = [o for o in result['orders'] if o['coin'] == 'BTC']
for order in btc_orders:
print(f" {order['side']} {order['sz']} @ {order['limitPx']} | "
f"type={order['orderType']} tif={order['tif']} oid={order['oid']}")
# For enhanced data (triggers, children), use frontend_open_orders()
enhanced = sdk.info().frontend_open_orders(sdk.address)close_position() closes the entire position. To close a percentage, read the current size and place a reduce-only market order for the desired amount:
def close_percentage(sdk, coin: str, percent: float):
"""Close a percentage (0-100) of an open position."""
state = sdk.info().clearinghouse_state(sdk.address)
position = next(
(p for p in state['assetPositions'] if p['position']['coin'] == coin), None
)
if position is None:
raise ValueError(f"No open position for {coin}")
# szi is signed: positive = long, negative = short
szi = float(position['position']['szi'])
# Note: round close_size to asset's size decimals in production
close_size = abs(szi) * (percent / 100)
if szi > 0:
# Long position: sell to close
sdk.sell(coin, size=close_size, tif="market", reduce_only=True)
else:
# Short position: buy to close
sdk.buy(coin, size=close_size, tif="market", reduce_only=True)
# Close 50% of BTC position
close_percentage(sdk, "BTC", 50)Cancel all orders for an asset in one call:
# Cancel all orders for a specific asset
sdk.cancel_all("BTC")
# Cancel by client order ID (for CLOID-tracked orders)
sdk.cancel_by_cloid("0xmycloid...", "BTC")Or cancel selectively with per-order error handling:
from hyperliquid_sdk import HyperliquidError
# Get open orders
result = sdk.open_orders()
# Cancel specific orders with per-order error handling
target_orders = [o for o in result['orders']
if o['coin'] == 'BTC' and float(o['limitPx']) < 50000]
failures = []
for order in target_orders:
try:
sdk.cancel(order['oid'], order['coin'])
except HyperliquidError as e:
failures.append({'oid': order['oid'], 'error': str(e)})
if failures:
print(f"Failed to cancel {len(failures)} orders: {failures}")Use client order IDs (CLOIDs) for idempotent orders and categorize errors for retry logic:
import uuid
import time
import random
from hyperliquid_sdk import (
Order, HyperliquidError, RateLimitError, InvalidNonceError,
DuplicateOrderError, GeoBlockedError, InsufficientMarginError,
ValidationError, SignatureError, MaxOrdersError,
)
# Set a CLOID for idempotency — the exchange rejects duplicates
cloid = "0x" + uuid.uuid4().hex
order = sdk.order(Order.buy("BTC").size(0.001).price(65000).gtc().cloid(cloid))
# Error categories:
# Transient (retry): RateLimitError, InvalidNonceError
# Permanent (fail): GeoBlockedError, InsufficientMarginError, ValidationError,
# SignatureError, MaxOrdersError
# Already done: DuplicateOrderError (order already placed)
TRANSIENT_ERRORS = (RateLimitError, InvalidNonceError)
def place_with_retry(sdk, order_builder, max_retries=3):
"""Place an order with exponential backoff and idempotency."""
cloid = "0x" + uuid.uuid4().hex
order_builder = order_builder.cloid(cloid)
for attempt in range(max_retries):
try:
return sdk.order(order_builder)
except DuplicateOrderError:
return None # Order already went through
except TRANSIENT_ERRORS as e:
if attempt == max_retries - 1:
raise
wait = (2 ** attempt) + random.random()
time.sleep(wait)
# Timeout configuration on SDK constructor
from hyperliquid_sdk import HyperliquidSDK
sdk = HyperliquidSDK(endpoint, private_key="0x...", timeout=30)# Update leverage
sdk.update_leverage("BTC", leverage=10, is_cross=True) # 10x cross
sdk.update_leverage("ETH", leverage=5, is_cross=False) # 5x isolated
# Isolated margin management
sdk.update_isolated_margin("BTC", amount=100, is_buy=True) # Add margin to long
sdk.update_isolated_margin("ETH", amount=-50, is_buy=False) # Remove from short
sdk.top_up_isolated_only_margin("BTC", amount=100) # Special maintenance modefrom hyperliquid_sdk import Side
# Stop loss (market order when triggered)
sdk.stop_loss("BTC", size=0.001, trigger_price=60000)
# Stop loss (limit order when triggered)
sdk.stop_loss("BTC", size=0.001, trigger_price=60000, limit_price=59500)
# Take profit
sdk.take_profit("BTC", size=0.001, trigger_price=70000)
# Buy-side (closing shorts)
sdk.stop_loss("BTC", size=0.001, trigger_price=70000, side=Side.BUY)# Time-weighted average price order
result = sdk.twap_order(
"BTC",
size=0.01,
is_buy=True,
duration_minutes=60,
randomize=True
)
twap_id = result["response"]["data"]["running"]["id"]
# Cancel TWAP
sdk.twap_cancel("BTC", twap_id)# Internal transfers
sdk.transfer_spot_to_perp(amount=100)
sdk.transfer_perp_to_spot(amount=100)
# External transfers
sdk.transfer_usd(destination="0x...", amount=100)
sdk.transfer_spot(destination="0x...", token="PURR", amount=100)
sdk.send_asset(destination="0x...", token="USDC", amount=100)
# Withdraw to L1 (Arbitrum)
sdk.withdraw(destination="0x...", amount=100)HLP_VAULT = "0xdfc24b077bc1425ad1dea75bcb6f8158e10df303"
sdk.vault_deposit(vault_address=HLP_VAULT, amount=100)
sdk.vault_withdraw(vault_address=HLP_VAULT, amount=50)# Stake/unstake HYPE
sdk.stake(amount=1000)
sdk.unstake(amount=500) # 7-day queue
# Delegate to validators
sdk.delegate(validator="0x...", amount=500)
sdk.undelegate(validator="0x...", amount=250)from hyperliquid_sdk import Order
order = sdk.order(
Order.buy("BTC")
.size(0.001)
.price(65000)
.gtc()
.reduce_only()
)All errors inherit from HyperliquidError with a code and message.
from hyperliquid_sdk import (
HyperliquidError,
ApprovalError,
InsufficientMarginError,
GeoBlockedError,
)
try:
order = sdk.buy("BTC", size=0.001, price=65000)
except ApprovalError as e:
print(f"Need approval: {e.guidance}")
except InsufficientMarginError as e:
print(f"Not enough margin: {e.guidance}")
except GeoBlockedError as e:
print(f"Geo-blocked: {e.message}")
except HyperliquidError as e:
print(f"Error [{e.code}]: {e.message}")Available error types:
HyperliquidError— Base errorBuildError— Order building failedSendError— Transaction send failedApprovalError— Builder fee approval neededValidationError— Invalid parametersSignatureError— Signature verification failedNoPositionError— No position to closeOrderNotFoundError— Order not foundGeoBlockedError— Region blockedInsufficientMarginError— Not enough marginLeverageError— Invalid leverageRateLimitError— Rate limitedMaxOrdersError— Too many ordersReduceOnlyError— Reduce-only constraintDuplicateOrderError— Duplicate orderUserNotFoundError— User not foundMustDepositError— Deposit requiredInvalidNonceError— Invalid nonce
HyperliquidSDK(
endpoint=None, # Endpoint URL
private_key=None, # Falls back to PRIVATE_KEY env var
auto_approve=True, # Auto-approve builder fee (default: True)
max_fee="1%", # Max fee for auto-approval
slippage=0.03, # Default slippage for market orders (3%)
timeout=30, # Request timeout in seconds
)
# Access sub-clients
sdk.info() # Info API (market data, user data, metadata)
sdk.core() # HyperCore (blocks, trades, orders)
sdk.evm() # EVM (Ethereum JSON-RPC)
sdk.stream() # WebSocket streaming
sdk.grpc() # gRPC streaming
sdk.evm_stream() # EVM WebSocket (eth_subscribe)See the hyperliquid-examples repository for 44 complete, runnable examples covering trading, streaming, market data, and more.
This is an unofficial community SDK. It is not affiliated with Hyperliquid Foundation or Hyperliquid Labs.
Use at your own risk. Always review transactions before signing.
MIT License - see LICENSE for details.