vike

Hyperliquid

Cohort positioning, wallets, leaderboards, liquidations, market structure and builder codes for Hyperliquid perps, one tool per family of routes.

8 tools over the on-chain half of Hyperliquid: where each cohort of wallets is positioned, what one wallet has done, who ranks where, where liquidations would cluster and which builder codes earn the fees. They are the /v1/hyperliquid REST routes shaped for an agent: each call reads one view, which is one route, runs the same query function that route runs, and costs what that route costs. Perps has the two older Hyperliquid tools (hl_perp_top_traders, hl_position_match) and Candles has hl_ohlcv.

How these tools behave

A tool with several views takes a view parameter. The first view in each table is the default, so a call with no view is valid. hl_cohort_metrics has one view and no view parameter.

A call is checked against its route before any query runs. An unknown view, an input the chosen view needs and lacks, a parameter the chosen view does not take, a number above the route's cap, and a symbol that disagrees with coin all come back as an {"error": ...} result that names the fix. A REST route silently ignores a query parameter it does not know, which on a tool would hand an agent an unfiltered answer that looks filtered; that is why these refuse instead.

symbol is the instrument parameter. Its old name, coin, is still accepted, as on hl_position_match, and is not in the schema. Pass one of them, not two different ones.

Field names are the new ones only. Until 2026-11-19 a REST response from many of these routes repeats each renamed field under its pre-2026-10-19 name (asset, coin, by_coin, n_coins, ...). These tools return the new field names only, so a script ported from the REST responses must not read the old ones.

Lists page by keyset cursor. Pass nextCursor from a response back as cursor; it is null on the last page. Every limit has the cap of its route, and the table row says which.

Units differ between fields with similar names. Read this table before comparing numbers.

FieldUnit
bias (every view that returns it)Fraction from -1 (all short) to +1 (all long): (long - short) / (long + short) of notional
pct_wallets_in_profit (hl_segments)Fraction from 0 to 1, whatever its name says
percent_risk (hl_liquidations)Fraction from 0 to 1, whatever its name says
win_rate, min_win_rate (hl_leaderboard, hl_wallet)Fraction from 0 to 1 (0.6 is 60%). hl_perp_top_traders uses percent (win_rate_pct)
max_drawdown_pct, pnl_pctPercent (12.5 is 12.5%); pnl_pct is null under $1 of equity
builder *_pct fieldsPercentage points, 0 to 100
money (*_usd, size_usd, account_value, notional)USD

Cohort labels are not time-stable unless you ask. A wallet's pnl cohort is a percentile of its cumulative realized PnL, and by default it is resolved at query time. A historical row therefore carries today's grading: right for "who is smart now", look-ahead for a backtest. hl_cohort_metrics with label_basis=point_in_time returns each hour's label as it was.

Not here. These routes have no tool: /wallets/{address}/trades (the closed round trips; use hl_wallet view trades_summary for the statistics), /stats, /stats/volume, /hype/holders, /symbols/hourly and /ohlcv/export. They stay on the REST API.

hl_cohort_metrics

1 credit. The hourly cohort matrix of one symbol: for every hour, how much long and short notional each bucket of one ladder holds. It answers "are whales or smart money long or short BTC", the history of that answer, and is the source for a positioning backtest.

ParameterTypeDefaultNotes
symbolstringrequiredInstrument ticker, e.g. BTC; a HIP-3 market is dex:TICKER. An all-symbol matrix is refused
axisenumsizesize, pnl, pnl_abs, tier or pnl_unrealized; the ladders are described below
startstring—ISO-8601 UTC lower bound
endstring—ISO-8601 UTC upper bound
opened_withinenumall24h, 7d, 30d or all: positions opened in that window before each hour, rolling rather than relative to now. Anything but all is refused where the matrix is a stored aggregate (see below)
hoursinteger168Hourly buckets, newest first, max 8760. Pass 1 to 24 for a current read
cursorstring—nextCursor from the previous page; it pages by whole hours
label_basisenum—current or point_in_time. Use point_in_time for any backtest
gradingenum—realized (the default on pnl), realized-pit or unrealized; only on the pnl and pnl_unrealized axes

Returns {axis, label_basis, grading, metrics, hours, nextCursor}, plus label_computed on every graded ladder (pnl, pnl_unrealized, pnl_abs) and freshness on a window that reaches the present. Each metrics row is one hour for one cohort: ts, cohort, total_position_value and total_position_value_long in USD, bias, and, except under label_basis=point_in_time, position_count, position_count_long, total_unrealized_pnl, total_position_size and total_position_size_long. The response holds about hours times the number of buckets on the ladder, so ask for hours=1 to 24 for a current read and page older data with cursor; paging is by whole hours, so an hour never arrives with some of its cohorts missing.

Three ladders are per wallet (size, pnl, pnl_abs); tier buckets each position by its own notional; pnl_unrealized ranks wallets by the unrealized PnL of their open positions as a share of account value, from the last snapshot before that hour. pnl_abs is always today's dollar bands, so it is look-ahead and never for a backtest. The hour in progress is never returned, so a series that is differenced or z-scored has no partial bar at its right edge. For the current value use hl_market view symbol_metrics.

opened_within is applied or refused, never dropped. It filters live positions, so it works on size, tier, pnl_abs and on pnl with the default label basis. The stored sources (axis=pnl_unrealized, grading=unrealized or realized-pit, and label_basis=point_in_time) have position age summed away, and the REST route answers the all-ages matrix for any value there, including a value that is not an age. The tool refuses anything but all in those combinations, naming the combination, and refuses a value that is not an age everywhere.

For a backtest, pass label_basis=point_in_time. Without it the pnl ladder is today's grading applied to past hours, which lets a wallet that is "smart" now label a period when it was not. label_computed states which source labelled the window and names the point where the label's resolution changes (daily before 2026-08-06, hourly after), which a turnover count will read as a regime change that is an artefact. grading=realized-pit is a frozen control for a study that crosses it: it stops growing, so a recent window comes back short, and freshness.behind_hours says by how much.

For a live read, check freshness. On a window that reaches the present the envelope carries {newest_ts, behind_hours, settled_lag_ceiling_hours, stale}; stale is the verdict, so a caller does not re-derive the rollup's cadence. A window that ends in the past has no freshness.

Are whales net long or short BTC right now, and how has that moved over the last 24 hours?

Compare smart-money and rekt positioning on ETH over the last month, with the cohort labels as they were at the time.

hl_segments

1 credit. The cohort vocabulary and its positioning at the latest snapshot. Read cohorts or segments first to learn the exact labels, then summary for one cohort or heatmap for the whole board.

ParameterTypeDefaultNotes
viewenumsegmentssegments, cohorts, summary or heatmap
cohortstring—One label on axis, e.g. whale or 3x smart, spelled as cohorts lists it. Required by summary
axisenumsizesize, pnl or pnl_abs (summary, heatmap)
opened_withinenumall24h, 7d, 30d or all (summary, heatmap); positions with no known open time are left out of every bounded window
  • cohorts returns {size, pnl, tier}, each a list of labels in ladder order (pnl also holds unknown, wallets under 10 closed trades). Every cohort parameter on every tool accepts exactly these strings.
  • segments returns one row per bucket with axis, cohort, slug, rank, basis, applies_to, groupable, the bounds (min_usd, max_usd, percentile_min, percentile_max) and min_closed_trades. It is how a client learns that the pnl ladder is a percentile rank of cumulative realized PnL, not dollars, and that pnl_abs is dollars over the same PnL. groupable is false for trade_size, which buckets a position rather than a wallet.
  • summary returns everything one cohort holds across all symbols: total_long_usd, total_short_usd, total_value, bias, n_positions, n_wallets, n_wallets_in_profit, pct_wallets_in_profit, total_margin_used, total_equity, exposure_ratio (notional over margin used, the cohort's realized leverage), total_unrealized_pnl and a by_side block. total_equity is the cohort's whole-account value, not the part backing the positions counted.
  • heatmap returns {axis, opened_within, snapshot_ts, source, totals, heatmap}: one row per symbol, ordered by total notional, each carrying its totals, bias and a segments list of the cohorts that hold anything in it. Empty cells are omitted rather than sent as zeros. It covers every symbol with open interest, so it is a large response.

axis is size, pnl or pnl_abs on summary and heatmap; the per-position tier ladder is refused there and is available on hl_cohort_metrics.

Which Hyperliquid cohorts are the most net short right now?

Show how every cohort on the pnl ladder is positioned in SOL.

hl_wallet

1 credit. One Hyperliquid wallet. Take the address from hl_leaderboard, hl_perp_top_traders or hl_position_match.

ParameterTypeDefaultNotes
viewenumsummarysummary or trades_summary
addressstring—Required. The wallet, 0x plus 40 hex characters, any case
windowenumall1d, 7d, 30d or all: the trade window of the metrics and statistics
opened_withinenumall24h, 7d, 30d or all (summary only); bounds the open-positions block only
  • summary returns {wallet, window, metrics_updated_at, has_metrics, equity, open_positions, cohorts, lifetime, ledger_by_type, metrics}. equity is the live account (account_value, margin_used, cash_balance_usd, total_unrealized_pnl), open_positions the current set (count, notional_usd, unrealized_pnl, the oldest and newest open time), cohorts the wallet's size and pnl labels and style tags, lifetime the cumulative realized PnL since inception with deposits, withdrawals and vault flows, and metrics the window's risk set: win_rate (a fraction), max_drawdown_pct, pnl_pct, profit factor, Calmar, streaks and average leverage. metrics is null and has_metrics is false for a wallet with no metrics row, which is not the same as a wallet with zero trades.
  • trades_summary returns {wallet, window, overall, by_symbol}: trade counts split into closed_trade_count and open_trade_count, wins and losses, average and median gain, loss, size and duration, profit factor, expectancy, fees and volume, overall and per symbol. Medians sit beside means because one outlier trade drags the mean far from anything the wallet typically does.

opened_within narrows only the open-positions block. The equity, lifetime and metrics blocks are wallet-level totals with nothing per position to filter, and bounding them would return a number that looks bounded and is not.

Is 0x... any good? Show its equity, open positions and risk metrics.

What does this wallet's trade record look like per coin, median versus mean?

hl_wallet_activity

1 credit. A wallet's event history. Fills, funding and ledger are newest first; builders is ranked by volume.

ParameterTypeDefaultNotes
viewenumfillsfills, funding, ledger or builders
addressstring—Required. The wallet, 0x plus 40 hex characters, any case
symbolstring—One symbol (fills, funding); omit for all
startstring—ISO-8601 UTC lower bound (fills, funding, ledger)
endstring—ISO-8601 UTC upper bound (fills, funding, ledger)
sideenum—buy or sell (fills only)
limitinteger—Rows per page. Default 100, max 5000; on builders default 50, max 500
cursorstring—nextCursor from the previous page, verbatim
event_typeenum—One ledger event type (ledger only); an unknown value is refused
windowenumall1d, 7d, 30d or all (builders only)
  • fills, funding and ledger return {wallet, items, nextCursor}. A fill carries ts, symbol, side, size_token, price, size_usd, fee with its own fee_token, is_maker, closed_pnl, order_id, trade_id and dex_name. A funding row carries payment_usd, position_size and funding_rate; payment_usd is signed from the wallet's side, so negative means the wallet paid. A ledger row carries event_type, amount_usd, fee, token, counterparty and hash.
  • builders returns {wallet, window, builders, nextCursor}: one row per builder the wallet's flow went through, with share_of_volume, volume_usd, fee_usd, fills and active_days. The share is of the wallet's builder-routed volume only. A fill placed without a builder code never reaches this table, so it is not a share of the wallet's total trading.

event_type is checked against the set the ledger holds; an unknown value is refused rather than answered with an empty list that reads as "this wallet never did that". The ledger records send one-sided: an outflow is seen where the matching inflow may not be, so a net-flow figure summed from send rows leans negative.

How much has 0x... paid in funding on ETH this month?

List this wallet's deposits and withdrawals.

hl_leaderboard

1 credit. Rank wallets with the full risk set. This is the ranking to use for risk-adjusted questions, a cohort filter, a deep page or a rank that excludes deposits; hl_perp_top_traders is the shorter list.

ParameterTypeDefaultNotes
viewenumrankingranking or flow_adjusted
windowenum30d1d, 7d, 30d or all
sortenumpnlOne of 20 keys (ranking only); an unknown key is refused, never replaced by pnl
orderenumdescasc or desc (ranking only)
cohortstring—One label on axis (ranking only); omit for no filter
axisenumsizesize, pnl or pnl_abs: the ladder cohort filters on (ranking only)
min_tradesinteger0Minimum closed trades (ranking only). No floor at 0, unlike hl_perp_top_traders, which floors at 3
min_win_ratenumber0A fraction from 0 to 1 (0.6 is 60%), compared with the win_rate the rows show (ranking only). 60 is refused: the route would return an empty board
min_volumenumber0Minimum total volume in USD (ranking only)
limitinteger25Rows per page, max 500
cursorstring—nextCursor verbatim; on ranking, resend the window, sort, order, axis and cohort it was issued for
  • ranking returns {traders, totalCount, nextCursor}. A row carries rank, wallet, account_value, total_realized_pnl, cum_realized_pnl, roi, pnl_pct, volume, fees, trade, win and loss counts, win_rate with its long and short halves, profit_factor, expectancy, max_drawdown_pct, current_drawdown_pct, calmar_ratio, recovery_factor, streaks, avg_leverage, avg_duration_seconds, and the size_cohort, pnl_cohort and style tag. A cursor is bound to the window, sort, order, axis and cohort it was issued for, and a different set is refused.
  • flow_adjusted returns the same rows plus ranked_by, and per row an attributed block, a flow block of deposits and withdrawals, and flow_unbalanced. It ranks fills-derived realized trading PnL, which excludes deposits by construction: a wallet that deposits $1M and loses $50k reads as +$950k on any ranking built from account-value change, and not on this one. flow_unbalanced is true when the wallet had a send in the window, which is when the attributed block beside the rank is unreliable. It is reported and never used to filter, so the board is not emptied of active traders.

Prefer pnl_pct to the raw roi: the stored roi is not guarded and reaches values like 4.8e10 on a near-empty account, while pnl_pct is null under $1 of equity.

Rank the top Hyperliquid wallets of the last 30 days by Calmar ratio with at least 100 trades.

Who made the most from trading, not from deposits, this week?

hl_liquidations

1 credit. Realized liquidations, where open positions would liquidate, and which symbols have the most open interest close to it.

ParameterTypeDefaultNotes
viewenumfillsfills, risk or heatmap
symbolstring—One symbol. Optional on fills, required by heatmap
walletstring—One wallet, to ask whether it has been liquidated (fills only)
startstring—ISO-8601 UTC lower bound (fills only)
endstring—ISO-8601 UTC upper bound (fills only)
directionenum—long or short: the side of the position that was closed (fills only)
limitinteger100Rows per page (fills, risk); max 5000 on fills, 500 on risk
cursorstring—nextCursor verbatim (fills only)
axisenumsizesize, pnl or pnl_abs (risk only)
cohortstring—One label on axis (risk only); omit for all wallets
binsinteger50Equal-width price bins, 5 to 500 (heatmap only)
  • fills returns {liquidations, label_computed, nextCursor}. A row carries liq_ts, wallet, symbol, side, size_token, size_usd, mark_price, size_cohort, pnl_cohort and pnl_cohort_basis. direction filters on the side of the position that was closed, so direction=long is longs being liquidated, which is price falling. The pnl_cohort is the label at the liquidation's own hour where the hourly label table covers it, and today's label where it does not; pnl_cohort_basis says which for each row, and label_computed names the windows with no point-in-time label.
  • risk returns a list of {symbol, total_value_usd, risk_value_usd, percent_risk, positions_count, at_risk_count, cohort_axis, cohort}. A position is at risk when it sits within half of its liquidation buffer, the same definition the Hyperliquid pages on the site use. Rows are ranked by percent_risk, a fraction, so thin micro-cap markets can top the list: read total_value_usd before reading a ranking.
  • heatmap returns {symbol, mark_price, snapshot_ts, bins, total_value_usd, cohort_axis, window, coverage}. Each bin carries price_bin_start, price_bin_end, liquidation_value_usd, positions_count, the long and short split and most_impacted_cohort. Bins are equal-width over +-50% of the mark price. Positions outside that window are dropped, not clamped into the edge bins, and positions with no liquidation price are excluded; coverage counts both, with in_window_fraction_of_open.

Which Hyperliquid symbols have the most open interest close to liquidation, among those with over $50M open?

Where would ETH liquidations cluster if price fell 10%?

hl_market

1 credit. Market-wide positioning: open interest per symbol, one symbol's hourly series, its split by position size, and individual position rows.

ParameterTypeDefaultNotes
viewenumopen_interestopen_interest, symbol_metrics, size_breakdown or positions
symbolstring—One symbol. Required by symbol_metrics and size_breakdown; a filter on positions
startstring—ISO-8601 UTC lower bound (symbol_metrics, positions); on positions it switches to history
endstring—ISO-8601 UTC upper bound (symbol_metrics, positions); on positions it needs start and is refused alone
axisenum—size, pnl or pnl_abs. On symbol_metrics omit it to sum all cohorts; on positions it defaults to size
cohortstring—One label on axis (symbol_metrics, positions)
opened_withinenumall24h, 7d, 30d or all (symbol_metrics only)
limitinteger—Rows per page, max 5000. Default 500 on symbol_metrics, 100 on positions
cursorstring—nextCursor verbatim (symbol_metrics, positions)
label_basisenum—current only (symbol_metrics); point_in_time is refused by name
walletstring—One wallet's positions (positions only)
open_onlybooleantrueLatest open positions (positions only); start switches to history whatever this says, and false without start is refused
  • open_interest returns a list of {symbol, total_value, total_value_long, total_value_short, count, count_long, count_short, venue_open_interest_usd}: our aggregate of the positions we hold beside the venue's own open interest, so the two can be reconciled.
  • symbol_metrics returns {axis, label_basis, metrics, nextCursor}; each row is one hour with total_position_value, total_position_value_long, position_count, total_unrealized_pnl, bias and provisional. provisional is true on at most one row, the newest, which covers the hour still in progress; its ts is a snapshot instant that changes on every poll, so drop it when storing a series. Omit axis to sum all cohorts. A pnl cohort slice uses today's grading for every past hour, and label_basis=point_in_time is refused here by name; use hl_cohort_metrics for research.
  • size_breakdown returns a list of the ten position-size buckets, largest first, zero-filled: tier, min_size, max_size, position_count, total_position_value, total_position_value_long, value_close_to_liquidation and bias.
  • positions returns {positions, nextCursor, label_computed}; a row carries wallet, symbol, direction, size_usd, entry_price, mark_price, liquidation_price, unrealized_pnl, leverage, margin_used, the cohort labels with pnl_cohort_basis, opened_at and snapshot_ts. By default it reads the latest open positions. Passing start switches to the historical snapshots, a very large table, so bound it with symbol or wallet; end is an optional upper bound and is refused without start, as is open_only=false. A historical pnl or pnl_abs cohort filter needs symbol or wallet.

What is the open interest of every Hyperliquid symbol, next to the venue's own number?

Show the largest open BTC positions and how close each is to liquidation.

hl_builders

1 credit. Builder codes: front-ends and bots that attach their address to an order and are paid a slice of the taker fee for it.

ParameterTypeDefaultNotes
viewenumleaderboardleaderboard, stats, profile, users, fills or series
windowenum30d1d, 7d, 30d or all (leaderboard, stats, profile, users)
sortstring—leaderboard: fee (default), volume, users or fills. users: volume (default), fees or pnl
orderenumdescasc or desc (leaderboard, users)
limitinteger—Rows per page. Defaults and caps: leaderboard 50 and 500, users 100 and 1000, fills 100 and 5000, series 500 and 2000
cursorstring—nextCursor verbatim (leaderboard, users, fills, series)
builderstring—The builder address. Required by profile, users, fills and series
breakdown_limitinteger100Rows per breakdown, max 1000 (profile only)
symbolstring—One symbol (fills only)
sideenum—buy or sell (fills only)
startstring—ISO-8601 UTC lower bound (fills, series)
endstring—ISO-8601 UTC upper bound (fills, series)
bucketenum1d1h or 1d (series only)
  • leaderboard returns {window, sort, order, venue_volume_usd, market_share_window_start, builders, nextCursor}. sort=fee ranks the builder's own cut, not the trader's total cost, and the two orderings differ materially. market_share_pct is over the overlap of the window with the period the venue-wide volume covers, which can start later than window.start; market_share_window_start says where.
  • stats returns {window, totals, lifetime, daily}: how many builders are active, how many distinct traders route through one, the share of all fill notional that carries a builder code, and how it moved day by day. lifetime is unwindowed.
  • profile returns one builder's totals, by_symbol, by_dex, user_volume_distribution (users split into volume deciles, so "19k users" and "one whale plus a tail" stop looking alike), and lifetime. profitable_users is a per-wallet test, not a per-fill one.
  • users returns the builder's wallets ranked by volume, fees or pnl. pnl is the traders' signed realized PnL, not the builder's.
  • fills returns the raw routed fills, newest first. Sum fee_usd, the builder's slice, which is dollars on every row; fee is in its own fee_token, and some fills pay in a non-dollar token, so summing fee is wrong.
  • series returns {builder, bucket, window, series, nextCursor}, newest first. users is a distinct count per bucket and not additive: summing a daily column counts anyone who traded on two days twice. A period total comes from profile over that period.

Three fee columns are not interchangeable: fee_usd is the builder's own revenue, trader_fee_usd is the total the trader paid, and builder_routed_deployer_fee_usd is the deployer's cut on builder-routed flow only, a lower bound on deployer revenue. Builder history reaches back different distances for different builders, so compare active_days and the resolved window before comparing two windows.

Which Hyperliquid builder codes earned the most fees in the last 30 days, and how concentrated are their users?

Show the daily fee revenue of this builder for the last 90 days.

On this page