ironflow-sdk
Async Python SDK for Ironflow — every Hyperliquid trade, fill, order, liquidation, and book update, plus HIP-3 builder markets, HIP-4 prediction outcomes, and full wallet analytics (open positions, funding payments, maker/taker split, full ledger). Historical fills back to 2025-07-27, sub-second streaming from venue. Pandas-friendly bulk export for analysis.
Get a free API key in 30 seconds — email-only, no credit card. Free tier: 24h history, 10 req/min, 1 WebSocket connection, 10 tracked addresses. Paid tiers add more WS connections, 90-day to unlimited history, and webhook triggers.
Install
pip install ironflow-sdk
Python 3.11+. Built on httpx and websockets. Fully typed (py.typed).
Quick Start
import asyncio
from ironflow_sdk import Ironflow
async def main():
async with Ironflow("if_your_api_key") as client:
# Stream live trades (paid tiers)
async for trade in client.stream.trades("BTC-PERP"):
print(trade.price, trade.size, trade.side)
break # demo: take one and exit
# Or fetch history with auto-pagination
page = await client.trades("BTC-PERP", limit=100)
for trade in page.data:
print(trade)
asyncio.run(main())
Recipes
Copy-trade a wallet
Mirror every fill from a leader address as it lands.
async with Ironflow("if_xxx") as client:
async for fill in client.stream.fills("0xleader"):
print(fill.side, fill.size, fill.market, fill.price)
# submit identical order to your venue
Alert on Hyperliquid liquidations
Pipe every liquidation above a size threshold to Slack.
import httpx
async with Ironflow("if_xxx") as client, httpx.AsyncClient() as http:
async for liq in client.stream.liquidations("BTC-PERP"):
if float(liq.size) >= 10:
await http.post(SLACK_WEBHOOK, json={
"text": f"{liq.size} BTC liq @ {liq.price}",
})
Scan funding rates across every perp market
Find rate divergences across native and HIP-3 builder markets in one pass.
async with Ironflow("if_xxx") as client:
markets = await client.markets(market_class="perp")
for m in markets:
page = await client.funding(m.display_symbol, limit=1)
if page.data and abs(float(page.data[0].rate)) > 0.0005:
print(m.display_symbol, page.data[0].rate)
Reconstruct any HL wallet
Four endpoints over the same 365-day history reverse-engineer a wallet end-to-end — open positions and margin, funding payments, maker/taker split, and a unified ledger across deposits/withdrawals/funding/transfers. Backed by a bloom-filter index on fills.address — wallet-scope queries return in milliseconds.
async with Ironflow("if_xxx") as client:
addr = "0xabc..."
# Live snapshot (HL clearinghouseState shape)
state = await client.user_state(addr)
print(state.margin_summary.account_value, len(state.positions))
# Funding payments — positive = paid, negative = received
funding = await client.user_funding(addr, from_ts=int(time.time() * 1000) - 14 * 86_400_000)
total = sum(float(p.usdc) for p in funding)
# Maker/taker split, per market + a synthetic TOTAL row
mt = await client.user_maker_taker(addr, from_ts=int(time.time() * 1000) - 14 * 86_400_000)
total_row = next(r for r in mt.breakdown if r.market == "TOTAL")
# Unified ledger: deposits, withdrawals, funding, transfers
page = await client.user_ledger(addr, limit=200)
Bulk export to pandas
Bulk historical data exports as CSV or Parquet (Builder+ tier). Pipe straight into pandas for analysis.
import io
import pandas as pd
async with Ironflow("if_xxx") as client:
data = await client.export_data("fills", market="BTC-PERP", format="csv")
df = pd.read_csv(io.BytesIO(data))
print(df.describe())
Discover HIP-4 prediction markets
HIP-4 binary outcome contracts went live on Hyperliquid mainnet on 2026-05-02. Complementary outcomes have prices summing to 1.0.
async with Ironflow("if_xxx") as client:
predictions = await client.markets(market_class="prediction")
# predictions[0].display_symbol -> e.g. "BTC-78213-20260503-Yes"
Configuration
client = Ironflow(
"if_your_api_key",
base_url="https://api.ironflow.sh", # default
source="hyperliquid", # default
timeout=30.0, # request timeout in seconds (default: 30)
)
REST Endpoints
Market Data
async with Ironflow("if_your_api_key") as client:
# Trades
trades = await client.trades("BTC-PERP", limit=100)
# Fills (requires address)
fills = await client.fills("0xabc...", market="ETH-PERP")
# Order book snapshot
book = await client.book("BTC-PERP")
# book.bids[0].price, book.bids[0].size
# OHLCV candles
candles = await client.candles("BTC-PERP", "1h", limit=24)
# Liquidations
liqs = await client.liquidations("BTC-PERP")
# Funding rates
rates = await client.funding("BTC-PERP")
# Open interest
oi = await client.open_interest("BTC-PERP")
# Mark prices
prices = await client.mark_prices("BTC-PERP")
# Deposits & withdrawals
deps = await client.deposits(address="0xabc...")
wds = await client.withdrawals(address="0xabc...")
# Order statuses
orders = await client.order_statuses(address="0xabc...")
# Vault operations
vaults = await client.vault_operations(vault="HLP")
Wallet Analytics
Reverse-engineer any Hyperliquid wallet end-to-end. Available on every paid tier; respects per-tier history windows.
addr = "0xabc..."
# Open positions + margin summary (HL clearinghouseState shape)
state = await client.user_state(addr)
# Funding payments — paid (positive) and received (negative)
funding = await client.user_funding(addr, from_ts=from_ms, to_ts=to_ms)
# Maker vs taker breakdown per market + a synthetic TOTAL row
mt = await client.user_maker_taker(addr, from_ts=from_ms, to_ts=to_ms)
# mt.breakdown[i].market, .maker_volume, .taker_volume, .maker_pct, .taker_pct
# Unified ledger: deposits / withdrawals / funding / transfers
page = await client.user_ledger(addr, limit=200, cursor=None)
Analytics (Builder+)
flows = await client.net_flows(interval="1d", limit=7)
# flows[0].deposits, flows[0].withdrawals, flows[0].net_flow
levels = await client.liquidation_levels("BTC-PERP", bucket_size=100)
# levels[0].price_bucket, levels[0].count, levels[0].total_size
order_flow = await client.order_flow()
# order_flow[0].total_orders, order_flow[0].filled_orders, order_flow[0].fill_rate
leaderboard = await client.vault_leaderboard()
# leaderboard[0].vault, leaderboard[0].total_deposits, leaderboard[0].net_flow
funding = await client.funding_stats("BTC-PERP", interval="8h")
# funding[0].avg_rate, funding[0].min_rate, funding[0].max_rate
Triggers
# Create a webhook trigger
trigger = await client.create_trigger(
name="whale-alert",
channel="trades",
webhook_url="https://your-server.com/hook",
rule={"condition": {"field": "data.size", "op": "gt", "value": "100"}},
)
# List, toggle, delete
triggers = await client.list_triggers()
await client.toggle_trigger(trigger.id, is_active=False)
await client.delete_trigger(trigger.id)
# Test a rule without creating
matched = await client.test_trigger(
rule={"condition": {"field": "data.size", "op": "gt", "value": "10"}},
event={"data": {"size": "50", "market": "BTC-PERP"}},
)
print(matched) # True
Markets
# All currently-active markets (perp + spot, every issuer)
all_markets = await client.markets()
# Filter by class and issuer
perps = await client.markets(market_class="perp")
native = await client.markets(issuer="") # native non-builder only
flx_only = await client.markets(issuer="flx") # HIP-3 builder
predictions = await client.markets(market_class="prediction") # HIP-4
# Each Market carries the v3 identity tuple so it joins with /v1/* responses:
# market_id, source, market_class, issuer,
# base_asset, quote_asset, base_market, display_symbol,
# hl_coin, active_from_ms
#
# `base_market` is the display symbol with any HIP-3 issuer prefix stripped:
# "flx:GAS-PERP" -> "GAS-PERP" (pair with `issuer` to query across builders).
This endpoint reads the markets registry directly — no per-tier query window applies.
Cohorts (Enterprise)
cohorts = await client.list_cohorts()
addrs = await client.cohort_addresses("top_pnl_30d")
await client.create_cohort("my_whales", ["0xabc...", "0xdef..."])
await client.delete_cohort("my_whales")
Export (Builder+)
data = await client.export_data(
"fills",
market="BTC-PERP",
format="csv",
)
# data is bytes — write to file or parse with pandas
import io
import pandas as pd
df = pd.read_csv(io.BytesIO(data))
Status
# Overall system status + per-venue freshness
status = await client.status()
print(status.status) # "operational"
print(status.venues["hyperliquid"].streams["fills"].age_seconds)
# Rolling-window performance metrics (5-min API + pipeline + synthetic)
metrics = await client.status_metrics()
print(metrics.api.latency_p99_ms, metrics.pipeline.events_per_sec)
# Uptime / freshness timeline — "24h" (default) or "7d"
history = await client.status_history("7d")
print(history.uptime_percent, len(history.points))
Info API Proxy
meta = await client.info({"type": "metaAndAssetCtxs"})
WebSocket Streaming
All stream methods return typed async generators. Subscriptions auto-reconnect; iterate as long as you want data.
# Real-time trades
async for trade in client.stream.trades("BTC-PERP"):
print(trade.price, trade.size, trade.side)
# Wallet fills (copy trading)
async for fill in client.stream.fills("0xleader"):
print(fill.side, fill.size, fill.market)
# Order book updates
async for snap in client.stream.book("ETH-PERP"):
print(snap.bids[0].price, snap.asks[0].price)
# Filter by minimum size
async for trade in client.stream.trades("BTC-PERP", min_size="10"):
pass # Only trades >= 10 BTC
Available streams: trades, fills, book, book_l4, orders, liquidations, funding_rates, deposits, withdrawals, vault_operations.
Error Handling
from ironflow_sdk import Ironflow, RateLimitError, AuthError, TierError, QueryWindowError
try:
trades = await client.trades("BTC-PERP")
except RateLimitError as e:
print(f"Rate limited, retry in {e.retry_after_ms}ms")
except AuthError:
print("Invalid API key")
except TierError:
print("Upgrade your plan for this endpoint")
except QueryWindowError:
print("Time range too wide for your tier")
Pagination
All list endpoints return a Page[T] with async pagination:
page = await client.trades("BTC-PERP", limit=1000)
all_trades = list(page.data)
while page.has_more:
page = await page.next()
all_trades.extend(page.data)
Links
- Dashboard: ironflow.sh/dashboard
- Docs: docs.ironflow.sh
- API reference: docs.ironflow.sh/api-reference
- TypeScript SDK:
@ironflowsh/sdk - MCP server (for AI agents):
@ironflowsh/mcp
License
MIT
Metadata
Release files for ironflow-sdk 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ironflow_sdk-0.6.0.tar.gz | 26.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ironflow_sdk-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.1 kB
Release files / ironflow_sdk-0.6.0.tar.gz
| Download URL | ironflow_sdk-0.6.0.tar.gz |
|---|---|
| Size | 26.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a66b39aa20d8e082ec442f841eed5f7c0d212106866da9530938ef9e3b855664
|
|
BLAKE2b-256 checksum How to use checksums |
fa7225f72863901c852ea8d295c4f39bff5ae7f21ad19b67283d21924a3f39ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / ironflow_sdk-0.6.0-py3-none-any.whl
| Download URL | ironflow_sdk-0.6.0-py3-none-any.whl |
|---|---|
| Size | 23.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
487d77853ecb81fad6c0f67d51a660c301c52eaabcfdb05fb9c64244ecf02f66
|
|
BLAKE2b-256 checksum How to use checksums |
2ad4f14c63f00d68b082d9738dd2276126815d2f2d9a527865ba4d16885aac45
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|