Moon Dev API

Unique trading data for Hyperliquid.

Base URL: https://api.moondev.com
Version: 1.0
Updated: 2026-11-03
Quick Startcopy & run

Copy-paste this to test your API key instantly:

curl "https://api.moondev.com/api/ticks/btc.json?api_key=YOUR_API_KEY"

Or in Python:

import requests

data = requests.get(
    "https://api.moondev.com/api/ticks/btc.json",
    headers={"X-API-Key": "YOUR_API_KEY"}
).json()

print(f"BTC Price: ${data['latest_price']:,.2f}")

Need an API key?

Common Errors & Fixes
ErrorCauseFix
401 UnauthorizedMissing or invalid API keyAdd ?api_key=YOUR_KEY to URL or use X-API-Key header
401 stream_key_expiredDaily moonstream_* key rotated (~24h validity)Fetch a current key
404 Not FoundUppercase symbol (BTC.json)Use lowercase: btc.json not BTC.json
404 Not FoundMissing .json extensionAdd .json: /api/ticks/btc.json
410 GoneEndpoint permanently retiredSee the Changelog section for the retirement list and alternatives
503 fills_scanner_busyFills scanner at its concurrency limitRetry shortly or use your fallback source - not an empty result
๐Ÿค–

Moon Dev AI

Trading AI built on 5 Years of Moon Dev Research

Black box. Custom built on 5 years of Moon Dev quant research, backtesting strategies, and real trading experience, layered on top of a leading AI model. If you're an algorithmic trader using any other AI, you're cooked.

๐Ÿ” Black Box

My research and system on top. Real quant research.

๐Ÿ“ˆ 5 Years of Alpha

RBI system, backtesting, bot building, real trading edge.

โšก Built for Traders

Not a generic chatbot. Built by a trader, for traders.

๐Ÿ”— Endpoints

EndpointAuthDescription
GET /api/ai/healthNoHealth check
POST /api/ai/v1/chat/completionsYesChat completions
POST /api/ai/chatYesSimple chat

๐ŸŽฏ Quick Test

Verify the AI is live:

curl https://api.moondev.com/api/ai/health
๐Ÿ”‘ Key Details (Read This First!)
  • Base URL: https://api.moondev.com/api/ai/v1
  • Model: moondev-ai (always use this exact model name)
  • Auth Header: Authorization: Bearer YOUR_API_KEY

๐Ÿ’ป cURL

curl -X POST "https://api.moondev.com/api/ai/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "moondev-ai",
    "messages": [{"role": "user", "content": "How do I build a trading bot?"}],
    "max_tokens": 500
  }'

๐Ÿ Python (requests)

import requests

response = requests.post(
    "https://api.moondev.com/api/ai/v1/chat/completions",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_API_KEY"
    },
    json={
        "model": "moondev-ai",
        "messages": [{"role": "user", "content": "What is the RBI system?"}],
        "max_tokens": 500
    }
)

print(response.json()["choices"][0]["message"]["content"])

๐Ÿ Python (OpenAI SDK)

If you already use the OpenAI SDK, just change the base_url and api_key:

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.moondev.com/api/ai/v1"
)

response = client.chat.completions.create(
    model="moondev-ai",
    messages=[{"role": "user", "content": "What is the RBI system?"}],
    max_tokens=500
)

print(response.choices[0].message.content)

๐Ÿ“ค Response

{
  "id": "gen-xxx",
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 1289,
    "completion_tokens": 500,
    "total_tokens": 1789
  }
}
โš™ Specs
  • Context Length: 200,000 tokens
  • Model Name: moondev-ai (required in request body)
  • Auth: Authorization: Bearer YOUR_API_KEY header
โš  This Is War

If you're trading with ChatGPT or any generic AI, you're bringing a butter knife to a sword fight. Moon Dev AI was built from the trenches - 5 years of live trading, thousands of backtests, hundreds of bots. No other AI has this edge.

AuthenticationCopy link

All /api/* endpoints require authentication via API key.Need an API key?

Method 1: Query Parameter

?api_key=YOUR_API_KEY

Method 2: Header (Recommended)

X-API-Key: YOUR_API_KEY

Error Response (401)

{
  "error": "Unauthorized",
  "message": "Valid API key required. Use ?api_key=YOUR_KEY or X-API-Key header"
}

Moon Dev MCP ServerCopy link

Ask your AI about live Hyperliquid positions and liquidations in plain English.

The Moon Dev MCP plugs Moon Dev's Hyperliquid data straight into any AI client that speaks MCP (Claude Code, Cursor, Claude Desktop, your own Python script). You ask "who is closest to liquidation on RUNE?" and the AI calls the tool and answers with real wallets, real liquidation prices, and real distances. Nothing to install and no server to run. It is one URL plus your API key.

It is read-only. It can look at data. It can never trade, move money, or touch any wallet.

What you need

  • A Moon Dev API key. Get it from your Moon Dev account. It is the same key the Moon Dev API uses.
  • An MCP client that can send a custom Bearer header. The endpoint has no sign-in screen (no OAuth), so the key goes in a header.
SettingValue
URLhttps://api.moondev.com/mcp
TransportStreamable HTTP
HeaderAuthorization: Bearer YOUR_MOONDEV_API_KEY

No key, or a wrong key, returns HTTP 401.

Keep your key safe

Put the key in an environment variable instead of pasting it into config files:

# add this line to ~/.zshrc or ~/.bashrc, then open a new terminal
export MOONDEV_API_KEY="your_key_here"

Never commit your key to GitHub. Every example below reads it from MOONDEV_API_KEY.

Connect it

Claude Code

One command:

claude mcp add --transport http moondev https://api.moondev.com/mcp \
  --header "Authorization: Bearer $MOONDEV_API_KEY"

Or put it in a .mcp.json file in your project. Claude Code fills in ${MOONDEV_API_KEY} from your environment, so the key never sits in the file:

{
  "mcpServers": {
    "moondev": {
      "type": "http",
      "url": "https://api.moondev.com/mcp",
      "headers": {
        "Authorization": "Bearer ${MOONDEV_API_KEY}"
      }
    }
  }
}

Check it: run claude mcp list and look for moondev. Inside Claude Code, /mcp shows its tools.

Cursor

Open Settings โ†’ MCP โ†’ Add new MCP server, or edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "moondev": {
      "url": "https://api.moondev.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_MOONDEV_API_KEY"
      }
    }
  }
}

Claude Desktop

Claude Desktop cannot send a custom header to a remote server by itself, so use the mcp-remote bridge (needs Node.js). Edit claude_desktop_config.json (Settings โ†’ Developer โ†’ Edit Config):

{
  "mcpServers": {
    "moondev": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://api.moondev.com/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer YOUR_MOONDEV_API_KEY"
      }
    }
  }
}

Restart Claude Desktop after saving.

Any other client

Any client that supports Streamable HTTP plus a custom header works. Use the URL and header from the table at the top. Field names differ a little between clients.

Tools not showing up? Refresh or reconnect the server in your client. Clients cache the tool list.

The tools

There are 3 tools.

1. get_positions: everyone's positions on a coin, closest to liquidation first

The big one. Pass a coin and get the tracked positions on it, sorted by how close they are to getting liquidated.

ArgumentTypeDefaultWhat it does
symbolstringrequiredThe coin. RUNE, BTC, HYPE, or a HIP-3 market like xyz:GOLD. Not case sensitive.
sideall / long / shortallOnly longs, only shorts, or both.
limit1 to 10025How many positions to return.

Each position has:

FieldMeaning
addressFull wallet address
sidelong or short
sizePosition size in coins (negative = short)
valuePosition value in USD
entry_priceWhere they got in
current_pricePrice right now
liq_priceWhere they get liquidated
distance_pctHow far price must move to hit liq_price, in %
leverageTheir leverage
pnlUnrealized profit or loss in USD

The reply also has closest_to_liquidation (the single nearest position), totals for each side (total_longs, total_shorts, total_long_value_usd, total_short_value_usd), and updated_at and price_age_seconds so you know how fresh it is.

Limits, read these:

  • Only positions worth $75,000 or more are tracked.
  • At most the closest 50 longs and 50 shorts per coin are kept.
  • So this is the big money near liquidation, not every wallet. A small coin may only show a few positions.

Real example, RUNE on Oct 4 2026:

{
  "symbol": "RUNE",
  "total_longs": 1,
  "total_shorts": 2,
  "closest_to_liquidation": {
    "address": "0x3596f701162a0bcbad8a5c52127ed02310a4707f",
    "side": "long",
    "size": 146740.9,
    "value": 117232.77,
    "entry_price": 0.5252,
    "current_price": 0.7985,
    "liq_price": 0.4265,
    "distance_pct": 46.58,
    "leverage": 5.0,
    "pnl": 40156.24
  }
}

That long gets liquidated if RUNE falls 46.58%, to $0.4265.

2. get_user_positions: every open position for one wallet

ArgumentTypeWhat it does
addressstringAny Hyperliquid 0x wallet address

Returns account_value, margin_used, and every open position with coin, side, size, entry_price, mark_price, position_value, unrealized_pnl, roe_pct, leverage, liquidation_price, and distance_to_liq_pct.

It is a snapshot of right now, not history. A wallet with nothing open returns an empty positions list. Any public wallet works. Your API key lets you look up any address; it does not prove you own it.

Good wallet to test with (an HLP sub-vault with 100+ positions): 0x010461c14e146ac35fe42271bdc1134ee31c703a

Combo move: use get_positions to find a wallet near liquidation on a coin, then get_user_positions on that wallet to see everything else it holds.

3. get_past_liquidations: liquidation stats and recent events

ArgumentTypeDefaultWhat it does
timeframe10m 1h 4h 12h 24h 2d 7d 14d 30drequiredThe window
limit1 to 10025How many recent events to return

Returns:

  • stats: total count and USD value of liquidations in the window, split long vs short, plus by_coin with the same numbers for every coin.
  • liquidations: the most recent events (time, coin, side, size, price, USD value, pnl).

Know this: the stats cover the whole window you pick. The event list holds at most 100 events, so on a busy market it may only cover the last few minutes even when you ask for 30d. For "how much got liquidated on RUNE this month", read stats.by_coin.RUNE, not the event list.

Things to ask your AI

  • "Use Moon Dev's get_positions tool to show who is closest to liquidation on RUNE."
  • "Show the 5 BTC shorts closest to liquidation."
  • "Which side of HYPE has more money near liquidation, longs or shorts?"
  • "Find the wallet closest to liquidation on ETH, then show me everything that wallet holds."
  • "How much got liquidated in the last 24 hours, and which coin had the most?"
  • "Compare long vs short liquidations over the last 7 days."

Test it without an AI (curl)

Good for checking your key works. In a terminal:

curl -N https://api.moondev.com/mcp \
  -H "Authorization: Bearer $MOONDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_positions","arguments":{"symbol":"RUNE"}}}'

List every tool:

curl -N https://api.moondev.com/mcp \
  -H "Authorization: Bearer $MOONDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The answer comes back on a line that starts with data:. The JSON after it holds the result. result.structuredContent is the clean data.

Use it from Python

import json
import os
import requests

URL = "https://api.moondev.com/mcp"
HEADERS = {
    "Authorization": f"Bearer {os.environ.get('MOONDEV_API_KEY')}",
    "Content-Type": "application/json",
    "Accept": "application/json, text/event-stream",
}

def call_tool(name, arguments):
    body = {"jsonrpc": "2.0", "id": 1, "method": "tools/call",
            "params": {"name": name, "arguments": arguments}}
    r = requests.post(URL, headers=HEADERS, json=body, timeout=30)
    r.raise_for_status()
    line = next(l for l in r.text.splitlines() if l.startswith("data:"))
    result = json.loads(line[5:])["result"]
    if result.get("isError"):
        raise RuntimeError(result["content"][0]["text"])
    return result["structuredContent"]

data = call_tool("get_positions", {"symbol": "RUNE", "limit": 10})
for p in data["positions"]:
    print(f"{p['side']:5} {p['address']}  ${p['value']:,.0f}  " \
          f"liq {p['liq_price']}  {p['distance_pct']}% away")

Errors

You seeWhyFix
HTTP 401Missing or wrong keyCheck the Authorization: Bearer ... header and your key
Unknown tool: ...Tool name typoRun tools/list, or refresh your client
isError: true on get_positionsThe coin isn't tracked or doesn't existCheck the symbol. HIP-3 coins need the dex prefix, like xyz:GOLD
Only 2 tools in your clientCached old tool listReconnect or refresh the MCP server
A coin shows few or no positionsNo positions on it are worth $75k+Normal for small coins

Rate Limits & CachingCopy link

SettingValue
Rate Limit60 requests/second sustained, burst up to 200
Response FormatJSON (Content-Type: application/json)

Health & InfoCopy link

EndpointAuthDescription
GET /healthNoHealth check
GET /NoAPI info and endpoint listing
{"status": "ok", "service": "hyperliquid-data-layer"}

Market DataCopy link

Drop-in replacements for Hyperliquid API calls. All requests go through Moon Dev's local node.

These endpoints replace metaAndAssetCtxs, l2Book, clearinghouseState, userFills, and candleSnapshot.

Prices (All 228 Coins)

EndpointDescription
GET /api/pricesAll prices, funding rates, and OI for 228 coins (replaces metaAndAssetCtxs)
GET /api/price/{coin}Quick single-coin price with bid/ask/spread (e.g., /api/price/BTC)

Orderbook

EndpointDescription
GET /api/orderbook/{coin}L2 orderbook with ~20 levels each side (replaces l2Book)

Account & Fills

EndpointDescription
GET /api/account/{address}Full account state for any wallet (replaces clearinghouseState)
GET /api/fills/{address}?limit=NTrade fills in Hyperliquid-compatible format (replaces userFills)

Fills query parameters (added 2026-08-13)

ParamTypeDescription
startTimeintegerEpoch-ms lower bound โ€” same name and units as HyperLiquid's userFillsByTime, so code written against HL ports directly
minutesnumber, 0โ€“4320Relative form of the same window โ€” only fills from the last N minutes
limitintegerMax fills to return (unchanged; combines with the window)

Passing a time window makes every wallet equally fast (~50ms). See the User Data section for the full fast-lane note and the new 503 fills_scanner_busy semantics.

โš ๏ธ Window size is the performance dial. Small windows (โ‰ค60 min) are the hot path โ€” ~50ms for any wallet. The maximum (minutes=4320, 3 days) is effectively a full-archive scan and can take 30โ€“60s on a cold cache: it's a deep-history call, not a polling call. If you need deep history on a schedule, page through it in smaller windows.

Candles (OHLCV)

EndpointDescription
GET /api/candles/{coin}?interval=1hOHLCV candles (intervals: 1m, 5m, 15m, 1h, 4h, 1d)

All coin symbols are case-insensitive (e.g., BTC, btc, Ada all work).

Candle intervals: 1m, 5m, 15m, 1h, 4h, 1d. Optional query params: start_time and end_time (millisecond timestamps).

Response Example (/api/prices)

{
  "count": 228,
  "timestamp": "2026-01-14T12:00:00Z",
  "prices": {
    "BTC": "94500.50",
    "ETH": "3250.25",
    "SOL": "185.30"
  },
  "funding_rates": {
    "BTC": "0.0001",
    "ETH": "0.00008"
  },
  "open_interest": {
    "BTC": "125000.5",
    "ETH": "850000.2"
  }
}

Response Example (/api/price/BTC)

{
  "coin": "BTC",
  "timestamp": "2026-01-29T15:37:44Z",
  "best_bid": "85324.0",
  "best_ask": "85325.0",
  "best_bid_size": "0.00036",
  "best_ask_size": "5.7609",
  "mid_price": "85324.5",
  "spread": "1.0",
  "spread_bps": 0.12
}

Response Example (/api/orderbook/BTC)

{
  "symbol": "BTC",
  "best_bid": "94500.00",
  "best_ask": "94501.00",
  "mid_price": "94500.50",
  "spread_bps": "0.11",
  "bid_depth": 20,
  "ask_depth": 20,
  "levels": [
    [
      {"px": "94500.0", "sz": "2.5"},
      {"px": "94499.0", "sz": "1.2"}
    ],
    [
      {"px": "94501.0", "sz": "1.8"},
      {"px": "94502.0", "sz": "3.1"}
    ]
  ]
}

Response Example (/api/candles/BTC?interval=1h)

A plain list of candles, oldest first, with Hyperliquid's short keys: t open time, T close time, s coin, i interval, o h l c prices (strings), v volume, n trades. So the latest close is candles[-1]['c'].

[
  {
    "t": 1792929600000,
    "T": 1792933199999,
    "s": "BTC",
    "i": "1h",
    "o": "80557.0",
    "c": "80434.0",
    "h": "80557.0",
    "l": "80295.0",
    "v": "924.58",
    "n": 5902
  }
]

Migration Cheatsheet

Old Hyperliquid CallNew Moon Dev API
{"type": "metaAndAssetCtxs"}GET /api/prices
{"type": "l2Book", "coin": "BTC"}GET /api/orderbook/BTC
{"type": "clearinghouseState", "user": "0x..."}GET /api/account/0x...
{"type": "userFills", "user": "0x..."}GET /api/fills/0x...
{"type": "candleSnapshot", ...}GET /api/candles/BTC?interval=1h

Python Example

import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.moondev.com"
headers = {"X-API-Key": API_KEY}

# Get all prices (replaces metaAndAssetCtxs)
prices = requests.get(f"{BASE_URL}/api/prices", headers=headers).json()
print(f"BTC: ${prices['prices']['BTC']}")
print(f"Loaded {prices['count']} coins")

# Quick price check
btc = requests.get(f"{BASE_URL}/api/price/BTC", headers=headers).json()
print(f"Mid: ${btc['mid_price']} | Spread: {btc['spread_bps']} bps")

# Get orderbook (replaces l2Book)
book = requests.get(f"{BASE_URL}/api/orderbook/BTC", headers=headers).json()
print(f"Best Bid: ${book['best_bid']} | Best Ask: ${book['best_ask']}")

# Get account state (replaces clearinghouseState)
wallet = "0x1234567890abcdef..."
account = requests.get(f"{BASE_URL}/api/account/{wallet}", headers=headers).json()
print(f"Account Value: ${account['marginSummary']['accountValue']}")

# Get candles
candles = requests.get(
    f"{BASE_URL}/api/candles/BTC?interval=1h",
    headers=headers
).json()
print(f"Latest close: ${candles[-1]['c']}")

HL Direct Proxies (Bot Endpoints)Copy link

Low-latency, retry-backed proxies to Hyperliquid's /info endpoint.

Drop-in replacements for info.open_orders() and info.clearinghouseState() that eliminate 429s on repeated polls. Both endpoints try Moon Dev's local HL node first and transparently fall back to api.hyperliquid.xyz on failure.

Common Notes

  • address is case-insensitive; 0x prefix optional. Works for wallets, sub-accounts, and vaults.
  • Numeric values are returned as strings (HL native format) โ€” cast client-side.
  • timestamp is ms since epoch (int).
  • source is "local" (HL local node) or "public" (public-API fallback).
  • Freshness: ~1โ€“2s from a fill on local; +~1s on fallback.
  • A 200 always means the data is real โ€” never a silent zero/empty from upstream failure. Both endpoints return 502 on total upstream failure instead of an empty body.

GET /api/hl/clearinghouse/{address}

Alias of /api/account/{address}. Returns the exact same body โ€” use whichever name you prefer.

WhereNameTypeDefaultNotes
pathaddressstringโ€”Wallet / sub-account / vault
querydexstring""Optional perp dex name. Empty = main perp.

Response (200)

{
  "address": "0xdfc24b077bc1425ad1dea75bcb6f8158e10df303",
  "timestamp": 1781703404216,
  "marginSummary": {
    "accountValue": "241896794.51",
    "totalNtlPos": "...",
    "totalRawUsd": "...",
    "totalMarginUsed": "..."
  },
  "crossMarginSummary": {
    "accountValue": "...",
    "totalNtlPos": "...",
    "totalRawUsd": "...",
    "totalMarginUsed": "..."
  },
  "crossMaintenanceMarginUsed": "0.0",
  "withdrawable": "0.0",
  "assetPositions": [
    {
      "type": "oneWay",
      "position": {
        "coin": "BTC",
        "szi": "0.001",
        "entryPx": "93210.0",
        "positionValue": "...",
        "unrealizedPnl": "...",
        "returnOnEquity": "0.0123",
        "leverage": { "type": "isolated", "value": 10 },
        "liquidationPx": "...",
        "marginUsed": "...",
        "maxLeverage": 40,
        "cumFunding": { "allTime": "...", "sinceOpen": "...", "sinceChange": "..." }
      }
    }
  ],
  "source": "local"
}

A genuinely flat account returns 200 with accountValue: "0.0" and assetPositions: [].

Errors

CodeWhen
401Missing / invalid API key
502Both local node and public HL upstream failed. Body: {"detail":{"error":"Upstream Failure","message":"..."}}

Examples

curl -H "X-API-Key: $KEY" \
  "https://api.moondev.com/api/hl/clearinghouse/0xdfc24b077bc1425ad1dea75bcb6f8158e10df303"
import requests

r = requests.get(
    f"https://api.moondev.com/api/hl/clearinghouse/{addr}",
    headers={"X-API-Key": KEY},
    timeout=5,
)
r.raise_for_status()
state = r.json()
account_value = float(state["marginSummary"]["accountValue"])

GET /api/hl/open_orders/{address}

Drop-in replacement for info.open_orders(address). Returns all resting orders for the address.

WhereNameTypeDefaultNotes
pathaddressstringโ€”Wallet / sub-account / vault
querycoinstring""Optional server-side filter (e.g. BTC). Case-insensitive.

Response (200)

{
  "address": "0xc71cc6f1d8b6d1b0ee55cfc70cd210b2bd1bc506",
  "timestamp": 1781704744647,
  "orders": [
    {
      "coin": "BTC",
      "oid": 123456789,
      "side": "B",
      "limitPx": "93000.0",
      "sz": "0.001",
      "origSz": "0.001",
      "timestamp": 1781700000000,
      "reduceOnly": false,
      "orderType": "Limit",
      "tif": "Gtc",
      "cloid": null
    }
  ],
  "source": "local"
}

When the account is genuinely flat, orders is [] and the status is still 200 โ€” use that as the signal to skip cancel loops. Minimum fields the bot needs: coin and oid.

Errors

CodeWhen
401Missing / invalid API key
502Both local node and public HL upstream failed. Never a silent [] on failure.

Examples

# All open orders
curl -H "X-API-Key: $KEY" \
  "https://api.moondev.com/api/hl/open_orders/0xC71CC6f1d8B6D1b0ee55cfc70CD210b2bd1BC506"

# Only BTC
curl -H "X-API-Key: $KEY" \
  "https://api.moondev.com/api/hl/open_orders/0xC71CC6f1d8B6D1b0ee55cfc70CD210b2bd1BC506?coin=BTC"
import requests

r = requests.get(
    f"https://api.moondev.com/api/hl/open_orders/{addr}",
    headers={"X-API-Key": KEY},
    params={"coin": "BTC"},
    timeout=5,
)
r.raise_for_status()
oids = [o["oid"] for o in r.json()["orders"]]

SDK Migration Cheatsheet

HL SDK callReplace with
info.user_state(address)GET /api/hl/clearinghouse/{address} (or /api/account/{address})
info.open_orders(address)GET /api/hl/open_orders/{address}
info.spot_user_state, info.portfolio, info.user_fills_by_time, info.meta, info.spot_meta, perpDexs, activeAssetData, perpsAtOpenInterestCapPOST /api/hl/info with the same body (see below)

No behaviour change โ€” same field names, same string-typed values, same shape.

POST /api/hl/info, Hyperliquid info reads from Moon Dev's nodeCopy link

Send the same JSON body you would send to Hyperliquid's /info endpoint and get Hyperliquid's JSON back. Most reads are answered by Moon Dev's own Hyperliquid node, so they use none of your Hyperliquid rate limit (Hyperliquid allows 1,200 weight per minute per IP and most of these reads cost 20 weight each there). Request and response formats are identical to Hyperliquid's, so any bot, or the official Hyperliquid Python SDK, can switch over by changing the base URL.

curl -X POST https://api.moondev.com/api/hl/info \
  -H 'X-API-Key: YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"type":"spotClearinghouseState","user":"0xYOUR_ADDRESS"}'

{"balances":[{"coin":"USDC","token":0,"total":"99.121993","hold":"83.10294","entryNtl":"0.0"}],
 "tokenToAvailableAfterMaintenance":[[0,"98.083207"]]}
URLPOST https://api.moondev.com/api/hl/info
AuthX-API-Key: YOUR_KEY, or Authorization: Bearer YOUR_KEY, or ?api_key=YOUR_KEY
BodyHyperliquid's /info request body (JSON), at most 2 KB
ResponseHyperliquid's /info response, unchanged

Supported reads

WhatRequest bodyFresh to withinSource
Spot balances{"type":"spotClearinghouseState","user":"0x..."}~1 sMoon Dev node
Leverage + max trade size for a coin{"type":"activeAssetData","user":"0x...","coin":"BTC"}~1 sMoon Dev node
Coins at their open interest cap{"type":"perpsAtOpenInterestCap"} or add "dex":"xyz"~2 sMoon Dev node
Perp market list{"type":"meta"} or add "dex":"xyz"~60 sMoon Dev node
Spot market list{"type":"spotMeta"}~60 sMoon Dev node
HIP-3 dex list{"type":"perpDexs"}~60 sMoon Dev node
Portfolio (PnL, account value, volume){"type":"portfolio","user":"0x..."}~5 minHyperliquid, cached by Moon Dev
Your fills since a time{"type":"userFillsByTime","user":"0x...","startTime":ms}, optional "endTime":mslive (~1 s)Moon Dev node

โ€œFresh to withinโ€ is how long an identical request may be answered from cache. Market lists rarely change, so a minute is safe. HIP-3 markets work everywhere: use "dex":"xyz" for a dex and the full name, for example "coin":"xyz:TSLA", for a coin. Any other type returns 400. user must be a full 0x address (40 hex characters), only the fields shown for each type are accepted, and the body can be at most 2 KB.

Example responses (shortened)

// activeAssetData
{"user":"0x1d3e...9e5d","coin":"BTC","leverage":{"type":"cross","value":1},
 "maxTradeSzs":["0.00232","0.0002"],"availableToTrade":["181.88568","15.6798"],"markPx":"78399.0"}

// perpsAtOpenInterestCap: a plain list of coin names
["CANTO","FTM","JELLY","LOOM","RLB","VINE","ZEREBRO"]

// meta
{"universe":[{"szDecimals":5,"name":"BTC","maxLeverage":40,"marginTableId":56},
             {"szDecimals":4,"name":"ETH","maxLeverage":25,"marginTableId":55}, ...],
 "marginTables":[...]}

// perpDexs: the first entry is null (the main dex)
[null,{"name":"xyz","fullName":"XYZ","deployer":"0x8880...0888", ...}, ...]

// spotMeta
{"universe":[{"tokens":[1,0],"name":"PURR/USDC","index":0,"isCanonical":true}, ...],"tokens":[...]}

Portfolio

curl -X POST https://api.moondev.com/api/hl/info \
  -H 'X-API-Key: YOUR_KEY' -H 'Content-Type: application/json' \
  -d '{"type":"portfolio","user":"0xYOUR_ADDRESS"}'

One call returns all 8 windows, exactly as Hyperliquid sends them. Each window has accountValueHistory and pnlHistory (lists of [timestamp_ms, "value"]) and vlm (volume).

[
  ["day",     {"accountValueHistory":[[1793713260000,"100.31"], ...],
               "pnlHistory":[[1793713260000,"0.0"], ...],
               "vlm":"0.0"}],
  ["week",    {...}],
  ["month",   {...}],
  ["allTime", {...}],
  ["perpDay", {...}], ["perpWeek", {...}], ["perpMonth", {...}], ["perpAllTime", {...}]
]

day, week, month and allTime cover the whole account (perps + spot). The perp* windows cover perps only.

How portfolio is served: our node cannot produce portfolio, so Moon Dev fetches it from Hyperliquid once per address every 5 minutes and serves that copy to everyone who asks. Polling every 30 s is fine. Extra headers on portfolio answers:

HeaderMeaning
X-MD-Sourcehyperliquid (just fetched), hyperliquid-cache (within 5 min), hyperliquid-stale (Hyperliquid was unavailable, so this is the last good copy, up to 30 min old)
AgeSeconds since the answer was fetched from Hyperliquid
  • The last point in each history is โ€œnowโ€ at fetch time, so it can be up to 5 minutes old. Hyperliquid's own answer changes on every call for the same reason.
  • New address limit: each key can trigger fetches for at most 10 new (uncached) addresses per minute. Beyond that you get 429 portfolio_fetch_limit with Retry-After. Addresses that are already cached are never limited.

Fills (userFillsByTime)

curl -X POST https://api.moondev.com/api/hl/info \
  -H 'X-API-Key: YOUR_KEY' -H 'Content-Type: application/json' \
  -d '{"type":"userFillsByTime","user":"0xYOUR_ADDRESS","startTime":1793800000000}'

You get the same JSON as Hyperliquid: a list of fills, oldest first, at most 2,000 per call.

[{"coin":"xyz:TSLA","px":"376.84","sz":"0.71","side":"B","time":1793801160123,"startPosition":"0.0",
  "dir":"Open Long","closedPnl":"0.0","hash":"0x...","oid":594448767657,"crossed":true,
  "fee":"0.0124","tid":81234567,"feeToken":"USDC","twapId":null}, ...]
  • startTime must be within the last 6 hours. Older windows return 422 range_not_covered; ask Hyperliquid for those.
  • endTime is optional and defaults to now.
  • Paging: if you get 2,000 fills, call again with startTime set to the last fill's time, and drop the boundary fill you already have.
  • aggregateByTime: true is not supported (returns 422 aggregate_not_served).
  • We return more history than Hyperliquid for very busy accounts. Hyperliquid only keeps each account's most recent 10,000 fills; we return every fill in your window.
  • This read uses none of your Hyperliquid rate limit.

SDK: info.user_fills_by_time("0xYOUR_ADDRESS", start_ms). Leave aggregate_by_time off.

Using it with the Hyperliquid Python SDK

The SDK makes its first requests inside Info(...), before you could set a header, so attach the key in post:

from hyperliquid.info import Info

MOONDEV_KEY = "YOUR_KEY"

class MoonDevInfo(Info):
    def post(self, url_path, payload=None):
        self.session.headers["X-API-Key"] = MOONDEV_KEY
        return super().post(url_path, payload)

info = MoonDevInfo(base_url="https://api.moondev.com/api/hl", skip_ws=True)
# include HIP-3 dexes:  MoonDevInfo(..., skip_ws=True, perp_dexs=["", "xyz"])

info.spot_user_state("0xYOUR_ADDRESS")       # spotClearinghouseState
info.portfolio("0xYOUR_ADDRESS")             # portfolio
info.user_fills_by_time("0xYOUR_ADDRESS", start_ms)   # userFillsByTime
info.meta()                                   # meta
info.meta(dex="xyz")                          # HIP-3 meta
info.spot_meta()                              # spotMeta
info.post("/info", {"type": "perpDexs"})
info.post("/info", {"type": "activeAssetData", "user": "0xYOUR_ADDRESS", "coin": "xyz:TSLA"})
info.post("/info", {"type": "perpsAtOpenInterestCap", "dex": "xyz"})
  • skip_ws=True is required. Websocket subscriptions are not served here, keep those on Hyperliquid.
  • Point only Info here, never Exchange. Orders, cancels and leverage changes go to Hyperliquid.
  • Only the reads listed above work. Other SDK methods, such as user_state, all_mids, l2_snapshot and meta_and_asset_ctxs, raise ClientError(400, "type_not_served"). Use a second, normal Info() pointed at Hyperliquid for those.
  • Very old SDK versions (for example 0.22) crash inside Info() on today's spot market data, even when pointed at Hyperliquid itself. Upgrade with pip install -U hyperliquid-python-sdk.

Plain Python and JavaScript

import requests
r = requests.post("https://api.moondev.com/api/hl/info",
                  headers={"X-API-Key": "YOUR_KEY"},
                  json={"type": "activeAssetData", "user": "0xYOUR_ADDRESS", "coin": "xyz:TSLA"},
                  timeout=10)
lev = r.json()["leverage"]        # {"type": "cross", "value": 20}
const r = await fetch("https://api.moondev.com/api/hl/info", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ type: "portfolio", user: "0xYOUR_ADDRESS" }),
});
const windows = Object.fromEntries(await r.json());   // windows.day.pnlHistory, ...

Rate limit

300 calls per minute per API key on this endpoint, all types combined. The count resets at the top of each minute. Your key's normal overall limit still applies too. Portfolio also has its own new address limit (see Portfolio above). Over the limit: 429 with a Retry-After header (seconds). Every response includes:

HeaderMeaning
X-RateLimit-LimitCalls allowed per minute (300)
X-RateLimit-RemainingCalls left this minute
X-RateLimit-ResetSeconds until the count resets
X-MD-Sourcenode / node-cache for node reads; hyperliquid / hyperliquid-cache / hyperliquid-stale for portfolio

Errors

Error bodies look like {"error": "...", "code": "...", "msg": "..."}. Every error response also carries the code in an X-MD-Error header.

StatuserrorMeaningWhat to do
400type_not_servedtype isn't one of the supported readsAsk Hyperliquid directly
400bad_coinNot a perp coin on the main dex or any HIP-3 dex (spot names like @107 aren't valid for activeAssetData)Use names like BTC or xyz:TSLA
400bad_fields, bad_user, bad_dex, body_not_json, body_not_objectMalformed requestFix the request
401Missing or invalid API keyCheck your key
413body_too_largeBody over 2 KB
429rate_limitedOver 300 calls this minuteWait Retry-After seconds
429portfolio_fetch_limitToo many new portfolio addresses this minuteWait Retry-After seconds
422range_not_covereduserFillsByTime window starts more than 6 hours agoSend that request to Hyperliquid
422aggregate_not_servedaggregateByTime: true isn't supportedSend that request to Hyperliquid
503node_unavailable, node_errorNode down, slower than 3 s, or failedAsk Hyperliquid for Retry-After seconds (60)
503hyperliquid_unavailable, hyperliquid_bad_answerPortfolio couldn't be fetched and no recent copy existsAsk Hyperliquid for Retry-After seconds (60)
503portfolio_busyAnother request for the same address is still being fetchedRetry after Retry-After seconds (5)
503fills_busyThe fill scanner is busyRetry after Retry-After seconds (5), or ask Hyperliquid

Every 503 includes a Retry-After header. This endpoint never returns 502 or 504 itself. If you see one, it came from the network in between, so treat it like a 503 with a 60 second wait.

Daily maintenance: the node restarts once a day around 04:15 New York time, for about 2 minutes. Expect 503 on node reads then. Portfolio is unaffected.

Recommended fallback pattern

import time, requests

MOONDEV = "https://api.moondev.com/api/hl/info"
HL = "https://api.hyperliquid.xyz/info"
KEY = "YOUR_KEY"
_skip_until = 0

def hl_info(body):
    global _skip_until
    if time.time() >= _skip_until:
        try:
            r = requests.post(MOONDEV, json=body, headers={"X-API-Key": KEY}, timeout=10)
            if r.status_code == 200:
                return r.json()
            if r.status_code == 400:
                r.raise_for_status()                      # our request is wrong; don't retry elsewhere
            if r.status_code in (429, 503):
                _skip_until = time.time() + int(r.headers.get("Retry-After", 60))
            elif r.status_code >= 500:                    # 502/504 from the network in between
                _skip_until = time.time() + 60
        except requests.ConnectionError:
            _skip_until = time.time() + 60
        except requests.Timeout:
            _skip_until = time.time() + 60
    return requests.post(HL, json=body, timeout=10).json()

Not available here: metaAndAssetCtxs (mark price, funding, open interest and 24h volume per coin), all trading actions, and every other /info type. Read those from Hyperliquid.

Node reads usually run about 1 second behind Hyperliquid's public API. That is fine for balances, leverage checks and market lists, but do not use it for latency critical prices.

Core DataCopy link

Built on these endpoints

Kill Zone
Kill Zone/api/positions.jsonCopy link

Every position under 1% from its liquidation price right now: size, leverage, liq price, distance and PnL. The top 100 near liq list, filtered down to the ones about to go.

Kill List
Kill List/api/positions.jsonCopy link

The closest positions to liquidation ranked by distance, with a heat bar per row and the whale rows pulled out at the bottom. Straight off the top 50 longs and 50 shorts list.

Liq Countdown
Liq Countdown/api/positions.jsonCopy link

Leverage to liquidation bars for the next positions to blow, crypto and HIP3 side by side. 12,073 positions tracked at the time of the screenshot.

Fuel Map
Fuel Map/api/positions/all.jsonCopy link

How much position value sits 1%, 2% and 5% below and above the price on each coin, so you can see where a move would find fuel. Built from the per symbol top 50 lists.

Fuel Butterfly
Fuel Butterfly/api/positions/all.jsonCopy link

Near liquidation dollars per coin, longs on the left and shorts on the right, with the short to long ratio. BTC alone had $1.30B of longs and $1.46B of shorts near liq here.

Liq Ladder (cumulative)
Liq Ladder (cumulative)/api/positions/all.jsonCopy link

BTC liquidation levels every 0.2% from price with the running total at each step and the leverage behind it. The bottom rows show where the big longs sit.

Liq Ladder
Liq Ladder/api/positions/all.jsonCopy link

The same ladder as plain bars: short liquidations above price, long liquidations below, dollars at each level.

Liq Map
Liq Map/api/positions/all.jsonCopy link

The 50 nearest positions each side of BTC grouped into price levels, with the whale sized ones marked. $385.8M of shorts above and $477.1M of longs below in this shot.

EndpointDescription
GET /api/positions.jsonThe 50 longs and 50 shorts closest to liquidation across ALL symbols, crypto + HIP3 combined. $75k minimum position, 100 positions total (~1s updates)
GET /api/positions_crypto.jsonSame list, crypto perps only (BTC, ETH, SOL, โ€ฆ). $75k minimum, 100 positions
GET /api/positions_hip3.jsonSame list, HIP3 only (xyz:GOLD, cash:USA500, โ€ฆ). $75k minimum, 100 positions
GET /api/positions/all.jsonEvery symbol (300+ today: 139 crypto + 163 HIP3) with its own top 50 longs and shorts โ€” combined (full scan every ~2 min)
GET /api/positions/all_crypto.jsonEvery crypto symbol (139 today) with top 50 longs and shorts each
GET /api/positions/all_hip3.jsonEvery HIP3 symbol (163 today, all dexes) with top 50 longs and shorts each
GET /api/positions/majors.jsonAll positions โ‰ฅ $10M within 50% of liquidation โ€” every symbol, uncapped (~2 min updates)
GET /api/whales.jsonRecent whale trades ($25k+, buys & sells)
GET /api/buyers.jsonRecent buyers only ($5k+, HYPE/SOL/XRP/ETH)
GET /api/depositors.jsonAll Hyperliquid depositors - canonical address list
GET /api/whale_addresses.txtPlain text list of whale addresses

Crypto / HIP3 Position Separation

Position data is now available in separate crypto and HIP3 feeds in addition to the existing combined files. Classification rule: any coin with a : in its name (e.g. xyz:GOLD, cash:USA500) is HIP3. All others (e.g. BTC, ETH) are crypto.

FilePositions trackedListedSymbols scanned
positions.json (combined)~11,800100 (50 longs + 50 shorts)302
positions_crypto.json~7,900100139
positions_hip3.json~3,900100163

Floor: every top-50 list only ranks positions worth $75,000 or more (the min_position_value field in the response). Smaller positions are still tracked and show up in the per-symbol all*.json files, where each symbol block carries its own min_position_value.

List cap: the top-50 files hold 100 positions total (50 longs + 50 shorts) across all coins, so on a busy day a coin can have zero entries there while its all*.json block has 50 and 50.

Update frequency: Top-50 files (positions*.json) update every ~1s via priority scan. Per-symbol files (all*.json) and majors.json update on the full scan, which takes about 2 minutes (1.9 min measured) across all 300+ symbols. Original endpoints are unchanged โ€” fully backward compatible.

Majors Feed โ€” Whale Watching (NEW โ€” added 2026-08-14)

GET /api/positions/majors.json โ€” all positions โ‰ฅ $10M within 50% of liquidation, across every symbol, uncapped. Same schema as all.json. Use this for whale-watching: unlike the top-50 near-liq lists (which rank purely by proximity and can rotate large positions out as smaller ones get closer), a position never leaves this feed while it exceeds $10M. Updated with the full scan, about every 2 minutes.

Response Example (positions_crypto.json)

{
  "updated_at": "2026-10-20T16:13:41.447080+00:00",
  "total_positions": 7937,
  "total_longs": 50,
  "total_shorts": 50,
  "min_position_value": 75000,
  "price_source": "websocket",
  "longs": [
    {
      "address": "0x...",
      "coin": "BTC",
      "value": 1250000.50,
      "entry_price": 85000.0,
      "current_price": 86500.0,
      "liq_price": 82000.0,
      "distance_pct": 5.20,
      "leverage": 10.0,
      "size": 14.705882,
      "pnl": 22058.82
    }
  ],
  "shorts": [ ... ]
}

longs and shorts are sorted by distance_pct ascending (closest to liquidation first). Each array contains up to 50 positions.

Response Example (all_crypto.json)

{
  "updated_at": "2026-10-20T16:13:42.901856+00:00",
  "min_position_value": 75000,
  "total_symbols": 139,
  "symbols": {
    "BTC": {
      "total_positions": 892,
      "total_longs": 510,
      "total_shorts": 382,
      "total_long_value": 450000000.00,
      "total_short_value": 280000000.00,
      "longs": [ ... ],
      "shorts": [ ... ]
    },
    "ETH": { ... }
  }
}

Symbols are sorted by total_positions descending. Each symbol contains up to 50 longs + 50 shorts.

Whale Watcher Expansion: 75 Symbols

Whale discovery now watches 75 symbols across native perps and HIP-3 dexes (previously 3). Whale threshold: $25,000+ per trade.

CategoryCountExamples
Always-watch (native perps)7BTC, ETH, SOL, HYPE, XRP, ZEC, FARTCOIN
Top volume (native perps)23PAXG, PUMP, SUI, DOGE, ASTER, LINK, XMR, MON, BNB, kPEPE, UNI, ENA, ...
HIP-3 Commodities14xyz:SILVER, xyz:GOLD, xyz:COPPER, xyz:CL, xyz:NATGAS, flx:OIL, ...
HIP-3 Indices8xyz:XYZ100, cash:USA500, km:USTECH, vntl:MAG7, vntl:SEMIS, vntl:ROBOT
HIP-3 Stocks18xyz:TSLA, xyz:NVDA, xyz:GOOGL, xyz:PLTR, xyz:META, xyz:AAPL, cash:NVDA, ...
HIP-3 FX2xyz:EUR, xyz:JPY
HIP-3 Pre-IPO3vntl:SPACEX, vntl:OPENAI, vntl:ANTHROPIC

HIP-3 perps live on separate dexes within Hyperliquid. Symbol format: dex:NAME (e.g., xyz:SILVER, cash:USA500). Whale addresses discovered from HIP-3 trades are added to the same whale address pool.

Position Scanner: 200 Threads

All 22,500+ discovered whale wallets are scanned continuously. Position tracking is wallet-based โ€” calling clearinghouseState for a wallet returns all positions across both native perps and HIP-3 markets automatically. No per-symbol config needed.

  • 200 scan threads (full wallet scans)
  • 30 priority threads (fast updates for top positions)
  • Adding more watched symbols increases the whale address pool over time, not the per-wallet scan cost

Response Example (depositors.json)

{
  "updated_at": "2026-01-14T12:00:00Z",
  "stats": {
    "total_count": 125000,
    "total_deposited": 2500000000
  },
  "depositors": [
    {
      "address": "0x1234567890abcdef...",
      "amount": 50000,
      "timestamp": "2026-01-14T11:30:00Z"
    }
  ]
}

The depositors endpoint contains every wallet that has ever bridged USDC to Hyperliquid - the canonical address list.

TrendersCopy link

NEW โ€” added 2026-10-20

A ready made trend scan over every Hyperliquid market (341 discovered today: all crypto perps plus all 163 HIP3 markets across 10 dexes) on 4 hour candles. Any trader building a trenders dashboard has to pull candles for every market, about 330 Hyperliquid calls per refresh, and that traffic eats the same rate limit your live bots run on. This endpoint runs the scan once on our side and hands you the finished lists in one call, so your bots keep the whole rate limit for themselves. The candles are built from our own node's trade records, each trade counted once, and match Hyperliquid's own 4h candles exactly on open, high, low, close and volume (30 of 30 test bars identical, crypto and HIP3). See it live in the ticker at the top of moondev.com/hyperliquid.

EndpointDescription
GET /api/trenders/latest.jsonThe scan: trenders up and down, fresh breakouts and breakdowns, 7 day gainers and losers, confluence (crypto, HIP3, down), HIP3 7 day supply and demand zones. Refreshes every 15 minutes.
GET /api/trenders/all.jsonEvery scored symbol's full metrics row (same fields as the lists above). Refreshes every 15 minutes.

Needs your normal API key (?api_key= or X-API-Key). No key returns 401.

Top level fields

FieldMeaning
updated_atWhen the scan last ran (UTC)
intervalCandle size the scan runs on, 4h
history_completefalse while a market is still filling its 15 days of history. Markets without enough bars are left out of the lists rather than guessed.
symbols_discovered / symbols_scored / symbols_liquidMarkets found, markets with enough history to score, markets above the volume floor
min_24h_volume_usdVolume floor for the lists ($500k 24h quote volume)
droppedMarkets left out and why (e.g. no_data)
trenders_up / trenders_downTrending markets by direction
fresh_breakouts / fresh_breakdownsDonchian channel breaks within the last bars
movers_up_7d / movers_dn_7d7 day gainers and losers
confluence / confluence_crypto / confluence_hip3 / confluence_downMarkets where several signals agree, each row wrapped as { row, ... }
hip3_supply_zone_7d / hip3_demand_zone_7dHIP3 markets sitting at the top or bottom of their 7 day range

Per symbol row (all.json rows, and every list entry)

{
  "symbol": "BTC",
  "venue": "crypto",            // crypto or hip3
  "price": 82560.0,
  "pct_24h": 0.876,             // % change over 24h
  "pct_7d": -0.853,             // % change over 7 days
  "adx": 28.6,                  // trend strength
  "dd_24h": 2.56,               // drawdown over 24h, %
  "max_dd_7d": 5.20,            // worst drawdown over 7 days, %
  "dd_ret_ratio": 6.10,         // drawdown to return ratio
  "roc": 1.25,                  // rate of change
  "mom_atr": 1.29,              // momentum in ATR units
  "ema_align": 33.3,            // % of EMAs stacked in trend order
  "donch_breakout_up": false,
  "donch_breakout_dn": false,
  "donch_break_age": 1,         // bars since the last Donchian break
  "above_bb_upper": false,
  "below_bb_lower": false,
  "vol_ratio": 0.013,           // current 4h volume vs its average
  "quote_vol_4h": 4219236.23,
  "quote_vol_24h": 2278454777.52,
  "high_7d": 84103.0,
  "low_7d": 79732.0,
  "rng_pos_7d": 64.7,           // where price sits in the 7 day range, 0 = low, 100 = high
  "bars": 90                    // 4h bars of history used
}

Python

import os, requests

KEY = os.environ["MOONDEV_API_KEY"]
scan = requests.get("https://api.moondev.com/api/trenders/latest.json",
                    params={"api_key": KEY}, timeout=10).json()

print(f"scored {scan['symbols_scored']} of {scan['symbols_discovered']} markets "
      f"(history complete: {scan['history_complete']})")
for r in scan["trenders_up"]:
    print(f"UP   {r['symbol']:14} {r['venue']:6} 24h {r['pct_24h']:+.1f}%  7d {r['pct_7d']:+.1f}%  adx {r['adx']:.0f}")
for r in scan["fresh_breakouts"]:
    print(f"BRK  {r['symbol']:14} broke out {r['donch_break_age']} bars ago")

# every symbol's full row
rows = requests.get("https://api.moondev.com/api/trenders/all.json",
                    params={"api_key": KEY}, timeout=10).json()["rows"]
strong = [r for r in rows if r["adx"] > 25 and r["ema_align"] == 100]
print(len(strong), "markets fully aligned with ADX over 25")

Good to know

  • History: each market needs 15 days of 4h bars before it is scored. New listings show up once they have the bars; until then history_complete is false and they are left out.
  • Indicators follow the current pandas_ta formulas (ADX, EMAs, Donchian, Bollinger, ATR). Readings should match a local pandas_ta run closely; an older local version may differ by a hair.
  • Delisted markets drop out of the scan (PAPER, for example).
  • Load: the scan runs in the background once a minute on the node's data and publishes every 15 minutes. It makes no Hyperliquid API calls once history is loaded, so it never competes with your rate limit.

OHLCV Candles v2 (10 second bars)Copy link

NEW: added 2026-10-24

Open, high, low, close and volume for every Hyperliquid market (3,220 today: 178 crypto perps, 164 HIP3, 150 spot and 2,728 outcome markets) down to 10 second bars. Hyperliquid itself only goes down to 1 minute, and only keeps a few days of it. Every bar also splits volume into buy and sell volume, plus dollar volume and trade count. The bars are built from our own node's trade records and match Hyperliquid's own candles exactly on open, high, low, close, volume and trade count (we checked BTC, ETH, SOL, HYPE, two HIP3 markets, a spot market and an outcome market: every bar identical). History starts 2026-10-21 and grows from there. Pages of up to 10,000 bars come back in about 50 to 150 ms.

EndpointDescription
GET /api/candles/v2/{coin}?interval=10sBars for one market. Intervals: 10s, 30s, 1m, 5m, 15m, 30m, 1h, 4h, 1d. Up to 10,000 bars per page.
GET /api/candles/v2/symbolsEvery market we hold bars for, with its type (perp, hip3, spot, outcome) and its first and last bar
GET /api/candles/v2/statusFreshness (data_through, lag_seconds), history start, the page cap per interval, and any gaps

Needs your normal API key (?api_key= or X-API-Key). No key returns 401. Add format=csv for CSV instead of JSON.

Query parameters

ParamMeaning
intervalBar size: 10s, 30s, 1m, 5m, 15m, 30m, 1h, 4h, 1d
limitBars per page, up to 10,000 (6,666 on 30m and 8,333 on 1d; /status lists the exact cap)
endPage backward from this time (ms). The default with no start or end is the newest bars.
startPage forward from this time (ms)
formatjson (default) or csv

Coin names

MarketExampleIn the URL
Crypto perpBTC/api/candles/v2/BTC
HIP3xyz:CL/api/candles/v2/xyz:CL
Spot@1/api/candles/v2/@1
Outcome (prediction)#149380/api/candles/v2/%23149380 (write # as %23)

Response (/api/candles/v2/BTC?interval=10s&limit=2)

{
  "coin": "BTC",
  "market_type": "perp",
  "interval": "10s",
  "count": 2,
  "bars": [
    {
      "t": 1792800940000,    // bar open time, ms UTC
      "o": 80961.0,          // open
      "h": 80961.0,          // high
      "l": 80941.0,          // low
      "c": 80941.0,          // close
      "v": 0.31444,          // volume (coins)
      "bv": 0.02976,         // buy volume (taker buys)
      "sv": 0.28468,         // sell volume (taker sells), bv + sv = v
      "qv": 25453.31016,     // dollar volume
      "n": 23                // trade count
    },
    ...
  ],
  "prev_end": 1792800940000,   // pass as end= for the page before this one (null = no more)
  "next_start": null,          // pass as start= for the page after this one (null = no more)
  "has_more": true,
  "data_through": 1792800961458,
  "last_bar_complete": false,  // the newest bar is still filling
  "coin_first_bar": 1792540800000,
  "history_start": 1792540800000
}

Python: pull all the 10 second history for one market

import os, requests

KEY = os.environ["MOONDEV_API_KEY"]
URL = "https://api.moondev.com/api/candles/v2/BTC"

bars, end = [], None
while True:
    params = {"interval": "10s", "limit": 10000, "api_key": KEY}
    if end:
        params["end"] = end
    page = requests.get(URL, params=params, timeout=30).json()
    bars = page["bars"] + bars          # each page is older than the last
    end = page["prev_end"]
    if end is None:
        break

print(len(bars), "bars from", bars[0]["t"], "to", bars[-1]["t"])
last = bars[-1]
print(f"close {last['c']}  buy vol {last['bv']}  sell vol {last['sv']}  trades {last['n']}")

curl

# newest 10,000 ten second BTC bars
curl "https://api.moondev.com/api/candles/v2/BTC?interval=10s&limit=10000&api_key=YOUR_KEY"

# 4h crude oil (HIP3) as CSV
curl "https://api.moondev.com/api/candles/v2/xyz:CL?interval=4h&format=csv&api_key=YOUR_KEY"

# forward from a date: keep passing next_start as start until it is null
curl "https://api.moondev.com/api/candles/v2/ETH?interval=1m&start=1792540800000&api_key=YOUR_KEY"

Good to know

  • No trades, no bar: an interval with zero trades is skipped instead of sent as a flat bar. Hyperliquid sends a flat candle with n: 0 there. On quiet markets (most spot and outcome markets) fill those gaps yourself by carrying the last close forward.
  • Freshness: bars update every minute, about a minute behind real time. last_bar_complete tells you if the newest bar is still filling.
  • History: starts 2026-10-21 00:00 UTC for every market and keeps growing. Settled outcome markets stay available after Hyperliquid stops serving them.
  • Errors: a bad interval returns 400, an unknown coin 404 (check /symbols). If the server is busy with big history pulls you may get a retry in a few seconds response; wait and try again.
  • The old endpoint /api/candles/{coin} still works the same. v2 is the one to use for 10s and 30s bars, buy and sell volume, and every market type.

Tick DataCopy link

Historical tick data for all 129 tracked symbols.

โš ๏ธ IMPORTANT: Symbols MUST be lowercase. BTC.json returns 404. Use btc.json

Available symbols (lowercase only):

0g, 2z, aave, ace, ada, aero, aixbt, apex, apt, ar, arb, aster, atom, avax, avnt, axs, banana, bch, bera, bio, blast, blur, bnb, btc, cake, cc, celo, crv, dash, doge, dot, eigen, ena, eth, ethfi, fartcoin, fet, fil, fogo, gas, grass, hbar, hemi, hmstr, hype, icp, init, inj, io, ip, jto, jup, kaito, layer, ldo, linea, link, lit, ltc, manta, me, mega, melania, meme, merl, met, mina, mnt, mon, moodeng, morpho, move, near, ondo, op, ordi, paxg, pendle, pengu, pol, popcat, prompt, pump, purr, pyth, render, resolv, rune, s, saga, sand, sei, skr, sky, sol, spx, stable, stbl, strk, stx, sui, super, syrup, tao, tia, ton, trump, trx, uni, virtual, vvv, wct, wif, wld, wlfi, xai, xlm, xmr, xpl, xrp, zec, zen, zerebro, zeta, zk, zro, kbonk, kpepe, kshib

EndpointExampleDescription
GET /api/ticks/{symbol}.json/api/ticks/btc.jsonCurrent/latest ticks
GET /api/ticks/{symbol}_10m.json/api/ticks/btc_10m.jsonLast 10 minutes
GET /api/ticks/{symbol}_1h.json/api/ticks/btc_1h.jsonLast 1 hour
GET /api/ticks/{symbol}_4h.json/api/ticks/btc_4h.jsonLast 4 hours
GET /api/ticks/{symbol}_24h.json/api/ticks/btc_24h.jsonLast 24 hours
GET /api/ticks/{symbol}_7d.json/api/ticks/btc_7d.jsonLast 7 days
GET /api/ticks/latest.jsonLatest tick data for all 129 assets
GET /api/ticks/stats.jsonTick collection statistics and metadata

Replace btc with any of the 129 symbols listed above.

Examples

# Get BTC tick data (last hour)
curl "https://api.moondev.com/api/ticks/btc_1h.json?api_key=YOUR_KEY"

# Get ADA tick data (last 24 hours)
curl "https://api.moondev.com/api/ticks/ada_24h.json?api_key=YOUR_KEY"

# Get TRUMP tick data (last 7 days)
curl "https://api.moondev.com/api/ticks/trump_7d.json?api_key=YOUR_KEY"

Response Example (stats.json)

{
  "generated_at": "2026-01-29T15:37:44Z",
  "symbols": ["0G", "2Z", "AAVE", "ACE", "ADA", "...129 total"],
  "collector_stats": {
    "ticks_collected": 1552,
    "ticks_saved": 1552,
    "errors": 0,
    "started_at": "2026-01-06T19:03:35Z"
  },
  "db_size_mb": 0.16,
  "symbol_stats": {
    "BTC": {
      "tick_count": 251,
      "min_price": 91950.5,
      "max_price": 92296.0,
      "last_price": 92256.5
    }
  }
}

Response Example (btc_1h.json)

{
  "symbol": "BTC",
  "generated_at": "2026-01-06T19:17:38Z",
  "duration": "1h",
  "tick_count": 251,
  "latest_price": 92256.5,
  "ticks": [
    {"timestamp": 1767726130918, "price": 91950.5, "datetime": "2026-01-06T19:02:10Z"}
  ]
}

Blockchain EventsCopy link

EndpointDescription
GET /api/events.jsonReal-time decoded blockchain events from Hyperliquid L1
{
  "updated_at": "2026-01-06T19:17:00Z",
  "stats": {
    "total_events": 2424,
    "events_by_type": {
      "Transfer": 1200,
      "Swap": 500,
      "Approval": 200,
      "Deposit": 150,
      "Withdrawal": 100
    }
  },
  "recent_events": [
    {
      "block_number": 23863116,
      "tx_hash": "0x...",
      "event_type": "Transfer",
      "contract": "0x5555555555555555555555555555555555555555",
      "timestamp": "2026-01-06T19:17:00Z"
    }
  ]
}

Contract RegistryCopy link

EndpointDescription
GET /api/contracts.jsonComplete registry of Hyperliquid EVM smart contracts
{
  "generated_at": "2026-01-06T18:54:45Z",
  "chain": "hyperliquid_evm",
  "chain_id": 999,
  "total_contracts": 27,
  "high_value_count": 12,
  "key_contracts": {
    "system_treasury": "0x2222222222222222222222222222222222222222",
    "whype": "0x5555555555555555555555555555555555555555",
    "core_trading": "0x8549fd7ffc092f8366e416e129a622ec060104ea",
    "deposit_bridge": "0x5ed8551f90acc6395810d8274b019bf13ef1f696",
    "oracle": "0x200302c99d93ae1a024ecf9475df7d71b125efed"
  },
  "liquidation_contracts": ["0x8549...", "0x2003..."],
  "trading_alpha_contracts": ["0x8549...", "0x2180..."],
  "contracts": [
    {
      "address": "0x2222222222222222222222222222222222222222",
      "name": "Hyperliquid System Treasury",
      "type": "system",
      "description": "System treasury holding 954M+ HYPE",
      "is_high_value": true,
      "monitoring_priority": 10
    }
  ]
}

Hyperliquid LiquidationsCopy link

Real-time liquidation data from Hyperliquid DEX.

Built on these endpoints

Liq Heat by coin
Liq Heat by coin/api/liquidations/stats.jsonCopy link

Hyperliquid liquidations per coin over 1h, 4h, 24h and 7d, longs hit in red and shorts hit in green, crypto and HIP3 in one table.

Whale Sonar
Whale Sonar/api/liquidations/24h.jsonCopy link

Every Hyperliquid liquidation of $100K or more in the last 24 hours as a dot, oldest to newest, sized by dollars, long or short by colour.

EndpointDescription
GET /api/liquidations/stats.jsonLiquidation monitoring statistics
GET /api/liquidations/scan_summary.jsonRecent liquidation scan results
GET /api/liquidations/10m.jsonLast 10 minutes
GET /api/liquidations/1h.jsonLast 1 hour
GET /api/liquidations/4h.jsonLast 4 hours
GET /api/liquidations/12h.jsonLast 12 hours
GET /api/liquidations/24h.jsonLast 24 hours
GET /api/liquidations/2d.jsonLast 2 days
GET /api/liquidations/7d.jsonLast 7 days
GET /api/liquidations/14d.jsonLast 14 days
GET /api/liquidations/30d.jsonLast 30 days
{
  "scan_timestamp": "2026-01-06T19:00:00Z",
  "blocks_scanned": 500,
  "total_alerts": 150,
  "critical_count": 5,
  "warning_count": 25,
  "alerts": [
    {
      "timestamp": "2026-01-06T18:55:00Z",
      "block_number": 23863000,
      "tx_hash": "0x...",
      "contract_name": "Core Trading",
      "alert_type": "trade_executed",
      "level": "info"
    }
  ]
}

Alert Levels: info, warning, critical

Liquidations by Time Range (Quant Elite)Copy link

NEW: added 2026-10-28

Every Hyperliquid liquidation between any two times you choose, on the main dex and every HIP3 dex, with the full wallet address. History goes back to 2026-01-07. Use it to backfill holes in your own copy: a whole month comes down in about 15 seconds.

Quant Elite Only

Requires a Quant Elite API key (ends in _qe). Other keys get 401. Pass the key with the X-API-Key header or ?api_key=.

EndpointDescription
GET /api/bulk/hl_liquidationsEvery liquidation from start_ms up to end_ms, oldest first, paged
GET /api/bulk/hl_liquidations/coverageCount per UTC day (all, HIP3, main dex, dollars) plus known gaps, so you can check your copy

Query parameters

ParamMeaning
start_msStart of the window, included. Unix ms, unix seconds or a date like 2026-10-27 (UTC midnight).
end_msEnd of the window, not included. Same formats.
coinOptional. One market, e.g. BTC or xyz:TSLA. Default every market.
limitRows per page, up to 10,000.

If has_more is true, call again with start_ms set to next_start_ms. A page never splits a millisecond, so nothing is skipped or repeated between pages. Deduplicate on (coin, tid).

Fields on each row

FieldMeaning
timestamp / time_msUTC ISO time with ms, and the same time in unix ms
coin / dexMarket (HIP3 coins carry the dex, e.g. xyz:SKHX) and its dex
side / size / price / value_usdThe liquidated position: long or short, size, fill price, dollars
addressThe liquidated wallet, full lowercase address
pnlThat walletโ€™s P&L on the fill
tid / hashTrade id and transaction hash
methodmarket (filled on the book) or backstop (taken by the liquidator vault). From 2026-10-21, null before
mark_pxMark price at the liquidation. From 2026-10-21
counterparty / counterparty_roleThe wallet that took the flow, and whether it was maker or taker. From 2026-10-21

Example request

curl -H "X-API-Key: YOUR_QE_KEY" \
  "https://api.moondev.com/api/bulk/hl_liquidations?start_ms=2026-10-27&end_ms=2026-10-28&limit=10000"

Response example

{
  "endpoint": "bulk_hl_liquidations",
  "access_tier": "quant_elite",
  "start_ms": 1793059200000,
  "end_ms": 1793145600000,
  "coin": null,
  "order": "oldest_first",
  "count": 6927,
  "next_start_ms": null,
  "has_more": false,
  "gaps": [],
  "data": [
    {
      "timestamp": "2026-10-27T00:00:24.657Z",
      "time_ms": 1793059224657,
      "coin": "xyz:SKHX",
      "dex": "xyz",
      "side": "short",
      "size": 0.1,
      "price": 1019.4,
      "value_usd": 101.94,
      "address": "0x0ab6d64f501bf5cc44f968bd6b4ad482c385df11",
      "pnl": -5.599,
      "tid": 133304234435535,
      "hash": "0xe191aea36eff5e3ce30b04476fbad10207ca008909f27d0e855a59f62df33827",
      "method": "market",
      "mark_px": 1013.5,
      "counterparty": "0xf30120f0487a9093dbd47a69527ac9a9edbb7895",
      "counterparty_role": "maker",
      "source": "fills"
    }
  ]
}

Python: pull a whole range

import requests

API_KEY = "YOUR_QE_KEY"
URL = "https://api.moondev.com/api/bulk/hl_liquidations"

def get_liquidations(start, end, coin=None):
    rows, seen = [], set()
    params = {"start_ms": start, "end_ms": end, "limit": 10000}
    if coin:
        params["coin"] = coin
    while True:
        r = requests.get(URL, params=params, headers={"X-API-Key": API_KEY}, timeout=60)
        r.raise_for_status()
        page = r.json()
        for row in page["data"]:
            key = (row["coin"], row["tid"])
            if key not in seen:
                seen.add(key)
                rows.append(row)
        if page.get("gaps"):
            print("known gaps in this window:", page["gaps"])
        if not page["has_more"]:
            return rows
        params["start_ms"] = page["next_start_ms"]

liqs = get_liquidations("2026-10-01", "2026-10-28")
print(len(liqs), "liquidations")

Using Python's urllib instead of requests? Set a User-Agent header, or Cloudflare returns 403.

Known gaps

One window has no data from any source: 2026-10-25 09:32:20 to 12:40:43 UTC (the node was down during a Hyperliquid upgrade). Any response that overlaps it lists it in gaps, and /coverage lists every known gap.

HIP3 Liquidations (TradFi Assets)Copy link

Real-time liquidation data for traditional finance assets trading on Hyperliquid. Includes stocks, commodities, indices, and forex pairs.

Asset Categories

CategoryAssetsApprox OI
StocksTSLA, NVDA, AAPL, META, MSFT, GOOGL, AMZN, AMD, INTC, PLTR, COIN, HOOD, MSTR, ORCL, MU, NFLX, RIVN, BABA~$100M+
CommoditiesGOLD, SILVER, COPPER, CL (Oil), NATGAS, URANIUM~$125M
IndicesXYZ100 (Nasdaq proxy)~$120M
FXEUR, JPY~$3M

Get HIP3 Liquidations

EndpointDescription
GET /api/hip3_liquidations/10m.jsonLast 10 minutes
GET /api/hip3_liquidations/1h.jsonLast 1 hour
GET /api/hip3_liquidations/24h.jsonLast 24 hours
GET /api/hip3_liquidations/7d.jsonLast 7 days

Response Fields

FieldTypeDescription
symbolstringAsset symbol (TSLA, GOLD, etc.)
sidestringlong or short
sizenumberPosition size
pricenumberLiquidation price
value_usdnumberUSD value of liquidation
categorystringstocks, commodities, indices, or fx
timestampnumberEvent timestamp (Unix ms)

Get HIP3 Liquidation Stats

EndpointDescription
GET /api/hip3_liquidations/stats.jsonAggregated statistics for HIP3 liquidations

Stats Response Fields

FieldTypeDescription
total_countnumberTotal liquidation count
total_volumenumberTotal USD volume liquidated
long_countnumberNumber of long liquidations
short_countnumberNumber of short liquidations
long_volumenumberUSD volume of long liquidations
short_volumenumberUSD volume of short liquidations
by_categoryobjectBreakdown by category (stocks, commodities, indices, fx)
by_symbolobjectBreakdown by individual symbol
top_symbolsarrayTop symbols by liquidation volume

Example Request

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_liquidations/1h.json

Python SDK Usage

from api import MoonDevAPI

api = MoonDevAPI()

# Get HIP3 liquidation stats
stats = api.get_hip3_liquidation_stats()
print(f"Total liquidations: {stats['total_count']}")
print(f"Total volume: ${stats['total_volume']:,.0f}")

# Get HIP3 liquidations for different timeframes
liqs_10m = api.get_hip3_liquidations("10m")   # Last 10 minutes
liqs_1h = api.get_hip3_liquidations("1h")     # Last 1 hour
liqs_24h = api.get_hip3_liquidations("24h")   # Last 24 hours
liqs_7d = api.get_hip3_liquidations("7d")     # Last 7 days

# Process liquidation data
for liq in liqs_1h:
    print(f"{liq['symbol']} {liq['side'].upper()} ${liq['value_usd']:,.0f} @ ${liq['price']}")

Use Cases

  • Risk Management - Monitor liquidation activity across traditional finance assets to gauge market stress
  • Trading Signals - High liquidation volume in one direction may indicate squeeze potential
  • Market Analysis - Track which asset categories are seeing the most liquidation activity
  • Alert Systems - Build alerts for large liquidations on specific symbols

Rate limit: 3,600 requests per minute. Data updates in real-time. Historical data available up to 7 days.

Ready to start building? Get your API key here.

HIP3 Market Data (Multi-Dex)Copy link

Real-time tick data for every HIP3 symbol on HyperLiquid โ€” currently 136 symbols across 7 dexes, up from the previous top-10-by-volume cap. New symbols are auto-discovered as HyperLiquid lists them, with no config changes required. All data is served on-demand from our SQLite tick store at request time, so the API scales to thousands of symbols without pre-generating files.

๐ŸŒ™ Why this beats the HyperLiquid Data API

  • HyperLiquid 1m candles โ€” max 3.6 days of history
  • HyperLiquid 5m candles โ€” max 17 days of history
  • Moon Dev API (starting 2026-04-26) โ€” unlimited days going forward, every tick, every HIP3 symbol. Want 30-second bars? We have every tick โ€” roll your own resolution.

Coverage at a Glance

Symbol count136 (live count โ€” grows automatically)
Dexes trackedxyz (XYZ), flx (Felix), vntl (Ventuals), hyna (HyENA), km (Kinetiq), cash (dreamcash), para (Paragon)
Categoriesstocks, indices, commodities, FX, crypto, pre-IPO, other
Trading hours24/7 (HyperLiquid is always open โ€” no market-hours gaps, even for equity-named perps)
Tick resolutionevery trade on the venue (~500ms heartbeat target)
Retention30 days of raw ticks per symbol
Freshnesssub-second (queried live from the tick DB)

Categories

CategoryExamples
StocksTSLA, NVDA, HIMS, AAPL, META, COIN
IndicesXYZ100, USA500, USTECH, SMALL2000
CommoditiesGOLD, SILVER, CL, OIL, NATGAS, COPPER
FXEUR, JPY
CryptoBTC, ETH, SOL, HYPE, XMR
Pre-IPOOPENAI, ANTHROPIC, SPACEX

Symbol Format: {dex}:{ticker} (e.g., xyz:TSLA, hyna:BTC, km:US500, vntl:OPENAI)

Get All HIP3 Symbols & Prices (Auto-Discovery)

The /meta endpoint auto-discovers dexes via perpDexs (5-min cache), so newly added HyperLiquid dexes appear automatically โ€” no config changes required.

EndpointDescription
GET /api/hip3/metaReturns all 136 symbols with current prices, categories, and per-dex active/delisted counts
GET /api/hip3/candles/symbolsSame coverage, organized by category
GET /api/hip3/meta?include_delisted=trueInclude delisted symbols
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3/meta

Get Tick Collector Stats

EndpointDescription
GET /api/hip3_ticks/stats.jsonReturns tick collector statistics across all 136 symbols / 7 dexes
{
  "generated_at": "2026-04-26T15:39:48Z",
  "market_type": "HIP3",
  "collection_method": "WebSocket Streaming",
  "dexes": ["xyz", "flx", "vntl", "hyna", "km", "cash", "para"],
  "symbol_count": 136,
  "by_category": {
    "stocks": ..., "indices": ..., "commodities": ...,
    "fx": ..., "crypto": ..., "pre_ipo": ..., "other": ...
  }
}

Get Individual Symbol Tick Data

EndpointDescription
GET /api/hip3_ticks/{dex}_{ticker}.jsonReturns tick data for a specific symbol

XYZ Dex (27) - Stocks, Commodities, FX

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/xyz_tsla.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/xyz_nvda.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/xyz_gold.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/xyz_eur.json

FLX Dex (7) - Stocks, XMR, Commodities

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/flx_xmr.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/flx_gold.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/flx_oil.json

VNTL Dex (7) - Pre-IPO & Indices

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/vntl_openai.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/vntl_anthropic.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/vntl_spacex.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/vntl_mag7.json

HYNA Dex (12) - Crypto

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/hyna_btc.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/hyna_eth.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/hyna_hype.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/hyna_sol.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/hyna_fartcoin.json

KM Dex (5) - US Indices

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/km_us500.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/km_ustech.json
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3_ticks/km_small2000.json

Python SDK Usage

from api import MoonDevAPI

api = MoonDevAPI()

# Get all HIP3 symbols with prices
meta = api.get_hip3_meta()
for sym in meta['symbols']:
    print(f"{sym['dex']}:{sym['ticker']} = ${sym['price']}")

# Get tick stats
stats = api.get_hip3_tick_stats()
print(f"Symbols: {stats['symbol_count']}")
print(f"Ticks received: {stats['collector_stats']['ticks_received']}")

# Get tick data by dex:ticker
tsla = api.get_hip3_ticks("xyz", "tsla")      # Tesla
openai = api.get_hip3_ticks("vntl", "openai") # OpenAI Pre-IPO
btc = api.get_hip3_ticks("hyna", "btc")       # Bitcoin
sp500 = api.get_hip3_ticks("km", "us500")     # S&P 500

Example Dashboard

python examples/21_hip3_market_data.py               # All 58 symbols with prices
python examples/21_hip3_market_data.py xyz tsla      # Tesla ticks
python examples/21_hip3_market_data.py vntl openai   # OpenAI Pre-IPO ticks
python examples/21_hip3_market_data.py hyna btc      # Bitcoin ticks
python examples/21_hip3_market_data.py km us500      # S&P 500 ticks

Legacy Endpoints (Still Supported)

The following endpoints from the original HIP3 Market Data are still available:

EndpointDescription
GET /api/hip3/candles/symbolsList all symbols organized by category
GET /api/hip3/pricesAll prices at once
GET /api/hip3/price/{coin}Single symbol price
GET /api/hip3/candles/{coin}?interval=OHLCV candles (1m, 5m, 15m, 1h, 4h, 1d). Same endpoint as Get OHLCV Candles below
GET /api/hip3/ticks/{coin}?duration=Raw tick data (10m, 1h, 4h, 24h, 7d)

List All HIP3 Symbols

EndpointDescription
GET /api/hip3/candles/symbolsReturns all 136 HIP3 symbols organized by category and dex
{
  "count": 136,
  "categories": {
    "stocks": ["xyz:TSLA", "xyz:NVDA", "xyz:HIMS", ...],
    "commodities": ["xyz:GOLD", "xyz:SILVER", "xyz:CL", "flx:OIL", ...],
    "fx": ["xyz:JPY", "xyz:EUR"],
    "indices": ["xyz:XYZ100", "cash:USA500", "km:USTECH", ...],
    "crypto": ["hyna:BTC", "hyna:ETH", "hyna:HYPE", ...],
    "pre_ipo": ["vntl:OPENAI", "vntl:ANTHROPIC", "vntl:SPACEX"]
  }
}

Get All HIP3 Prices

EndpointDescription
GET /api/hip3/pricesReturns current prices for all 136 HIP3 symbols
{
  "generated_at": "2026-04-26T15:39:48Z",
  "market_type": "HIP3",
  "dexes": ["xyz", "flx", "vntl", "hyna", "km", "cash", "para"],
  "prices": {
    "xyz:HIMS":    {"dex": "xyz",  "ticker": "HIMS",    "price": 30.399, "category": "other"},
    "xyz:TSLA":    {"dex": "xyz",  "ticker": "TSLA",    "price": 431.64, "category": "stocks"},
    "cash:USA500": {"dex": "cash", "ticker": "USA500",  "price": 6780.6, "category": "indices"},
    "vntl:OPENAI": {"dex": "vntl", "ticker": "OPENAI",  "price": 412.5,  "category": "pre_ipo"}
  }
}

Get Single Symbol Price

EndpointDescription
GET /api/hip3/price/{coin}Returns current price for a single HIP3 symbol

The dex and ticker fields are now split out as top-level keys, so consumers don't need to parse the colon-qualified symbol string.

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/hip3/price/HIMS
{
  "symbol": "xyz:HIMS",
  "dex": "xyz",
  "ticker": "HIMS",
  "price": 30.399,
  "category": "other",
  "market_type": "HIP3",
  "timestamp": "2026-04-26T15:39:48.793000+00:00"
}

Get OHLCV Candles

EndpointDescription
GET /api/hip3/candles/{coin}?interval={interval}Returns OHLCV candle data for any HIP3 symbol
ParamDefaultDescription
coinrequiredSymbol (TSLA, GOLD, EUR, XYZ100, etc.)
interval5mCandle interval: 1m, 5m, 15m, 1h, 4h, 1d
startTimeautoStart timestamp (Unix ms)
endTimenowEnd timestamp (Unix ms)
curl -H "X-API-Key: YOUR_KEY" "https://api.moondev.com/api/hip3/candles/TSLA?interval=1h"
[
  {
    "t": 1737288000000,
    "T": 1737291599999,
    "s": "TSLA",
    "i": "1h",
    "o": "430.50",
    "h": "432.20",
    "l": "429.80",
    "c": "431.90",
    "v": "0",
    "n": 245
  }
]

Candle Response Fields

FieldDescription
tOpen time (Unix ms)
TClose time (Unix ms)
sSymbol
iInterval
oOpen price
hHigh price
lLow price
cClose price
vVolume
nNumber of ticks in candle

Get Raw Tick Data

EndpointDescription
GET /api/hip3/ticks/{coin}?duration={duration}Returns raw tick-by-tick price data for any HIP3 symbol
ParamDefaultDescription
coinrequiredSymbol (TSLA, GOLD, EUR, XYZ100, etc.)
duration1hTime window: 10m, 1h, 4h, 24h, 7d
limit10000Max ticks to return
startTime-Start time (Unix ms), overrides duration
endTime-End time (Unix ms)
curl -H "X-API-Key: YOUR_KEY" "https://api.moondev.com/api/hip3/ticks/GOLD?duration=1h"
{
  "symbol": "GOLD",
  "duration": "1h",
  "tick_count": 112,
  "latest_price": 4672.40,
  "ticks": [
    {
      "t": 1737288000000,
      "p": 4671.50,
      "dt": "2026-01-19T13:00:00.000000+00:00"
    },
    {
      "t": 1737288003000,
      "p": 4671.80,
      "dt": "2026-01-19T13:00:03.000000+00:00"
    }
  ]
}

Python SDK Usage

from api import MoonDevAPI

api = MoonDevAPI()

# Get all HIP3 symbols by category
symbols = api.get_hip3_symbols()
print(f"{symbols['count']} symbols available")
print(f"Stocks: {symbols['categories']['stocks']}")
print(f"Commodities: {symbols['categories']['commodities']}")

# Get all HIP3 prices at once
prices = api.get_hip3_prices()
print(f"TSLA: ${prices['prices']['TSLA']['price']}")
print(f"GOLD: ${prices['prices']['GOLD']['price']}")

# Get single symbol price
tsla = api.get_hip3_price("TSLA")
print(f"TSLA: ${tsla['price']} ({tsla['category']})")

# Get OHLCV candles
candles = api.get_hip3_candles("TSLA", interval="5m")
for c in candles[-5:]:
    print(f"O:{c['o']} H:{c['h']} L:{c['l']} C:{c['c']}")

# Get 1-hour candles for GOLD
gold_candles = api.get_hip3_candles("GOLD", interval="1h")

# Get daily candles
daily = api.get_hip3_candles("NVDA", interval="1d")

# Get raw tick data
ticks = api.get_hip3_ticks("TSLA", duration="1h")
print(f"{ticks['tick_count']} ticks, latest: ${ticks['latest_price']}")

# Get 24h of tick data
ticks_24h = api.get_hip3_ticks("GOLD", duration="24h")

# Custom time range (Unix ms)
ticks = api.get_hip3_ticks("EUR", start_time=1737280000000, end_time=1737290000000)

Use Cases

  • Technical Analysis - Build charts and indicators using OHLCV candles
  • Algorithmic Trading - Use tick data for high-frequency strategies
  • Cross-Asset Analysis - Compare crypto with TradFi assets on same platform
  • Price Alerts - Monitor tick-by-tick price changes for specific assets
  • Backtesting - Historical candle data for strategy testing

Like what you see? Grab your API key and start building.

Data Collection Details

  • Polling Interval: 500ms (only stores price changes)
  • Auto-Discovery: New symbols detected every 5 minutes
  • Candle Intervals: 1m, 5m, 15m, 1h, 4h, 1d
  • Tick Durations: 10m, 1h, 4h, 24h, 7d

Rate limit: 3,600 requests per minute. Data updates at 500ms intervals. Tick data stored only on price changes.

HIP3 Tick Data (All Symbols)Copy link

Tick-level data and server-computed OHLCV candles for every HIP3 symbol on HyperLiquid โ€” currently 136 symbols across 7 dexes (xyz, flx, vntl, hyna, km, cash, para). As of 2026-04-26, the previous top-10-by-volume cap is gone. New symbols are auto-discovered as HyperLiquid lists them. Data is served on-demand from our SQLite tick store at request time, candles are computed live from those ticks, and retention is 30 days of raw ticks per symbol.

๐ŸŒ™ Why this matters

HIP3 tick data on traditional venues costs thousands per month per symbol. Because we run a HyperLiquid node, every HIP3 symbol โ€” stocks, commodities, FX, indices, crypto, pre-IPO โ€” is available through one API at no marginal cost, 24/7, with sub-second freshness and OHLCV at any interval.

  • HyperLiquid Data API: 1m candles capped at 3.6 days, 5m candles capped at 17 days.
  • Moon Dev API: from 2026-04-26 forward, unlimited days back per tick, every tick. Want 30-second bars? We have every trade โ€” roll your own bucket.

Endpoints

All endpoints require api_key as a query param or X-API-Key header.

EndpointDescription
GET /api/hip3/candles/symbolsList all currently tracked symbols, intervals, and categories
GET /api/hip3/ticks/{coin}?duration=1hRaw tick data for a symbol (durations: 10m, 1h, 4h, 24h, 7d)
GET /api/hip3/candles/{coin}?interval=5mThe same candles endpoint as in HIP3 Market Data (one endpoint, not two). Its bars are built from these ticks (intervals: 1m, 5m, 15m, 1h, 4h, 1d)
GET /api/hip3/price/{coin}Latest price for a single symbol
GET /api/hip3/pricesLatest prices for all tracked symbols

Symbol Lookup

Three symbol formats are accepted โ€” bare ticker, full dex:ticker, or non-xyz dex prefix. Bare tickers auto-resolve to the correct dex.

# Bare ticker (resolves to correct dex automatically)
curl "https://api.moondev.com/api/hip3/ticks/CL?duration=1h&api_key=YOUR_KEY"

# Full dex:ticker format
curl "https://api.moondev.com/api/hip3/ticks/xyz:CL?duration=1h&api_key=YOUR_KEY"

# Non-xyz dex
curl "https://api.moondev.com/api/hip3/ticks/cash:USA500?duration=1h&api_key=YOUR_KEY"

1. List Available Symbols

curl "https://api.moondev.com/api/hip3/candles/symbols?api_key=YOUR_KEY"

Response Example

{
  "count": 136,
  "dexes": ["xyz", "flx", "vntl", "hyna", "km", "cash", "para"],
  "intervals": ["1m", "5m", "15m", "1h", "4h", "1d"],
  "by_category": {
    "stocks":      ["xyz:TSLA", "xyz:NVDA", "xyz:HIMS", "..."],
    "indices":     ["xyz:XYZ100", "cash:USA500", "km:USTECH", "..."],
    "commodities": ["xyz:CL", "xyz:GOLD", "xyz:SILVER", "flx:OIL", "..."],
    "fx":          ["xyz:EUR", "xyz:JPY"],
    "crypto":      ["hyna:BTC", "hyna:ETH", "hyna:HYPE", "..."],
    "pre_ipo":     ["vntl:OPENAI", "vntl:ANTHROPIC", "vntl:SPACEX"]
  },
  "market_type": "HIP3"
}

2. Raw Tick Data

Durations: 10m, 1h, 4h, 24h, 7d

curl "https://api.moondev.com/api/hip3/ticks/CL?duration=1h&api_key=YOUR_KEY"

Response Example

{
  "symbol": "xyz:CL",
  "category": "commodities",
  "market_type": "HIP3",
  "duration": "1h",
  "tick_count": 1842,
  "start_time": 1741611600000,
  "end_time": 1741615200000,
  "latest_price": 87.89,
  "ticks": [
    {"t": 1741611600500, "p": 87.65, "dt": "2026-03-10T13:00:00+00:00"},
    {"t": 1741611601000, "p": 87.66, "dt": "2026-03-10T13:00:01+00:00"}
  ]
}

3. OHLCV Candles (computed from ticks)

Intervals: 1m, 5m, 15m, 1h, 4h, 1d. Optional params: startTime, endTime (Unix ms).

curl "https://api.moondev.com/api/hip3/candles/CL?interval=5m&api_key=YOUR_KEY"
curl "https://api.moondev.com/api/hip3/candles/cash:USA500?interval=1h&api_key=YOUR_KEY"

Response Example

[
  {
    "t": 1741611600000, "T": 1741611899999,
    "s": "CL", "i": "5m",
    "o": "87.65", "h": "87.92", "l": "87.60", "c": "87.89",
    "v": "0", "n": 42
  }
]

4. Latest Price (single symbol)

The dex and ticker fields are split out as top-level keys, so consumers don't need to parse the colon-qualified symbol string.

curl "https://api.moondev.com/api/hip3/price/HIMS?api_key=YOUR_KEY"

Response Example

{
  "symbol": "xyz:HIMS",
  "dex": "xyz",
  "ticker": "HIMS",
  "price": 30.399,
  "category": "other",
  "market_type": "HIP3",
  "timestamp": "2026-04-26T15:39:48.793000+00:00"
}

5. All Latest Prices

curl "https://api.moondev.com/api/hip3/prices?api_key=YOUR_KEY"

Response Example

{
  "generated_at": "2026-04-26T15:39:48+00:00",
  "market_type": "HIP3",
  "dexes": ["xyz", "flx", "vntl", "hyna", "km", "cash", "para"],
  "prices": {
    "xyz:HIMS":     {"dex": "xyz",  "ticker": "HIMS",     "price": 30.399, "category": "other"},
    "xyz:CL":       {"dex": "xyz",  "ticker": "CL",       "price": 87.89,  "category": "commodities"},
    "cash:USA500":  {"dex": "cash", "ticker": "USA500",   "price": 6780.6, "category": "indices"},
    "vntl:OPENAI":  {"dex": "vntl", "ticker": "OPENAI",   "price": 412.5,  "category": "pre_ipo"},
    "hyna:BTC":     {"dex": "hyna", "ticker": "BTC",      "price": 96420,  "category": "crypto"}
  }
}

Tick + Candle Query Params

All parameters are strictly validated. Invalid input returns HTTP 400 with a helpful message โ€” no silent fallbacks. Unknown symbols return HTTP 404 with a pointer to /api/hip3/candles/symbols.

ParameterValid valuesError on invalid
duration10m, 1h, 4h, 24h, 7d400 Invalid duration 'X'. Supported: 10m, 1h, 4h, 24h, 7d
interval1m, 5m, 15m, 1h, 4h, 1d400 Invalid interval. Supported: 1m, 5m, 15m, 1h, 4h, 1d
limitinteger 1..100000 (default 10000 ticks / 200 candles)400 Invalid limit X. Must be 1..100000
orderasc or desc (default asc)400 Invalid order 'X'. Use 'asc' or 'desc'
startTime / endTimeUnix ms (overrides duration when provided)โ€”

Quick Examples

# Live HIMS price
curl "https://api.moondev.com/api/hip3/price/HIMS?api_key=KEY"

# Last hour of HIMS ticks
curl "https://api.moondev.com/api/hip3/ticks/HIMS?duration=1h&api_key=KEY"

# 1-minute HIMS candles for the last 7 days
NOW=$(($(date +%s)*1000)); WEEK=$((NOW - 7*86400*1000))
curl "https://api.moondev.com/api/hip3/candles/HIMS?interval=1m&startTime=$WEEK&endTime=$NOW&api_key=KEY"

# All current HIP3 prices (136 symbols across 7 dexes)
curl "https://api.moondev.com/api/hip3/prices?api_key=KEY"

# Pre-IPO exposure via Ventuals
curl "https://api.moondev.com/api/hip3/price/vntl:OPENAI?api_key=KEY"
curl "https://api.moondev.com/api/hip3/price/vntl:ANTHROPIC?api_key=KEY"

Key Notes

  • All 136 symbols โ€” the previous top-10 cap was removed on 2026-04-26; every HIP3 symbol on HyperLiquid is now tracked
  • Auto-discovery โ€” new symbols and dexes are picked up automatically via perpDexs (5-min cache) โ€” no config changes required
  • 7 dexes โ€” xyz, flx, vntl, hyna, km, cash, para
  • 24/7 trading โ€” HyperLiquid never closes, so equity-named perps trade through nights and weekends
  • 30-day raw tick retention โ€” every trade for the last 30 days, per symbol
  • Bare ticker lookups โ€” pass just HIMS, CL, or USA500; ambiguous tickers (e.g. GOLD on xyz/flx/km) require the full dex:ticker form
  • Server-computed candles โ€” built live from stored ticks; pick any standard interval, or pull raw ticks and bucket them yourself (e.g. 30s)
  • Beats the HyperLiquid Data API โ€” their 1m candle history caps at ~3.6 days and 5m at ~17 days; we keep going from 2026-04-26 forward

Migration Notes

  • No breaking changes. Legacy /api/hip3_ticks/{dex}_{symbol}_{duration}.json static files continue to publish for the top 10 by volume for backward compatibility.
  • New consumers should use the on-demand endpoints above โ€” they cover every symbol, return live data, and support time-window queries.
  • If you previously parsed xyz:HIMS client-side to extract the dex, you can now read dex and ticker directly from the price response.

Multi-Exchange LiquidationsCopy link

Real-time liquidation data from multiple exchanges: Binance, Bybit, OKX, and HyperLiquid. Get individual exchange data or combined aggregated stats across all exchanges.

Built on these endpoints

Flow
Flow/api/all_liquidations/totals.jsonCopy link

Long vs short liquidation flow over 5m, 15m, 1h and 4h across all four exchanges, then the net per coin. One call, six rolling windows.

Tug of War
Tug of War/api/all_liquidations/totals.jsonCopy link

Longs liquidated against shorts liquidated per coin for the last hour, with the window split up top. The same totals file, drawn as a bar fight.

Liq Rain
Liq Rain/api/all_liquidations/1h.jsonCopy link

Minute by minute liquidations for the last hour, shorts up and longs down, then the per exchange split for 1h and 24h underneath.

Liq Flow, 4 exchanges
Liq Flow, 4 exchanges/api/all_liquidations/Copy link

Binance, Bybit, OKX and Hyperliquid side by side over 5m, 1h and 4h, plus the biggest single liquidations of the day with the exchange and the price they went at.

Liq Heat 24h
Liq Heat 24h/api/all_liquidations/24h.jsonCopy link

A 24 hour heat strip per coin and per exchange, every cell a slice of time, red for longs and green for shorts, with the hourly total along the bottom.

Update Frequency

  • Live endpoints (10m - 5d): Updated every 30 seconds
  • Archive endpoints (7d - 30d): Updated every 15 minutes

Combined (All Exchanges) - Live

EndpointDescription
GET /api/all_liquidations/stats.jsonCombined stats from all exchanges
GET /api/all_liquidations/10m.jsonLast 10 minutes
GET /api/all_liquidations/1h.jsonLast 1 hour
GET /api/all_liquidations/4h.jsonLast 4 hours
GET /api/all_liquidations/12h.jsonLast 12 hours
GET /api/all_liquidations/24h.jsonLast 24 hours
GET /api/all_liquidations/2d.jsonLast 2 days
GET /api/all_liquidations/5d.jsonLast 5 days

Combined (All Exchanges) - Archive

EndpointDescription
GET /api/all_liquidations/7d.jsonLast 7 days (15-min updates)
GET /api/all_liquidations/14d.jsonLast 14 days (15-min updates)
GET /api/all_liquidations/30d.jsonLast 30 days (15-min updates)

Rolling Totals (Long vs Short), all windows

One call returns the combined long and short liquidation split across all four exchanges for six rolling windows: 5m, 15m, 1h, 2h, 3h, 4h. Every window carries long_volume_usd / long_count and short_volume_usd / short_count, and the same split repeats inside each exchange under by_exchange (binance, bybit, okx, hyperliquid). Standard key. Updated every 20 seconds.

EndpointDescription
GET /api/all_liquidations/totals.jsonLong vs short totals across all exchanges, six rolling windows (5m to 4h)

Response Fields (totals.json)

FieldTypeDescription
windowsobjectKeyed by window: 5m, 15m, 1h, 2h, 3h, 4h
total_volume_usdnumberTotal liquidated USD in the window (long plus short)
total_countnumberTotal liquidation events in the window
long_volume_usdnumberUSD of long liquidations
long_countnumberNumber of long liquidations
short_volume_usdnumberUSD of short liquidations
short_countnumberNumber of short liquidations
by_exchangeobjectSame six fields, one entry per exchange
generated_atstringISO 8601 UTC timestamp of the reading
notestringPlain text summary of what the file contains

Example Request

curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/all_liquidations/totals.json

# or with the key as a query parameter
curl "https://api.moondev.com/api/all_liquidations/totals.json?api_key=YOUR_KEY"

Response Example (all_liquidations/totals.json)

{
  "generated_at": "2026-07-20T19:47:02Z",
  "note": "Total liquidations (USD amount + count) across binance, bybit, okx, hyperliquid.",
  "windows": {
    "5m": {
      "total_volume_usd": 247147,
      "total_count": 112,
      "long_volume_usd": 166096,
      "long_count": 78,
      "short_volume_usd": 81051,
      "short_count": 34,
      "by_exchange": {
        "binance": {
          "volume_usd": 103379,
          "count": 56,
          "long_volume_usd": 78161,
          "long_count": 38,
          "short_volume_usd": 25217,
          "short_count": 18
        },
        "bybit":       { "...": "same shape" },
        "okx":         { "...": "same shape" },
        "hyperliquid": { "...": "same shape" }
      }
    },
    "15m": { "...": "same shape" },
    "1h":  { "...": "same shape" },
    "2h":  { "...": "same shape" },
    "3h":  { "...": "same shape" },
    "4h":  { "...": "same shape" }
  }
}

Binance Liquidations

EndpointDescription
GET /api/binance_liquidations/stats.jsonBinance stats (24h volume, counts, top coins)
GET /api/binance_liquidations/10m.jsonLast 10 minutes
GET /api/binance_liquidations/1h.jsonLast hour
GET /api/binance_liquidations/24h.jsonLast 24 hours
GET /api/binance_liquidations/7d.jsonLast 7 days
GET /api/binance_liquidations/30d.jsonLast 30 days

Bybit Liquidations

EndpointDescription
GET /api/bybit_liquidations/stats.jsonBybit stats (24h volume, counts, top coins)
GET /api/bybit_liquidations/10m.jsonLast 10 minutes
GET /api/bybit_liquidations/1h.jsonLast hour
GET /api/bybit_liquidations/24h.jsonLast 24 hours
GET /api/bybit_liquidations/7d.jsonLast 7 days
GET /api/bybit_liquidations/30d.jsonLast 30 days

OKX Liquidations

EndpointDescription
GET /api/okx_liquidations/stats.jsonOKX stats (24h volume, counts, top coins)
GET /api/okx_liquidations/10m.jsonLast 10 minutes
GET /api/okx_liquidations/1h.jsonLast hour
GET /api/okx_liquidations/24h.jsonLast 24 hours
GET /api/okx_liquidations/7d.jsonLast 7 days
GET /api/okx_liquidations/30d.jsonLast 30 days

Response Example (all_liquidations/stats.json)

{
  "updated_at": "2026-01-09T12:00:00Z",
  "exchanges": ["binance", "bybit", "okx"],
  "combined": {
    "total_liquidations": 45000,
    "total_value_usd": 380000000,
    "long_liquidations": {
      "count": 25000,
      "value_usd": 215000000
    },
    "short_liquidations": {
      "count": 20000,
      "value_usd": 165000000
    }
  },
  "by_exchange": {
    "binance": {"count": 18000, "value_usd": 165000000},
    "bybit": {"count": 15000, "value_usd": 125000000},
    "okx": {"count": 12000, "value_usd": 90000000}
  },
  "top_liquidated_coins": [
    {"symbol": "BTC", "value_usd": 125000000, "count": 9500},
    {"symbol": "ETH", "value_usd": 85000000, "count": 8200},
    {"symbol": "SOL", "value_usd": 45000000, "count": 5100}
  ]
}

Response Example (binance_liquidations/1h.json)

{
  "exchange": "binance",
  "timeframe": "1h",
  "generated_at": "2026-01-09T12:00:00Z",
  "stats": {
    "total_count": 850,
    "long_count": 480,
    "short_count": 370,
    "total_value_usd": 8500000,
    "long_value_usd": 5200000,
    "short_value_usd": 3300000
  },
  "liquidations": [
    {
      "symbol": "BTCUSDT",
      "side": "SELL",
      "quantity": 0.15,
      "price": 42500.00,
      "value_usd": 6375.00,
      "timestamp": "2026-01-09T11:55:00Z"
    }
  ]
}

Python Example - Multi-Exchange

import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.moondev.com"
headers = {"X-API-Key": API_KEY}

# Get combined stats from ALL exchanges
all_stats = requests.get(
    f"{BASE_URL}/api/all_liquidations/stats.json",
    headers=headers
).json()

print("=== COMBINED LIQUIDATIONS (All Exchanges) ===")
print(f"Total Volume: ${all_stats['combined']['total_value_usd']:,.0f}")
print(f"Longs Rekt:   ${all_stats['combined']['long_liquidations']['value_usd']:,.0f}")
print(f"Shorts Rekt:  ${all_stats['combined']['short_liquidations']['value_usd']:,.0f}")

print("\n=== BY EXCHANGE ===")
for exchange, data in all_stats['by_exchange'].items():
    print(f"{exchange.upper()}: {data['count']:,} liquidations, ${data['value_usd']:,.0f}")

# Get individual exchange data
for exchange in ["binance", "bybit", "okx"]:
    hourly = requests.get(
        f"{BASE_URL}/api/{exchange}_liquidations/1h.json",
        headers=headers
    ).json()
    print(f"\n{exchange.upper()} Last Hour: {hourly['stats']['total_count']} liquidations")

Note: side: "SELL" = Long position liquidated, side: "BUY" = Short position liquidated.

Cross-exchange liquidation data in one API call. Get your API key here.

Binance Futures LiquidationsCopy link

Historical and live Binance Futures liquidation data โ€” 35 million+ records dating back to June 2024, plus the real-time feed.

โš ๏ธ Data gap: 2026-04-23 โ†’ 2026-07-18

This dataset has two segments โ€” a historical archive (2024-06-04 โ†’ 2026-04-23) and the live feed (2026-07-18 onward) โ€” with no data in between. No liquidations were collected during that window, and the gap is permanent (the data cannot be recovered). Use the Coverage endpoint below to get exact, always-current segment boundaries before assuming a date range has data.

Coverage Endpoint

Returns the available data segments and the gap between them. Stays current as the live feed grows. Uses a standard API key โ€” no Quant Elite key required.

MethodURL
GET/api/binance_liquidations/coverage.json?api_key=YOUR_KEY

Response

{
  "dataset": "binance_futures_liquidations",
  "generated_at": "2026-07-19T15:17:00Z",
  "segments": [
    {
      "name": "historical",
      "status": "frozen",
      "note": "Complete historical archive. This segment is final and will not change.",
      "start": "2024-06-04T12:46:58Z",
      "end":   "2026-04-23T16:30:49Z",
      "records": 35624285
    },
    {
      "name": "live",
      "status": "collecting",
      "note": "Live feed, collected in real time.",
      "start": "2026-07-18T23:47:58Z",
      "end":   "2026-07-19T15:17:00Z",
      "records": 1234
    }
  ],
  "gap": {
    "from": "2026-04-23",
    "to": "2026-07-18",
    "reason": "No liquidation data was collected during this period. This gap is permanent and the data cannot be recovered."
  },
  "access": {
    "bulk_endpoint": "/api/bulk/binance_liquidations",
    "tier": "quant_elite",
    "historical_example": "/api/bulk/binance_liquidations?end=2026-04-23",
    "live_example": "/api/bulk/binance_liquidations?start=2026-07-18"
  }
}
FieldDescription
segments[].namehistorical (frozen archive) or live (real-time feed)
segments[].statusfrozen = final, never changes; collecting = growing in real time
segments[].start / endISO 8601 UTC boundaries of the segment
segments[].recordsNumber of liquidations in the segment
gap.from / toThe dates with no data. Queries spanning this range simply return fewer rows.

Bulk Data Endpoint

Quant Elite Only

Requires a Quant Elite API key (must end in _qe). Standard keys receive 403 Forbidden. Pass the key via ?api_key= or the X-API-Key header.

Both segments live in one continuous table, so a single endpoint serves everything. Slice by date to target the historical archive or the live feed.

MethodURL
GET/api/bulk/binance_liquidations?api_key=YOUR_QE_KEY

Parameters

ParamTypeDescription
api_keystringQuant Elite API key (required)
startstringStart date YYYY-MM-DD or unix ms timestamp
endstringEnd date YYYY-MM-DD or unix ms timestamp
symbolstringFilter by symbol (e.g. BTCUSDT)
sidestringBUY (short liquidated) or SELL (long liquidated)
min_usdfloatMinimum liquidation size in USD
limitintRecords per page (default 10,000 / max 100,000)
offsetintPagination offset (default 0)

Selecting a Segment

GoalRequest
Historical archive only?end=2026-04-23
Live feed only?start=2026-07-18
Everythingno date filter (gap rows simply do not exist)

Response

{
  "endpoint": "bulk_binance_liquidations",
  "access_tier": "quant_elite",
  "total_records": 35624285,
  "returned": 10000,
  "limit": 10000,
  "offset": 0,
  "has_more": true,
  "next_offset": 10000,
  "data": [
    {
      "symbol": "BTCUSDT",
      "side": "SELL",
      "price": 96500.0,
      "avg_price": 96312.5,
      "qty": 0.103,
      "usd_size": 9920.19,
      "trade_time": 1771514647172
    }
  ]
}
FieldDescription
symbolTrading pair
sideBUY = short position liquidated, SELL = long position liquidated
price / avg_priceOrder price / average fill price
qtyQuantity
usd_sizeLiquidation value in USD
trade_timeUnix timestamp in milliseconds

Pagination & Rate Limits

Page with limit + offset; follow next_offset until has_more is false. Rate limits: 60 req/s sustained, 200 burst. At limit=100000 the full 35M+ dataset downloads in ~3 minutes.

Python โ€” Download Full Dataset to CSV

import requests, csv, time

API_KEY = "yourkey_qe"
URL = "https://api.moondev.com/api/bulk/binance_liquidations"
limit, offset = 100000, 0

with open("binance_liqs.csv", "w", newline="") as f:
    writer = None
    while True:
        r = requests.get(URL, params={
            "api_key": API_KEY,
            "limit": limit,
            "offset": offset
        }).json()
        if not r["data"]:
            break
        if not writer:
            writer = csv.DictWriter(f, fieldnames=r["data"][0].keys())
            writer.writeheader()
        writer.writerows(r["data"])
        print(f"{offset + len(r['data']):,} / {r['total_records']:,}")
        if not r["has_more"]:
            break
        offset = r["next_offset"]
        time.sleep(0.5)

Position SnapshotsCopy link

Historical snapshots of HyperLiquid positions within 15% of liquidation. Captured every 1 minute โ€” perfect for backtesting liquidation cascade strategies and squeeze detection.

Tracked Symbols

Currently tracking: BTC, ETH, SOL, XRP, HYPE

Filters: Positions within 15% of liquidation, minimum $10k position value, 1-minute snapshots

Endpoints

EndpointDescription
GET /api/position_snapshots/stats?hours=NAggregate statistics across all tracked symbols
GET /api/position_snapshots/symbol/{symbol}?hours=NHistorical snapshots for a symbol (BTC, ETH, SOL, XRP, HYPE)

Query Parameters

ParameterDefaultDescription
hours24Lookback period in hours
limit1000Maximum records to return (symbol endpoint only)
min_distance_pct-Filter: minimum distance to liquidation %
max_distance_pct-Filter: maximum distance to liquidation %
side-Filter: "long" or "short"

Response Example (stats)

{
  "overall": {
    "total_snapshots": 39128,
    "unique_users": 2579,
    "avg_distance_pct": 6.46
  },
  "by_symbol": {
    "BTC": {
      "snapshots": 22952,
      "unique_users": 1710,
      "avg_distance_pct": 5.95,
      "longs": 17646,
      "shorts": 5306
    },
    "ETH": { "snapshots": 8500, "unique_users": 620, "avg_distance_pct": 6.8, "longs": 5200, "shorts": 3300 },
    "SOL": { "snapshots": 4200, "unique_users": 380, "avg_distance_pct": 7.2, "longs": 2800, "shorts": 1400 },
    "XRP": { "snapshots": 2100, "unique_users": 180, "avg_distance_pct": 8.1, "longs": 1400, "shorts": 700 },
    "HYPE": { "snapshots": 1376, "unique_users": 95, "avg_distance_pct": 7.5, "longs": 900, "shorts": 476 }
  },
  "top_10_closest": [
    {
      "user": "0x702f...",
      "symbol": "BTC",
      "side": "long",
      "position_value": 184600,
      "entry_price": 74913.80,
      "liquidation_price": 67164.00,
      "distance_pct": 0.00
    }
  ]
}

Response Example (symbol/BTC)

{
  "symbol": "BTC",
  "snapshots": [
    {
      "snapshot_time": 1738763400000,
      "user": "0xabc123...",
      "symbol": "BTC",
      "side": "long",
      "position_value": 333500,
      "entry_price": 69469.50,
      "liquidation_price": 66859.73,
      "current_price": 68500.00,
      "distance_pct": 2.43,
      "leverage": 20.0
    }
  ],
  "count": 50
}

Response Fields (Snapshot Records)

FieldDescription
snapshot_timeUnix timestamp in milliseconds
userWallet address
symbolBTC, ETH, SOL, XRP, or HYPE
side"long" or "short"
position_valueUSD value of position
distance_pct% distance to liquidation
leveragePosition leverage
entry_priceEntry price
liquidation_priceLiquidation price
current_priceCurrent market price at snapshot time

Curl Examples

# Get stats for last hour
curl "https://api.moondev.com/api/position_snapshots/stats?hours=1" \
  -H "X-API-Key: YOUR_API_KEY"

# Get BTC snapshots (last hour, limit 50)
curl "https://api.moondev.com/api/position_snapshots/symbol/BTC?hours=1&limit=50" \
  -H "X-API-Key: YOUR_API_KEY"

# Get ETH shorts only, within 5% of liquidation
curl "https://api.moondev.com/api/position_snapshots/symbol/ETH?hours=24&side=short&max_distance_pct=5" \
  -H "X-API-Key: YOUR_API_KEY"

Python Example

import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.moondev.com"
headers = {"X-API-Key": API_KEY}

# Get aggregate stats
stats = requests.get(
    f"{BASE_URL}/api/position_snapshots/stats",
    headers=headers,
    params={"hours": 24}
).json()

print(f"Total snapshots: {stats['overall']['total_snapshots']}")
print(f"Unique users: {stats['overall']['unique_users']}")
print(f"Top at risk: {stats['top_10_closest']}")

# Get BTC positions close to liquidation
btc = requests.get(
    f"{BASE_URL}/api/position_snapshots/symbol/BTC",
    headers=headers,
    params={"hours": 24, "limit": 100}
).json()

for snap in btc['snapshots']:
    print(f"{snap['user']}: {snap['distance_pct']}% from liq")

# Filter to very risky positions only
risky = requests.get(
    f"{BASE_URL}/api/position_snapshots/symbol/ETH",
    headers=headers,
    params={"hours": 12, "max_distance_pct": 5}
).json()

Backtesting Use Cases

Since this is historical snapshot data, you can use it for:

  • Liquidation Cascade Detection โ€” Query positions that were <2% from liquidation, cross-reference with price data to see if they got liquidated, build models predicting cascade events
  • Squeeze Setup Identification โ€” Track when shorts cluster near liquidation prices, identify price levels where forced buying would occur, backtest "buy when shorts are trapped" strategies
  • Whale Liquidation Hunting โ€” Monitor large positions approaching liquidation, identify recurring whale addresses and their patterns, backtest strategies targeting known liquidation levels
  • Risk Concentration Analysis โ€” Analyze where leverage clusters by price level, identify "liquidation magnets" (price zones with heavy exposure), backtest contrarian strategies around these zones

Example Backtest Query

# Get all positions that were within 3% of liquidation yesterday
risky_positions = requests.get(
    f"{BASE_URL}/api/position_snapshots/symbol/BTC",
    headers=headers,
    params={"hours": 24, "max_distance_pct": 3, "limit": 5000}
).json()

# Group by snapshot_time to see how risk evolved
# Cross-reference with price data to see which got liquidated
for snap in risky_positions['snapshots']:
    print(f"{snap['snapshot_time']}: {snap['user']} - {snap['distance_pct']}% from liq")

Want to plug this into your trading system? Get your API key here.

Position History (every wallet, every minute)Copy link

NEW: added 2026-10-25

Every Hyperliquid position of $10,000 or more, on every perp and HIP3 market (342 today), rebuilt minute by minute from our own node's fills. Ask what the BTC book looked like at any minute since 2026-10-21, what changed between two times, every open, add, cut, close, flip and liquidation in a window, or one wallet's full position story. It updates every minute and runs about 30 to 60 seconds behind live. Most calls come back in 50 to 200 ms.

EndpointDescription
GET /api/hl/position_history/{coin}/bookEvery position on one market at one minute (now by default, or any past minute with at=), biggest first, with long and short totals
GET /api/hl/position_history/{coin}/diff?from=Which wallets changed their position between two times, with net long and short dollar change and a count by kind
GET /api/hl/position_history/{coin}/changesEvery position change on one market in a window, oldest first, paged
GET /api/hl/position_history/user/{address}One wallet: its open positions now plus its position changes, newest first
GET /api/hl/position_history/statusFreshness (data_through, lag_seconds), history start, the $10k floor, every covered coin, and any gaps

Needs your normal API key (?api_key= or X-API-Key). No key returns 401. Coins are perps (BTC, case does not matter) or HIP3 with the dex (xyz:TSLA, xyz:CL). All times are Unix ms. Every response carries data_through and history_start.

Query parameters

EndpointParamMeaning
bookatThe minute to rebuild (ms). Default now. Anything before history_start returns 400.
booksidelong or short. Default both.
bookmin_usdOnly positions at least this big. Default 10000.
booklimitPositions returned, biggest first. Default 500, max 5,000. total_matching and the long/short totals always cover every match.
difffromRequired. Start time (ms).
difftoEnd time (ms). Default now.
difflimitWallets returned. Max 5,000.
changesstart / endWindow (ms). Default the last hour.
changeslimitChanges per page, max 10,000 (about 2,000 by default). A page always ends on a whole minute, so it can run a few past the limit. If has_more is true, call again with start=next_start.
userstart / endWindow for the change list (ms). Default the last 24 hours.
userlimitChanges returned, newest first. Default 1,000, max 5,000.

Change kinds

Every change has a kind: open (from flat), increase, reduce, close (to flat), flip (long to short or short to long) or liquidated. Sizes are in coins, negative for shorts.

Response Example (/api/hl/position_history/BTC/book?limit=1)

{
  "coin": "BTC",
  "at": 1792936651022,
  "mark_price": 80339.0,
  "min_usd": 10000.0,
  "side": "both",
  "long_usd": 882499099.09,
  "long_count": 2930,
  "short_usd": 1310430967.89,
  "short_count": 1351,
  "count": 1,
  "total_matching": 4281,
  "truncated": true,
  "positions": [
    {
      "address": "0x5b5d51203a0f9079f8aeb098a6523a13f298c060",
      "side": "short",
      "size": -2640.20445,
      "notional_usd": 212111385.31,
      "last_change": 1792913160000
    }
  ],
  "data_through": 1792936651022,
  "history_start": 1792540800000
}

Response Example (/api/hl/position_history/BTC/diff?from=...)

{
  "coin": "BTC",
  "from": 1792933133863,
  "to": 1792934933863,
  "mark_from": 80429.0,
  "mark_to": 80257.0,
  "min_usd": 10000.0,
  "wallets_changed": 201,
  "by_kind": {"open": 19, "increase": 65, "reduce": 52, "close": 24, "flip": 41},
  "net_long_usd_change": -11065828.9,
  "net_short_usd_change": -1915862.62,
  "count": 201,
  "truncated": false,
  "changes": [
    {
      "address": "0xa379bedcc2a237cab1021cc2a4744edfb6c42618",
      "kind": "close",
      "size_before": 164.92724,
      "size_after": 0.0,
      "size_change": -164.92724,
      "usd_before": 13264932.99,
      "usd_after": 0.0,
      "usd_change": -13264932.99,
      "fills": 802
    }
  ]
}

Response Example (/api/hl/position_history/user/{address})

{
  "address": "0x3d7a23552dfddc40b5872cbd148f4f1b4f055c36",
  "start": 1792850311022,
  "end": 1792936711022,
  "current": [
    {"coin": "BTC", "side": "long", "size": 0.66336, "notional_usd": 53293.68}
  ],
  "count": 362,
  "truncated": false,
  "order": "newest_first",
  "changes": [
    {
      "t": 1792936620000,
      "coin": "BTC",
      "kind": "increase",
      "size_before": 0.66321,
      "size_after": 0.66336,
      "size_change": 0.00015,
      "price": 80345.0,
      "usd_after": 53297.66,
      "fills": 1
    }
  ]
}

Python Example

import requests, time

API_KEY = "your_api_key"
BASE = "https://api.moondev.com/api/hl/position_history"
headers = {"X-API-Key": API_KEY}

# Who holds the biggest BTC positions right now?
book = requests.get(f"{BASE}/BTC/book?limit=10", headers=headers).json()
print(f"Longs ${book['long_usd']:,.0f} vs shorts ${book['short_usd']:,.0f}")
for p in book["positions"]:
    print(p["side"], p["address"], f"${p['notional_usd']:,.0f}")

# What changed in the last hour?
now = int(time.time() * 1000)
diff = requests.get(f"{BASE}/BTC/diff?from={now - 3600_000}", headers=headers).json()
print(diff["by_kind"], f"net long change ${diff['net_long_usd_change']:,.0f}")

# Every change in a window, page by page
start, changes = now - 6 * 3600_000, []
while True:
    page = requests.get(f"{BASE}/BTC/changes?start={start}&end={now}", headers=headers).json()
    changes += page["changes"]
    if not page["has_more"]:
        break
    start = page["next_start"]
print(len(changes), "BTC position changes in 6 hours")

Gaps

/api/hl/position_history/status lists any window our node missed under gaps, with the reason. Today that is 2026-10-25 from 09:32 to 12:40 UTC, when the node was down for a Hyperliquid upgrade. Books outside a gap match the node to the last decimal.

Want to plug this into your trading system? Get your API key here.

Liquidation Flow (who takes the liquidations)Copy link

NEW: added 2026-10-27

Every Hyperliquid liquidation, of any size on every perp and HIP3 market, with the wallet that was liquidated and the wallet that took the other side. See who is eating the liquidation flow, whether they were resting on the book (maker) or crossing the spread (taker), and their position before and after. History from 2026-10-21, updated every minute, kept forever. Calls come back in about 0.1 to 0.2 s.

EndpointDescription
GET /api/hl/liquidation_flow/takersLeaderboard of the wallets that took the liquidations in a window, biggest first: dollars taken, share of all flow, count, maker vs backstop dollars, top coins. Plus window totals
GET /api/hl/liquidation_flow/fillsEvery liquidation fill in a window with both wallets, oldest first, paged. Filter by coin, by wallet (as the liquidated one or as the taker) and by method

Needs your normal API key (?api_key= or X-API-Key). No key returns 401. Coins are perps (BTC, case does not matter) or HIP3 with the dex (xyz:TSLA). All times are Unix ms. Every response carries data_through and history_start; asking for anything before 2026-10-21 returns 400.

Query parameters

EndpointParamMeaning
bothstart / endWindow (ms). Default the last 24 hours. Windows up to 31 days.
bothcoinOne market, e.g. BTC or xyz:EWZ. Default every market.
bothmethodmarket (filled on the order book) or backstop (taken by the liquidator vault). Default both.
takerslimitWallets returned, 1 to 1,000. Default 100. total always covers the whole window.
fillsaddressOnly liquidations involving this wallet.
fillsroleWith address: liquidated (it got liquidated) or taker (it took the other side).
fillslimitFills per page, 1 to 10,000. Default 1,000. If has_more is true, call again with start=next_start.

Response Example (takers)

{
  "coin": null,
  "start": 1793021821298,
  "end": 1793108221298,
  "method": null,
  "total": {
    "liquidations": 5482,
    "usd": 11433816.13,
    "usd_market": 11428245.21,
    "usd_backstop": 5570.92,
    "takers": 988,
    "liquidated_wallets": 1800
  },
  "count": 100,
  "takers": [
    {
      "address": "0x25773676902085225ae5751075e4161369334897",
      "usd": 619452.41,
      "share": 0.0542,
      "liquidations": 108,
      "maker_usd": 619452.41,
      "backstop_usd": 0,
      "coins": 25,
      "top_coins": [
        { "coin": "io:NBIS", "usd": 134393.49 },
        { "coin": "xyz:CRWV", "usd": 127254.53 },
        { "coin": "BTC", "usd": 80811.24 }
      ],
      "first": 1793022598701,
      "last": 1793107986924
    }
  ],
  "data_through": 1793108221297,
  "history_start": 1792540800000
}

Response Example (fills)

{
  "coin": "BTC",
  "start": 1793021821298,
  "end": 1793108221298,
  "address": null,
  "role": null,
  "method": null,
  "count": 1,
  "liquidations": [
    {
      "t": 1793026697729,
      "coin": "BTC",
      "tid": 405580047710537,
      "hash": "0xc3c5f710886aea8c...",
      "method": "market",
      "liquidated": "0xd4802f72024d88fef5ee4991423073605aa084ce",
      "liquidated_side": "short",
      "size": 0.00178,
      "px": 80353.0,
      "usd": 143.03,
      "mark_px": 80344.0,
      "liquidated_size_before": -0.00178,
      "counterparty": "0x6e8bc7cd0978397b06a14af2a8c31f5daeffea79",
      "counterparty_role": "maker",
      "counterparty_size_before": -20.60243,
      "counterparty_size_after": -20.60421
    }
  ],
  "next_start": 1793026697730,
  "has_more": true,
  "data_through": 1793108221297,
  "history_start": 1792540800000
}
FieldMeaning
liquidated / liquidated_sideThe wallet that got liquidated and the side it was on (long or short)
size / px / usd / mark_pxSize of this liquidation fill, its fill price, its dollar value, and the mark price used
liquidated_size_beforeThe liquidated wallet's position before this fill (negative = short)
methodmarket = filled on the order book, backstop = taken by the liquidator vault
counterpartyThe wallet that took the other side of the liquidation, lower case
counterparty_rolemaker = its order was resting on the book, taker = it crossed the spread to hit the liquidation
counterparty_size_before / _afterThe taking wallet's position before and after the fill (negative = short)

Python

import requests

KEY = "YOUR_KEY"
BASE = "https://api.moondev.com/api/hl/liquidation_flow"

# Who took the BTC liquidations in the last 24 hours?
top = requests.get(f"{BASE}/takers", params={"coin": "BTC", "limit": 10, "api_key": KEY}).json()
print(f"${top['total']['usd']:,.0f} liquidated, {top['total']['takers']} wallets took the other side")
for t in top["takers"]:
    print(t["address"], f"${t['usd']:,.0f}", f"{t['share']:.1%}")

# Every liquidation one wallet has taken this week
wallet = top["takers"][0]["address"]
start, fills = None, []
while True:
    params = {"address": wallet, "role": "taker", "limit": 10000, "api_key": KEY}
    if start:
        params["start"] = start
    page = requests.get(f"{BASE}/fills", params=params).json()
    fills += page["liquidations"]
    if not page["has_more"]:
        break
    start = page["next_start"]
print(len(fills), "liquidations taken by", wallet)

What it shows (2026-10-21 to 10-27)

$394M liquidated across 103k fills and about 24,800 wallets, taken by about 6,300 different wallets. 98% went to market makers' resting orders, not to bots crossing the spread. The top 20 takers took 37%, the single biggest took $25M. HLP took only $0.34M. Backstop liquidations were $8.4M, almost all on xyz:EWZ.

Want to plug this into your trading system? Get your API key here.

Smart MoneyCopy link

EndpointDescription
GET /api/smart_money/rankings.jsonTop 100 smart + Bottom 100 dumb money by PnL
GET /api/smart_money/leaderboard.jsonTop 50 performers with detailed metrics
GET /api/smart_money/signals_10m.jsonTrading signals - last 10 minutes
GET /api/smart_money/signals_1h.jsonTrading signals - last 1 hour
GET /api/smart_money/signals_24h.jsonTrading signals - last 24 hours

Response Example (rankings.json)

{
  "updated_at": "2026-01-06T19:17:19Z",
  "total_tracked_addresses": 3488,
  "smart_money": {
    "description": "Top 100 most profitable addresses",
    "count": 100,
    "addresses": [
      {
        "address": "0x...",
        "total_pnl": 5000000.00,
        "win_rate": 0.72,
        "total_trades": 500
      }
    ]
  },
  "dumb_money": {
    "description": "Bottom 100 least profitable addresses",
    "count": 100,
    "addresses": []
  }
}

Response Example (signals_1h.json)

{
  "updated_at": "2026-01-06T19:17:19Z",
  "duration": "1h",
  "signals": [
    {
      "timestamp": "2026-01-06T19:15:00Z",
      "address": "0x...",
      "address_type": "smart_money",
      "action": "open_long",
      "coin": "BTC",
      "size": 2.5,
      "price": 92000.0,
      "leverage": 10
    }
  ]
}

Trades & Order FlowCopy link

EndpointDescription
GET /api/trades.jsonRecent trades (last 1000)
GET /api/large_trades.jsonLarge trades only (>$100k)
GET /api/orderflow.jsonCurrent order flow metrics
GET /api/orderflow/stats.jsonOrder flow statistics
GET /api/imbalance/5m.jsonBuy/sell imbalance - 5 minutes
GET /api/imbalance/15m.jsonBuy/sell imbalance - 15 minutes
GET /api/imbalance/1h.jsonBuy/sell imbalance - 1 hour
GET /api/imbalance/4h.jsonBuy/sell imbalance - 4 hours
GET /api/imbalance/24h.jsonBuy/sell imbalance - 24 hours

Orderflow Expansion: Now tracking 130 symbols across all Hyperliquid coins!

Every coin on Hyperliquid is now tracked for buy/sell imbalance, enabling pairs trading discovery and cross-market analysis.

Data Retention Policy

  • Raw trade data: Retained for 90 days, then auto-deleted. Export if you need it longer!
  • Hourly aggregates: Kept permanently (forever) for historical backtesting. Per-symbol buy/sell pressure every hour.

Response Example (trades.json)

{
  "updated_at": "2026-01-06T19:17:00Z",
  "trade_count": 1000,
  "trades": [
    {
      "timestamp": 1767727000000,
      "coin": "BTC",
      "side": "buy",
      "size": 0.5,
      "price": 92000.0,
      "value_usd": 46000.0,
      "is_large": false
    }
  ]
}

Response Example (orderflow.json)

{
  "updated_at": "2026-01-06T19:17:00Z",
  "window": "5m",
  "metrics": {
    "BTC": {
      "buy_volume": 5000000.0,
      "sell_volume": 4500000.0,
      "net_flow": 500000.0,
      "buy_count": 150,
      "sell_count": 140,
      "imbalance_ratio": 1.11
    }
  }
}

Response Example (imbalance/1h.json)

Now returns data for all 130 tracked symbols:

{
  "time_window": "1h",
  "overall": {
    "buy_volume_usd": 923134333.04,
    "sell_volume_usd": 1146007719.76,
    "imbalance_ratio": -0.1077,
    "dominant_side": "SELL"
  },
  "by_coin": {
    "BTC": {
      "buy_volume_usd": 616856512.28,
      "sell_volume_usd": 814592126.43,
      "net_imbalance_usd": -197735614.15,
      "imbalance_ratio": -0.1381,
      "buy_count": 15420,
      "sell_count": 18350,
      "dominant_side": "SELL"
    },
    "ETH": { "..." : "..." },
    "SOL": { "..." : "..." },
    "ADA": { "..." : "..." },
    "EIGEN": { "..." : "..." },
    "...": "130 symbols total"
  }
}

Each symbol includes:

  • buy_volume_usd / sell_volume_usd - Volume in USD
  • net_imbalance_usd - Net buy/sell imbalance
  • imbalance_ratio - Ratio (-1.0 to 1.0, negative = sell pressure)
  • buy_count / sell_count - Number of trades
  • dominant_side - Either BUY or SELL

Pairs Trading Example

With 130 symbols, you can compare imbalance across any two coins for pairs trading signals:

import requests

API_KEY = "your_api_key"

r = requests.get(
    "https://api.moondev.com/api/imbalance/1h.json",
    headers={"X-API-Key": API_KEY}
).json()

# Compare any two coins for pairs trading
ada = r["by_coin"]["ADA"]["imbalance_ratio"]
eigen = r["by_coin"]["EIGEN"]["imbalance_ratio"]
spread = ada - eigen  # Your entry signal!

print(f"ADA imbalance: {ada:.4f}")
print(f"EIGEN imbalance: {eigen:.4f}")
print(f"Spread: {spread:.4f}")

Exporting Raw Data (Before 90-Day Expiry)

Raw trade data is auto-deleted after 90 days. Pull and store locally if you need it longer:

import requests, json

API_KEY = "your_api_key"

# Pull all recent trades and save locally
trades = requests.get(
    "https://api.moondev.com/api/trades.json",
    headers={"X-API-Key": API_KEY}
).json()

with open("trades_backup.json", "w") as f:
    json.dump(trades, f)

print(f"Saved {trades['trade_count']} trades")

User Data (Local Node)Copy link

Get positions and trade history for any Hyperliquid wallet. Powered by Moon Dev's local node for fast responses.

EndpointDescription
GET /api/user/{address}/positionsCurrent positions for any wallet
GET /api/user/{address}/fills?limit=NHistorical fills (default: 100, max: 2000, -1 for ALL)
GET /api/user/{address}/flowNet buy/sell flow over a time window โ€” cap-proof, server-side aggregate (NEW)

Fills Query Parameters (time windows added 2026-08-13)

ParamTypeDescription
limitintegerMax fills to return (default 100, max 2000, -1 = all). Unchanged โ€” combines with the window.
minutesnumber, 0โ€“4320Only return fills from the last N minutes. Strongly recommended for polling โ€” activates the fast lane (see note below).
since_msintegerOnly return fills at/after this epoch-milliseconds timestamp. Same fast lane. If both are given, the later (narrower) one wins.
curl "https://api.moondev.com/api/user/0xABC.../fills?minutes=10&limit=2000&api_key=YOUR_KEY"

โšก Use a time window when polling

Passing a time window makes every wallet equally fast (~50ms) regardless of how many fills it has. Without a window, first contact with a fill-sparse wallet forces a full 3-day archive scan that can take ~30s (returns 200, it's just slow). For deep history, page backwards with since_ms windows instead of one giant call.

โš ๏ธ Window size is the performance dial

Small windows (โ‰ค60 min) are the hot path โ€” ~50ms for any wallet. The maximum (minutes=4320, 3 days) is effectively a full-archive scan and can take 30โ€“60s on a cold cache: it's a deep-history call, not a polling call. If you need deep history on a schedule, page through it in smaller windows.

The fills response now echoes since_ms โ€” the resolved window start (null when no window was passed) โ€” so clients can assert the server honored their window.

Response Example (positions)

{
  "address": "0xABC123...",
  "positions": [
    {
      "symbol": "BTC",
      "side": "long",
      "size": 0.5,
      "size_usd": 21250,
      "entry_price": 42500,
      "mark_price": 42800,
      "unrealized_pnl": 150,
      "leverage": 10
    }
  ],
  "total_value": 45000,
  "margin_used": 4500
}

Response Example (fills)

{
  "address": "0xABC123...",
  "fills": [
    {
      "coin": "BTC",
      "side": "A",
      "px": 80278.0,
      "sz": 0.25536,
      "value_usd": 20499.79,
      "time": 1793104908590,
      "timestamp": "2026-10-27T12:41:48.590000+00:00",
      "dir": "Open Short",
      "closedPnl": 0.0,
      "fee": -0.614993,
      "feeToken": "USDC",
      "hash": "0x305bae4e...",
      "oid": 587247279724,
      "tid": 184579510914126,
      "crossed": false,
      "startPosition": "0.0",
      "liquidation": null,
      "counterparty": "0x8fc63e5b8166253346b95b747c4e0a73bc8944fb",
      "counterparty_order": {
        "oid": 587247342306,
        "crossed": true,
        "has_cloid": true,
        "twap": false,
        "tif": null,
        "orig_sz": null,
        "limit_px": null
      }
    }
  ],
  "total_count": 1543,
  "since_ms": 1765183800000,
  "order": "newest_first",
  "truncated": true,
  "newest_ms": 1786651098765,
  "oldest_ms": 1786650012345,
  "page_summary": {
    "scope": "returned_page",
    "total_pnl": 1250.40,
    "total_volume": 185000.00,
    "total_fees": 92.50
  },
  "summary": "(deprecated alias of page_summary)"
}

New Response Fields (added 2026-08-13)

FieldMeaning
orderAlways "newest_first" โ€” see the ordering guarantee below
truncatedtrue iff limit cut off older in-window fills. Exact, not inferred โ€” count == limit with truncated: false means the window genuinely held exactly that many
newest_ms / oldest_msReal time coverage of the returned page; oldest_ms is the paging cursor
page_summaryPnL/volume/fees of the returned page only, never the whole window (use /flow for window-true aggregates). summary remains as a deprecated alias

NEW: added 2026-10-27

Counterparty on every fill

Every fill from /api/user/{address}/fills now names the wallet on the other side of the trade, for all the history we hold (back to 2026-10-25). Our node writes both sides of every trade, so each fill is matched to the other side with the same coin and tid. No extra call, same speed.

FieldMeaning
counterpartyLower case address of the other wallet in this trade. On a liquidation fill it is the wallet that took the other side; on a self trade it is the address itself. null only for outcome market fills (coins starting with #), which have no second side in the node data
counterparty_order.oidThe other side's order id
counterparty_order.crossedtrue = the other side took liquidity (taker), false = it was resting (maker). Always the opposite of your own crossed
counterparty_order.has_cloidtrue if the other side sent a client order id (usually a bot)
counterparty_order.twaptrue if the other side's fill came from a TWAP order
counterparty_order.tif, orig_sz, limit_pxAlways null for now. Our node does not record order details yet, so get these from Hyperliquid if you need them

Only on /api/user/{address}/fills. The Hyperliquid compatible /api/fills/{address} keeps Hyperliquid's exact shape. Also fixed on 2026-10-27: this endpoint now returns only the wallet's own fills. Before, a liquidated wallet could get the liquidator's fill too, and a builder address could get other people's fills.

โš ๏ธ Ordering guarantee (permanent API contract)

Fills are always returned descending (newest first). When limit caps the result, the newest fills are kept and the oldest dropped. This is a permanent API contract, and it is intentionally the opposite of HyperLiquid's userFillsByTime (which returns ascending and keeps the oldest 2000 โ€” silently blinding recency-based consumers on busy wallets). Build recency signals against this endpoint with confidence; it will not flip for HL parity.

New 503 response (both fills endpoints)

{
  "error": "Service Busy",
  "message": "Fills scanner is at its concurrency limit - retry shortly or use your fallback source",
  "code": "fills_scanner_busy"
}

Retry shortly or fall back โ€” do not treat a 503 as an empty result. The flip side is now guaranteed: an empty fills array with HTTP 200 genuinely means the wallet has no fills. (Previously it could also mean "scanner busy" โ€” if you coded around that old ambiguity, you can drop the workaround.)

Net Flow (NEW โ€” added 2026-08-13)

GET /api/user/{address}/flow โ€” net flow for a wallet over a time window. Answers "has this wallet net-bought or net-sold since T?" in one call. Aggregates all fills in the window server-side with no result cap, so the answer can never be truncated โ€” correct even on wallets with tens of thousands of fills. Standard auth (?api_key= / X-API-Key / Bearer).

ParamTypeRequiredDescription
since_msinteger (epoch ms)one of these twoWindow start, absolute
minutesnumber (0โ€“4320)one of these twoWindow: last N minutes. If both given, the later (narrower) wins
coinstringnoExact symbol (e.g. BTC). Omit for a per-coin breakdown
curl "https://api.moondev.com/api/user/0xABC.../flow?minutes=60&coin=BTC&api_key=YOUR_KEY"

โš ๏ธ Window size is the performance dial. Small windows (โ‰ค60 min) are the hot path โ€” ~50ms for any wallet. The maximum (minutes=4320, 3 days) is effectively a full-archive scan and can take 30โ€“60s on a cold cache: it's a deep-history call, not a polling call. If you need deep history on a schedule, page through it in smaller windows.

Response Example (with coin)

{
  "address": "0x...",
  "since_ms": 1786650000000,
  "coin": "BTC",
  "bought_sz": 1.08012,
  "sold_sz": 0.77272,
  "net_sz": 0.3074,
  "bought_usd": 68540.12,
  "sold_usd": 49102.77,
  "net_usd": 19437.35,
  "count": 8,
  "first_ms": 1786650012345,
  "last_ms": 1786651098765,
  "truncated": false
}

net_sz = bought_sz โˆ’ sold_sz (positive = net buyer). truncated is always false โ€” kept in the shape so clients can share response handling with /fills.

Without coin: same envelope, plus "coins": {"BTC": {โ€ฆ}, "ETH": {โ€ฆ}} (each with the fields above) and USD totals only at the top level โ€” coin sizes aren't comparable across coins, so there's no global size total.

Errors: 400 window_required (a window is mandatory โ€” this endpoint answers recency questions), 503 fills_scanner_busy (retry or fall back), 401 standard.

Python Example

import requests

API_KEY = "your_api_key"
WALLET = "0x1234567890abcdef..."

# Get positions
positions = requests.get(
    f"https://api.moondev.com/api/user/{WALLET}/positions",
    headers={"X-API-Key": API_KEY}
).json()

print(f"Total Value: ${positions['total_value']:,.2f}")
for pos in positions["positions"]:
    print(f"  {pos['symbol']} {pos['side']}: ${pos['size_usd']:,.0f}")

# Poll recent fills (fast lane โ€” ~50ms for any wallet)
recent = requests.get(
    f"https://api.moondev.com/api/user/{WALLET}/fills?minutes=10&limit=2000",
    headers={"X-API-Key": API_KEY}
)
if recent.status_code == 503:
    # fills_scanner_busy โ€” retry shortly or use your fallback source
    print("Scanner busy, retrying shortly...")
else:
    data = recent.json()
    print(f"Fills in last 10 min: {data['total_count']} (window start: {data['since_ms']})")
    if data["truncated"]:
        # newest fills kept โ€” page backwards from oldest_ms for the rest
        print(f"Page covers {data['oldest_ms']} โ†’ {data['newest_ms']}, older fills cut off")

# Net flow โ€” has this wallet net-bought or net-sold in the last hour?
# Cap-proof: aggregated server-side over EVERY fill in the window
flow = requests.get(
    f"https://api.moondev.com/api/user/{WALLET}/flow?minutes=60&coin=BTC",
    headers={"X-API-Key": API_KEY}
).json()
side = "net BUYER" if flow["net_usd"] > 0 else "net SELLER"
print(f"BTC last hour: {side} of ${abs(flow['net_usd']):,.0f} ({flow['count']} fills)")

# Get ALL fills (no window โ€” first contact with a fill-sparse
# wallet can take ~30s; prefer paging with since_ms windows)
fills = requests.get(
    f"https://api.moondev.com/api/user/{WALLET}/fills?limit=-1",
    headers={"X-API-Key": API_KEY}
).json()

print(f"Total trades: {fills['total_count']}")

HLP (Hyperliquidity Provider)Copy link

Complete reverse engineering of Hyperliquid's native market-making protocol (~$210M+ AUM, 7 strategies).

EndpointDescription
GET /api/hlp/positionsAll 7 HLP strategy positions + combined net exposure
GET /api/hlp/positions?include_strategies=falseSummary only (faster response)
GET /api/hlp/positions/history?hours=NPosition snapshots over time
GET /api/hlp/liquidatorsLiquidator activation events
GET /api/hlp/deltas?hours=NNet exposure changes over time

Response Example (positions)

{
  "total_value_usd": 210000000,
  "net_exposure": {
    "BTC": {"long": 125000000, "short": 98000000, "net": 27000000},
    "ETH": {"long": 85000000, "short": 92000000, "net": -7000000}
  },
  "strategies": [
    {
      "name": "Strategy A",
      "vault_address": "0x...",
      "value_usd": 45000000,
      "positions": [
        {"symbol": "BTC", "side": "long", "size_usd": 12000000}
      ]
    }
  ]
}

Response Example (deltas)

{
  "deltas": [
    {
      "timestamp": "2026-01-08T10:00:00Z",
      "BTC": {"delta": 500000, "direction": "more_long"},
      "ETH": {"delta": -200000, "direction": "more_short"}
    }
  ]
}

Python Example

import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.moondev.com"

# Get HLP positions (full details)
hlp = requests.get(
    f"{BASE_URL}/api/hlp/positions",
    headers={"X-API-Key": API_KEY}
).json()

print(f"Total HLP Value: ${hlp['total_value_usd']:,.0f}")
print(f"Strategies: {len(hlp['strategies'])}")

# Net exposure per coin
for coin, exp in hlp["net_exposure"].items():
    direction = "LONG" if exp["net"] > 0 else "SHORT"
    print(f"  {coin}: ${abs(exp['net']):,.0f} {direction}")

# Position snapshots over the last 24 hours
history = requests.get(
    f"{BASE_URL}/api/hlp/positions/history?hours=24",
    headers={"X-API-Key": API_KEY}
).json()

HLP data collection started Nov 3, 2025. Historical analysis covers this full period.

This data is nowhere else. Get your API key and start using it.

HLP Sentiment & AnalyticsCopy link

Advanced analytics endpoints for HLP sentiment analysis, liquidator monitoring, market maker tracking, and timing analysis. These endpoints provide institutional-grade signals based on HLP positioning data.

Available Endpoints

EndpointDescription
GET /api/hlp/sentimentNet delta with z-scores and trading signals - THE sentiment indicator
GET /api/hlp/liquidators/statusReal-time liquidator status (active/idle) with PnL
GET /api/hlp/market-makerStrategy B tracker for BTC/ETH/SOL positions
GET /api/hlp/timingHourly and session profitability analysis
GET /api/hlp/correlationDelta-price correlation analysis by coin

Sentiment Analysis (The Big One)

The /api/hlp/sentiment endpoint analyzes HLP net delta positions and generates z-score based trading signals. This is the primary sentiment indicator for understanding institutional positioning.

curl "https://api.moondev.com/api/hlp/sentiment?api_key=YOUR_KEY"

Response Example

{
  "timestamp": "2025-01-12T15:30:00Z",
  "net_delta": {
    "BTC": { "value": -2450000, "z_score": 2.2, "signal": "Retail heavily SHORT - potential short squeeze" },
    "ETH": { "value": 1200000, "z_score": -0.8, "signal": "Neutral positioning" },
    "SOL": { "value": -580000, "z_score": 1.5, "signal": "Moderate retail SHORT bias" }
  },
  "overall_signal": "Market sentiment: Retail skewed SHORT on majors",
  "confidence": "high"
}

Liquidator Status

Monitor liquidator wallet activity in real-time. Track which liquidators are active/idle and their recent PnL.

curl "https://api.moondev.com/api/hlp/liquidators/status?api_key=YOUR_KEY"

Market Maker (Strategy B)

Track Strategy B market maker positions across BTC, ETH, and SOL. Useful for understanding MM inventory and potential mean reversion.

curl "https://api.moondev.com/api/hlp/market-maker?api_key=YOUR_KEY"

Timing Analysis

Analyze HLP profitability by hour of day and trading session. Identify optimal trading windows based on historical HLP performance.

curl "https://api.moondev.com/api/hlp/timing?api_key=YOUR_KEY"

Correlation Analysis

Analyze correlation between HLP delta changes and price movements by coin. Higher correlation suggests stronger predictive signal.

curl "https://api.moondev.com/api/hlp/correlation?api_key=YOUR_KEY"

Python Example

import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.moondev.com"

# Get HLP sentiment signals
sentiment = requests.get(
    f"{BASE_URL}/api/hlp/sentiment",
    params={"api_key": API_KEY}
).json()

print(f"Overall: {sentiment['overall_signal']}")
print(f"Confidence: {sentiment['confidence']}")

for coin, data in sentiment["net_delta"].items():
    print(f"  {coin}: z={data['z_score']:.1f} - {data['signal']}")

# Check liquidator activity
liquidators = requests.get(
    f"{BASE_URL}/api/hlp/liquidators/status",
    params={"api_key": API_KEY}
).json()

for liq in liquidators.get("liquidators", []):
    status = "ACTIVE" if liq["active"] else "IDLE"
    print(f"  {liq['address'][:10]}...: {status} (PnL: ${liq['pnl']:,.0f})")

Polymarket Profitable TradersCopy link

Follow the smart money in prediction markets. Moon Dev's backend continuously scans Polymarket and surfaces the wallets actually making money, ranked by 7-day P&L.

Overview

FieldValue
EndpointGET /api/poly/profitable-traders
SDK methodMoonDevAPI().get_poly_profitable_traders()
Exampleexamples/34_polymarket_traders.py
AuthAPI key required (MOONDEV_API_KEY)
ParametersNone

How traders are discovered

The service finds profitable traders from two live discovery sources, then keeps only wallets clearing a $300+ 7-day P&L threshold:

  • BTC 5m (source: "btc_5m") โ€” traders active in BTC 5-minute prediction markets.
  • Trending (source: "trending") โ€” traders making big trades ($500+) in trending markets.

Results are always sorted by 7-day P&L, highest first.

Endpoints

MethodEndpointAuthDescription
GET/api/poly/profitable-tradersYesProfitable Polymarket traders sorted by 7-day P&L
GET/api/poly/healthNoPolymarket service health check

Access Tiers

TierAPI KeyWhat You Get
Standardregular keyTop 25 traders
Quant Elite_qe keyFull list of all profitable traders

The full_list field in the response confirms which tier you received (true = full Quant Elite list, false = standard top 25).

cURL

curl "https://api.moondev.com/api/poly/profitable-traders?api_key=YOUR_API_KEY"

Python (SDK)

from api import MoonDevAPI

api = MoonDevAPI()  # reads MOONDEV_API_KEY from .env
data = api.get_poly_profitable_traders()

for trader in data["traders"]:
    print(f"{trader['wallet']}: ${trader['pnl_7d']:,.2f} P&L | ${trader['volume_7d']:,.2f} volume")
    print(f"  Profile: {trader['polymarket_link']}")

Python (requests)

import requests

response = requests.get(
    "https://api.moondev.com/api/poly/profitable-traders",
    headers={"X-API-Key": "YOUR_API_KEY"}
)
data = response.json()

for trader in data["traders"]:
    print(f"{trader['wallet']}: ${trader['pnl_7d']:,.2f} P&L ({trader['trades_7d']} trades)")
    print(f"  Profile: {trader['polymarket_link']}")

JavaScript

const response = await fetch(
  "https://api.moondev.com/api/poly/profitable-traders",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await response.json();

data.traders.forEach(t => {
  const short = `${t.wallet.slice(0,6)}...${t.wallet.slice(-4)}`;
  console.log(`${short}: $${t.pnl_7d.toFixed(2)} P&L (${t.trades_7d} trades)`);
});

Response Format

{
  "total": 2894,
  "full_list": true,
  "updated_at": "2026-04-14T15:41:42.182139+00:00",
  "stats": {
    "wallets_checked": 1163,
    "queue_depth": 0,
    "uptime_minutes": 5.3
  },
  "traders": [
    {
      "wallet": "0x8c80d213c0cbad777d06ee3f58f6ca4bc03102c3",
      "polymarket_link": "https://polymarket.com/0x8c80d213c0cbad777d06ee3f58f6ca4bc03102c3",
      "pnl_7d": 1183556.88,
      "volume_7d": 1376544.64,
      "trades_7d": 470,
      "redeems_7d": 1,
      "discovered_at": "2026-04-13T22:50:05.965342+00:00",
      "source": "trending"
    }
  ]
}

Top-Level Fields

FieldTypeDescription
totalintegerNumber of traders returned in this response
full_listbooleantrue for Quant Elite keys, false for standard keys (top 25)
updated_atstringISO 8601 timestamp of when this response was generated
statsobjectService health metrics
tradersarrayProfitable traders sorted by pnl_7d descending

Stats Object

FieldTypeDescription
wallets_checkedintegerTotal wallets analyzed since service start
queue_depthintegerWallets waiting to be analyzed (0 = fully caught up)
uptime_minutesfloatService uptime in minutes

Trader Object

FieldTypeDescription
walletstringEthereum wallet address (0x...) โ€” use this as the identifier
polymarket_linkstringDirect link to Polymarket profile (wallet-based)
pnl_7dfloat7-day profit & loss in USD. Minimum $300
volume_7dfloat7-day trading volume in USD
trades_7dintegerNumber of trades in last 7 days
redeems_7dintegerNumber of winning redemptions in last 7 days
discovered_atstringISO 8601 timestamp of when wallet was discovered
sourcestringDiscovery source: "trending" or "btc_5m"

Breaking Changes (2026-04-14)

If you integrated before 2026-04-14, update your code:

ChangeBeforeAfter
name fieldPresent (Polymarket pseudonym)Removed โ€” was unreliable
display_name fieldPresentRemoved
polymarket_linkhttps://polymarket.com/@Usernamehttps://polymarket.com/<wallet>

Migration: Replace any usage of name or display_name with wallet. The wallet address is now the only stable identifier, and polymarket_link is wallet-based so it will never break due to username changes.

Data Freshness

MetricFrequency
Scanner discoveryEvery 5 minutes
P&L recalculationContinuous (5 worker threads)
Seen wallets resetEvery 6 hours (fresh re-evaluation)
JSON snapshot to diskEvery 60 seconds

How It Works

  1. BTC 5-Min Scanner โ€” Every 5 min, scans the 3 most recently closed BTC up/down prediction markets and discovers all trading wallets
  2. Trending Markets Scanner โ€” Every 5 min, fetches top 50 markets by 24h volume, filters for trades where size x price >= $500
  3. P&L Workers (5 threads) โ€” Fetches 7-day activity per wallet, computes P&L = sells + redemptions - buys
  4. Filter โ€” Only traders with P&L >= $300 are included
  5. Persistence โ€” Results survive restarts via periodic JSON snapshots

Use Cases

  • Copy-trade profitable Polymarket traders (follow the wallet)
  • Identify sharp money in prediction markets
  • Track consistent winners on BTC 5-min markets
  • Monitor whale activity on trending markets
  • Build alerts when new highly-profitable wallets are discovered

Run the example

python examples/34_polymarket_traders.py

The example renders a full terminal dashboard: a service-stats panel, a detailed Top 10 leaderboard, a compact full list, summary stat cards (combined P&L, combined volume, total trades, and a discovery-source breakdown), and a footer.

Related Polymarket endpoints

  • GET /api/poly/whales โ€” live whale trade log ($1,000+ fills, newest first)
  • GET /api/poly/whales/top-traders โ€” whale leaderboard by wallet
  • GET /api/poly/whales/top-markets โ€” whale leaderboard by market
  • GET /api/poly/whales/daily โ€” per-day whale activity rollup (charting)
  • GET /api/poly/whales/health โ€” whale ingestion status (no auth)
  • GET /api/poly/health โ€” Polymarket service health (no auth)

Polymarket Whales APICopy link

Live whale tracker for Polymarket prediction markets. A background service maintains a persistent WebSocket to wss://ws-live-data.polymarket.com and records every trade with USD notional โ‰ฅ $1,000 into a database. Query by time window, dollar threshold, wallet, and market.

Authentication & Rate Limits

Pass your key as ?api_key=YOUR_KEY query param, X-API-Key: YOUR_KEY header, or Authorization: Bearer YOUR_KEY. Keys ending in _qe get the full result set; standard keys are capped per endpoint. Rate limit: 60 req/sec sustained, 200 burst (shared across all API endpoints).

Endpoints

MethodEndpointAuthDescription
GET/api/poly/whalesYesRecent whale trade log (newest first)
GET/api/poly/whales/top-tradersYesLeaderboard by wallet over the window
GET/api/poly/whales/top-marketsYesLeaderboard by market over the window
GET/api/poly/whales/dailyYesPer-day OHLCV-style rollup of whale activity
GET/api/poly/whales/healthNoService status & live ingestion counters

GET /api/poly/whales โ€” recent whale trade log

Returns individual whale fills, newest first.

ParamDefaultNotes
min_usd1000Minimum trade size in USD. Floor is $1,000 โ€” anything below is never collected.
days1Lookback window. Max 365.
walletโ€”Filter to a single wallet address (proxyWallet).
marketโ€”Filter by market_slug or event_slug.
sideโ€”BUY or SELL.
limit250Max rows. Standard keys capped at 250, _qe keys up to 5,000.

Example:

curl "https://api.moondev.com/api/poly/whales?api_key=YOUR_API_KEY&min_usd=5000&days=7&side=BUY"

Each trade includes: ts, wallet, pseudonym, market_title, market_slug, event_slug, outcome, side, price, size, usd_amount, tx_hash.

GET /api/poly/whales/top-traders โ€” leaderboard by wallet

Aggregates whale trades per wallet over the window.

ParamDefaultNotes
min_usd1000
days7
limit100Standard keys capped at 50, _qe up to 1,000.

Returns per wallet: trade_count, total_volume, biggest_trade, markets_traded, last_trade_ts. Sorted by total_volume desc.

GET /api/poly/whales/top-markets โ€” leaderboard by market

Same shape as top-traders but grouped by market.

ParamDefault
min_usd1000
days7
limit100

Returns per market: market_slug, event_slug, market_title, whale_trades, whale_volume, unique_whales, biggest_trade.

GET /api/poly/whales/daily โ€” per-day rollup

OHLCV-style daily summary of whale activity. Use this for charting.

ParamDefault
min_usd1000
days30

Returns one row per UTC day: trade_count, total_volume, biggest_trade, smallest_trade, avg_trade, unique_whales, unique_markets.

GET /api/poly/whales/health โ€” service status (no auth)

Live counters: trades_seen, whales_queued, whales_written, biggest_usd, biggest_market, ws_connects, ws_disconnects, last_trade_at, queue_depth, uptime_minutes. Useful for confirming the WebSocket is connected and ingestion is fresh.

Python (Moon Dev SDK)

from api import MoonDevAPI

api = MoonDevAPI()

whales      = api.get_poly_whales(min_usd=5000, days=7, side="BUY")
top_wallets = api.get_poly_whale_top_traders(days=7)
top_markets = api.get_poly_whale_top_markets(days=7)
daily       = api.get_poly_whale_daily(days=30)
status      = api.poly_whales_health()   # no auth required

for trade in whales["trades"]:
    print(f"{trade['ts']} {trade['side']} ${trade['usd_amount']:,.0f} | {trade['market_title']}")
    print(f"  wallet: {trade['wallet']}  tx: {trade['tx_hash']}")

Python (requests)

import requests

response = requests.get(
    "https://api.moondev.com/api/poly/whales",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"min_usd": 5000, "days": 7, "side": "BUY"},
)
data = response.json()

for trade in data["trades"]:
    print(f"{trade['ts']} {trade['side']} ${trade['usd_amount']:,.0f} | {trade['market_title']}")

JavaScript

const url = new URL("https://api.moondev.com/api/poly/whales");
url.searchParams.set("min_usd", "5000");
url.searchParams.set("days", "7");
url.searchParams.set("side", "BUY");

const response = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
const data = await response.json();

data.trades.forEach(t => {
  console.log(`${t.ts} ${t.side} $${t.usd_amount.toLocaleString()} | ${t.market_title}`);
});

How It Works (Internals)

  • Service: poly-whales.service (systemd, auto-restart, 512 MB / 50% CPU caps). Code: data-layer/scripts/poly_whales.py. Internal port 8105, exposed via nginx behind Cloudflare.
  • Ingestion: subscribes to {topic: "activity", type: "orders_matched"}. Filters price * size < $1,000 in-process before any DB write โ€” cheapest possible reject.
  • Storage: SQLite at data-layer/data/polymarket/whales.db, WAL mode. Indexed on ts, wallet, market_slug, event_slug, usd_amount. Dedup via dedup_key UNIQUE (transaction hash when present, composite of ts|wallet|asset_id|size|price otherwise) โ€” safe across WebSocket reconnects.
  • Writes: batched every 5 s or 500 rows, whichever comes first. Application-layer ping every 30 s keeps the WebSocket alive through Polymarket's proxies; reconnects after 5 s on drop.
  • Storage projection: ~400 bytes/row including indexes. At ~5,000 whale fills/day (busy day) that's 2 MB/day โ†’ ~700 MB/year.

Relationship to /api/poly/profitable-traders

Completely separate service (port 8104, polling-based, focused on 7-day P&L). The whales endpoint is the live order-flow log; profitable-traders is the "who's actually making money" filter. Cross-reference them by wallet address.

Use Cases

  • Build real-time alerts when whales open size in trending markets
  • Chart whale activity per day to spot conviction shifts
  • Stack-rank markets by whale dollar volume to find sharp interest early
  • Cross-reference whale wallets with profitable-traders to follow sharp money
  • Backtest signals where whale buys/sells lead price moves

Code ExamplesCopy link

More examples on GitHub

Every new API endpoint gets a working example added to the repo. Clone it and start building!

View Repo

Replace your_api_key with your actual key.Need an API key?

Python - Get Smart Money Signals

import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.moondev.com"

# Get smart money signals from last hour
signals = requests.get(
    f"{BASE_URL}/api/smart_money/signals_1h.json",
    headers={"X-API-Key": API_KEY}
).json()

for signal in signals["signals"][:10]:
    print(f"{signal['action']} {signal['coin']} @ ${signal['price']:,.0f}")

Python - Monitor Order Flow (130 Symbols)

import requests

API_KEY = "your_api_key"

imbalance = requests.get(
    "https://api.moondev.com/api/imbalance/1h.json",
    headers={"X-API-Key": API_KEY}
).json()

# Overall market pressure
overall = imbalance["overall"]
print(f"Market: {overall['dominant_side']} pressure (ratio: {overall['imbalance_ratio']:.4f})")

# Top coins by sell pressure
for coin, data in sorted(imbalance["by_coin"].items(), key=lambda x: x[1]["imbalance_ratio"]):
    print(f"{coin}: {data['dominant_side']} ({data['imbalance_ratio']:.4f})")

JavaScript - Real-time Ticks

const API_KEY = "your_api_key";

fetch("https://api.moondev.com/api/ticks/latest.json", {
  headers: { "X-API-Key": API_KEY }
})
  .then(res => res.json())
  .then(data => {
    console.log("Current prices:", data);
  });

cURL

# Get smart money rankings
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/smart_money/rankings.json

# Get BTC ticks for last hour
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/ticks/btc_1h.json

# Get large trades
curl -H "X-API-Key: YOUR_KEY" https://api.moondev.com/api/large_trades.json

Want more? Check out the full collection of examples on GitHub.

Data FreshnessCopy link

CategoryUpdate Frequency
Tick Data500ms
Events2 seconds
Trades/Order Flow5 seconds
User Data5 seconds
Binance LiquidationsReal-time (WebSocket)
Bybit LiquidationsReal-time (WebSocket)
OKX LiquidationsReal-time (WebSocket)
All Liquidations (Combined)Real-time (WebSocket)
HIP3 Liquidations (TradFi)Real-time
HIP3 Market Data (Candles/Ticks)500ms
Near liquidation top 50 lists (positions*.json)~1 second
Per symbol position files (all*.json) and majors.json~2 minutes (full scan)
Trenders (latest.json, all.json)15 minutes
OHLCV v2 candles (/api/candles/v2)1 minute (about 1 minute behind real time)
HLP Positions30 seconds
HLP Trades30 seconds
HLP Sentiment/Analytics30 seconds
HIP3 Funding~15 seconds
Hyperliquid Liquidations30 seconds
Positions/Whales (22,500+ wallets)30 seconds
Smart Money60 seconds
Contracts5 minutes

Error CodesCopy link

HTTP CodeMeaning
200Success
400Bad request - missing or invalid parameters
401Unauthorized - Invalid or missing API key
404Endpoint not found
410Gone - endpoint permanently retired
429Rate limit exceeded
500Server error
503Service busy - retry shortly

Machine-Readable Error Codes

Error responses include a code field so clients can branch without parsing messages:

CodeStatusMeaning
missing_api_key / invalid_api_key401No key / wrong key
stream_key_expired401Daily moonstream_* key rotated (~24h validity) - fetch a current key
rate_limited429Rate limit exceeded. Includes clients retrying dead keys - after ~5 explanatory 401s, dead-key retries collapse to 2/min per IP
endpoint_retired410Permanent - the endpoint has been removed (retired HLP funding/trades and SafeLaunch endpoints)
fills_scanner_busy503Fills scanner at its concurrency limit - retry shortly or use your fallback source. Do not treat as an empty result.
window_required400A time window (minutes or since_ms) is mandatory on /api/user/{address}/flow - it answers recency questions

Getting 401 errors? Get your API key here.

ChangelogCopy link

2026-10-28

  • New Liquidations by Time Range (Quant Elite): /api/bulk/hl_liquidations returns every Hyperliquid liquidation between any two times, main dex and every HIP3 dex, back to 2026-01-07, paged up to 10,000 rows. /api/bulk/hl_liquidations/coverage gives counts per day and known gaps.

2026-10-27

  • New Liquidation Flow: every Hyperliquid liquidation with the wallet that took the other side, maker or taker, and its position before and after. /api/hl/liquidation_flow/takers (who takes the flow) and /api/hl/liquidation_flow/fills (every liquidation, filter by coin, wallet, role, method). History from 2026-10-21.
  • User fills now carry counterparty (the wallet on the other side) and counterparty_order (its oid, taker or maker, client order id, TWAP) on /api/user/{address}/fills, for all history back to 2026-10-25. Existing fields unchanged.
  • Fix: /api/user/{address}/fills returns only the wallet's own fills. A liquidated wallet no longer gets the liquidator's fill, and builder addresses no longer get other people's fills.

2026-10-25

  • New Position History: every $10k+ Hyperliquid position on every perp and HIP3 market, minute by minute since 2026-10-21. /api/hl/position_history/{coin}/book (any past minute), /diff, /changes, /user/{address} and /status.

2026-10-24

  • New OHLCV v2: GET /api/candles/v2/{coin} with 10s, 30s, 1m, 5m, 15m, 30m, 1h, 4h and 1d bars for every Hyperliquid market (perps, HIP3, spot and outcome), with buy and sell volume, dollar volume and trade count. Up to 10,000 bars per page, history from 2026-10-21. Plus /api/candles/v2/symbols and /api/candles/v2/status.

2026-10-20

  • New Trenders: GET /api/trenders/latest.json and all.json, a 4h trend, breakout and confluence scan over every Hyperliquid market (crypto + all HIP3 dexes), built from our own node's trades, refreshed every 15 minutes. One call instead of ~330.
  • Positions docs corrected to what the feeds actually do: the top-50 near-liquidation lists use a $75k minimum position (was documented as $10k) and hold 100 positions total across all coins; all*.json covers 300+ symbols (139 crypto + 163 HIP3, was documented as 182); the full scan behind all*.json and majors.json takes about 2 minutes (was documented as 90s).

2026-08-14

  • New GET /api/positions/majors.json: all positions โ‰ฅ $10M within 50% of liquidation, every symbol, uncapped โ€” a position never leaves the feed while it exceeds $10M. Same schema as all.json, ~90s updates.

2026-08-13

  • New GET /api/user/{address}/flow: cap-proof net buy/sell flow for a wallet over a time window (per-coin or breakdown).
  • GET /api/user/{address}/fills responses now include order (guaranteed newest_first, newest-kept on cap), exact truncated, newest_ms/oldest_ms, and page_summary (replaces summary, which remains as a deprecated alias).
  • Fills endpoints now accept time windows: minutes/since_ms on /api/user/{address}/fills, startTime/minutes on /api/fills/{address}. Windowed queries are ~50ms for any wallet.
  • New 503 code fills_scanner_busy (retry / fall back); an empty fills array now always means genuinely no fills.
  • Retired (410): /api/hlp/funding, /api/hlp/funding/hip3, /api/hlp/trades, /api/hlp/trades/stats, /api/launch/*, /ws/launch/*, /api/sol-launch/*. Use /api/hlp/sentiment and /api/hlp/positions instead.

Quick Reference - All EndpointsCopy link

# Market Data

/api/prices

/api/price/{coin}

/api/orderbook/{coin}

/api/account/{address}

/api/fills/{address}?limit=N&startTime=&minutes= (time windows NEW)

/api/candles/{coin}?interval={1m,5m,15m,1h,4h,1d}

/api/candles/v2/{coin}?interval={10s,30s,1m,5m,15m,30m,1h,4h,1d} (every market, buy/sell volume, NEW)

/api/candles/v2/symbols ยท /api/candles/v2/status

# HL Direct Proxies (NEW)

/api/hl/clearinghouse/{address}?dex= (alias of /api/account)

/api/hl/open_orders/{address}?coin= (drop-in for info.open_orders)

POST /api/hl/info (Hyperliquid /info body in, same JSON out: spotClearinghouseState, activeAssetData, perpsAtOpenInterestCap, meta, spotMeta, perpDexs, portfolio, userFillsByTime)

# Position History (NEW)

/api/hl/position_history/{coin}/book?at=&side=&min_usd=&limit=

/api/hl/position_history/{coin}/diff?from=&to=

/api/hl/position_history/{coin}/changes?start=&end=&limit=

/api/hl/position_history/user/{address}?start=&end=&limit=

/api/hl/position_history/status

# Liquidation Flow (NEW)

/api/hl/liquidation_flow/takers?start=&end=&coin=&method=&limit=

/api/hl/liquidation_flow/fills?start=&end=&coin=&address=&role=&method=&limit=

# Core Data

/api/positions.json (combined)

/api/positions_crypto.json (crypto only)

/api/positions_hip3.json (HIP3 only)

/api/positions/all.json (combined)

/api/positions/all_crypto.json (crypto only)

/api/positions/all_hip3.json (HIP3 only)

/api/positions/majors.json ($10M+ whale positions, uncapped)

# Trenders (4h trend scan, every market, NEW)

/api/trenders/latest.json (trenders, breakouts, 7d movers, confluence, HIP3 zones)

/api/trenders/all.json (every symbol's metrics row)

/api/whales.json (75 symbols: native + HIP-3)

/api/buyers.json

/api/depositors.json

/api/whale_addresses.txt

# Blockchain

/api/events.json

/api/contracts.json

# Tick Data (129 symbols)

/api/ticks/{stats,latest}.json

/api/ticks/{symbol}.json

/api/ticks/{symbol}_{10m,1h,4h,24h,7d}.json

# Trades & Order Flow (130 symbols)

/api/trades.json

/api/large_trades.json

/api/orderflow.json

/api/orderflow/stats.json

/api/imbalance/{5m,15m,1h,4h,24h}.json

Raw data: 90-day retention | Hourly aggregates: permanent

# Hyperliquid Liquidations

/api/liquidations/{stats,scan_summary}.json

/api/liquidations/{10m,1h,4h,12h,24h,2d,7d,14d,30d}.json

# HIP3 Liquidations (TradFi)

/api/hip3_liquidations/stats.json

/api/hip3_liquidations/{10m,1h,24h,7d}.json

# HIP3 Market Data (136 symbols / 7 dexes โ€” auto-discovered)

/api/hip3/meta (all symbols + per-dex counts)

/api/hip3/candles/symbols

/api/hip3/prices

/api/hip3/price/{coin}

/api/hip3/candles/{coin}?interval={1m,5m,15m,1h,4h,1d}

/api/hip3/ticks/{coin}?duration={10m,1h,4h,24h,7d}

# Multi-Exchange Liquidations

/api/all_liquidations/stats.json

/api/all_liquidations/{10m,1h,4h,12h,24h,2d,5d}.json (30s updates)

/api/all_liquidations/{7d,14d,30d}.json (15min updates)

/api/binance_liquidations/stats.json

/api/binance_liquidations/{10m,1h,24h,7d,30d}.json

/api/bybit_liquidations/stats.json

/api/bybit_liquidations/{10m,1h,24h,7d,30d}.json

/api/okx_liquidations/stats.json

/api/okx_liquidations/{10m,1h,24h,7d,30d}.json

# Binance Futures Liquidations

/api/binance_liquidations/coverage.json?api_key=KEY (segments + gap, standard key)

/api/bulk/binance_liquidations?api_key=KEY&symbol=&start=&end=&side=&min_usd=&limit=&offset= (Quant Elite)

/api/bulk/hl_liquidations?start_ms=&end_ms=&coin=&limit= (Quant Elite, NEW)

/api/bulk/hl_liquidations/coverage (Quant Elite)

35M+ records, June 2024+ (data gap 2026-04-23 โ†’ 2026-07-18), bulk requires _qe API key

# Position Snapshots (Liquidation Risk)

/api/position_snapshots/symbol/{BTC,ETH,SOL,XRP,HYPE}?hours=24

/api/position_snapshots/stats?hours=24

Tracks positions within 15% of liquidation, min $10k value, 1-min snapshots

# Smart Money

/api/smart_money/{rankings,leaderboard}.json

/api/smart_money/signals_{10m,1h,24h}.json

# User Data (Local Node)

/api/user/{address}/positions

/api/user/{address}/fills?limit=N&minutes=&since_ms= (time windows NEW)

/api/user/{address}/flow?minutes=&since_ms=&coin= (cap-proof net flow NEW)

# HLP (Hyperliquidity Provider)

/api/hlp/positions

/api/hlp/positions?include_strategies=false

/api/hlp/positions/history?hours=N

/api/hlp/liquidators

/api/hlp/deltas?hours=N

# HLP Sentiment & Analytics

/api/hlp/sentiment

/api/hlp/liquidators/status

/api/hlp/market-maker

/api/hlp/timing

/api/hlp/correlation

# Polymarket

/api/poly/profitable-traders (profitable traders sorted by 7d P&L)

/api/poly/health (no auth required)

# Polymarket Whales

/api/poly/whales (recent whale fills, $1k+ trades)

/api/poly/whales/top-traders (leaderboard by wallet)

/api/poly/whales/top-markets (leaderboard by market)

/api/poly/whales/daily (per-day rollup)

/api/poly/whales/health (no auth required)

Need an API key or integration support? Get your API key here

GitHub Examples & Code

Terms of ServicePrivacy PolicyContact: [email protected]

Copyright 2026 Moon Dev. All rights reserved. Market data is informational and not financial advice.