Skip to main content
Four endpoints feed the Coinversa chart — and work just as well on their own. Positioning by entry shows where the money that is open right now got in, whale trades lists the largest recent fills with both counterparties, cohort-bias history gives Apex vs The Crowd hour by hour, and recent candles draws the price underneath. Each one is a single cached call with bounded parameters, and every body says how fresh it is instead of implying “live”. The three layer routes are Pro; candles are Starter, so on a Starter key the chart keeps its candles, indicators and the Starter snapshots (liquidation levels, cohort positioning) and marks the Pro layers instead of failing. All four take a market symbol in the path — a native perp (BTC) or a builder-dex symbol (xyz:GOLD). Case and surrounding whitespace are normalized, and the body echoes the canonical spelling. For positioning by entry, whale trades and recent candles, a symbol Hyperliquid’s own universe does not list is a 404 (Unknown market 'X'). Cohort-bias history does not check the universe: an unknown symbol returns 200 with no history. A listed market with nothing to report is a 200 with empty arrays. Cohorts are returned as legacy slugs — money_printer is Apex, exit_liquidity is The Crowd — see Cohorts.

Positioning by entry

GET /live/positioning-by-entry/{coin} — every open Hyperliquid position on the market, bucketed by entry price into equal-width bins, split long vs short and by cohort, plus one summary row per cohort and side. Think of it as a volume-by-price profile built from who is actually holding, not from what traded.

Response

Only positions above $10 notional are counted (coverage.positions). The reference mark is Hyperliquid’s live mark when the feed answers (markMethod: "live_mark", read through a short per-dex cache — never older than 60 s). If the feed is unavailable the endpoint falls back to the mark stored on the most recently refreshed position (newest_position), then a notional-weighted stored mark (weighted_fallback), then none — never a 500. The live mark is also skipped when it is older than the newest stored position row; the stored mark is then the reference (newest_position) and a note says so. The stored mark is always reported beside it: stored notionals are size × each wallet’s last-poll mark, so a markDivergencePct above 1% means stored notionals and liquidation distances are noticeably stale, and a note says so.
A snapshot, never a history. This is the open book now. A wallet that has not traded keeps its last-poll mark and notional, so in a quiet market positions can be hours old on average — read source.medianAgeS before calling it “live”. Cohorts are each wallet’s current label, not the label it had when it entered. Positions whose wallet has no tier yet are in the bins and side totals but in no cohort row (coverage.withoutTier). No wallet addresses are returned.

Whale trades

GET /live/whale-trades/{coin} — the largest individual fills on a market by USD notional (price × size), largest first, with both counterparties where indexed. Each trades[] row carries tid (a decimal string — 64-bit, do not parse it into a JavaScript number), idKind, time, price, size, notional, and a buyer and seller with address, pnlTier, sizeTier and direction (what the fill did to that wallet’s position: Open Long, Close Short, Long > Short, …). An unindexed counterparty is an empty party. “Whale” means the trade is large — not the whale size tier (lifetime volume) and not realized PnL (/pulse/biggest-wins, /pulse/biggest-losses and /pulse/trades/recent rank by PnL). A fill whose exchange id was missing carries a negative, wallet-specific id and idKind: "synthetic": it is one wallet’s observation and cannot be paired with its counterparty, which may appear as a separate row.
The 24h ceiling is a performance bound, not a data limit: fills are not indexed by notional, so cost grows with the market’s fill count in the window. Equivalent windows (6h, 360m) share one cache entry.

Cohort-bias history

GET /live/cohort-bias-history/{coin} — hourly long/short notional and net bias per cohort, read from the hourly snapshot table: The chart’s call is /live/cohort-bias-history/BTC?tiers=apex,crowd&hours=2160&format=layer, which returns:
  • netBias is a −1..1 ratio on this route (netBiasUnit: "ratio"), not the −100..100 percent of /pulse/cohort-bias/history. Long share is (netBias + 1) / 2.
  • The window is explicit UTC: (windowStart, windowEnd], captured once and echoed in the body; rows stamped in the future are excluded. Snapshots are written at :00:05 UTC, so observedThrough normally trails now by up to an hour.
  • Missing hours stay missing. A stalled hour has no row, and a cohort with no open notional in an hour has no point — never 50%. hoursPresent vs coverage.hoursExpected tells you how many are absent. Draw gaps; do not interpolate or zero-fill.
Not suitable for backtests. Some hours are written by a backfill that stamps today’s tier labels on past hours (lookahead) and can touch the last 7 days, not only old ones; beyond the 30-day candle window a backfilled hour may also carry a placeholder price. Live and backfilled rows cannot be told apart yet, so coverage.provenance is unknown_mixed and backtestSuitable is false at every age. Compare snapshot to snapshot for “change vs 1h” — the current /live/cohort-bias/{coin} value filters out positions of $10 notional or less, and the snapshots do not.

Recent candles

GET /pulse/market/candles/recent/{symbol} returns recent OHLCV, newest first:
  • Unknown market → 404, the same contract as /market/price/{symbol}: only when Hyperliquid’s universe says the symbol does not exist. A listed market with no candles stays 200 [].
  • Rolled-up intervals inherit 1-minute retention (30 days), so 1d returns at most 30 daily bars.
  • Responses are cached for 15 s, keyed by symbol (case-folded), interval and effective limit — limit=600 and limit=720 share one entry.
The MCP chart view is built on exactly these four calls — one per layer, cached, no fan-out. See the tier matrix and data windows for how they sit alongside the rest of the API.