vike
API EndpointsHyperliquid

/symbols/{symbol}/cohort-metrics

The full cohort matrix for one coin — every bucket on an axis, hourly. The bulk-history endpoint.

GET https://data.vike.io/v1/hyperliquid/symbols/{symbol}/cohort-metrics

The full cohort matrix for one coin — every bucket on an axis, hourly. /symbols/{symbol}/metrics returns one row per hour for a single cohort or for all of them summed; rebuilding the matrix from it costs one request per cohort (12 for size, 13 for pnl). This returns all of them in one.

Truncated: metrics holds 72 rows — 6 hourly buckets x 12 size cohorts, which is the matrix this endpoint exists to return in one call; the first 2 are shown.

cURL
# the full size matrix for BTC in one call: every account-value tier, six hourly buckets
curl -s "https://data.vike.io/v1/hyperliquid/symbols/BTC/cohort-metrics?axis=size&hours=6" \
  -H "X-API-KEY: $VIKE_API_KEY"

# next page of the call just above: NEXT is its nextCursor, passed back verbatim
curl -s "https://data.vike.io/v1/hyperliquid/symbols/BTC/cohort-metrics?axis=size&hours=6&cursor=$NEXT" \
  -H "X-API-KEY: $VIKE_API_KEY"

# the per-position ladder: how much BTC notional sits in each position-size bucket, hour by hour
curl -s "https://data.vike.io/v1/hyperliquid/symbols/BTC/cohort-metrics?axis=tier&hours=24" \
  -H "X-API-KEY: $VIKE_API_KEY"

# a backtest-safe smart-money matrix: each row labelled as it was that hour, over a pinned week
curl -s "https://data.vike.io/v1/hyperliquid/symbols/BTC/cohort-metrics?axis=pnl&labelBasis=point_in_time&start=2026-08-10T00:00:00Z&end=2026-08-16T23:59:59Z&hours=168" \
  -H "X-API-KEY: $VIKE_API_KEY"

# the control for a study that crosses the 2026-08-06 seam: one grading across the whole window
curl -s "https://data.vike.io/v1/hyperliquid/symbols/BTC/cohort-metrics?axis=pnl&grading=realized-pit&start=2026-08-01T00:00:00Z&end=2026-08-12T00:00:00Z&hours=300" \
  -H "X-API-KEY: $VIKE_API_KEY"

# live use: honest labels, one hour behind the clock; freshness says whether the book is stale
curl -s "https://data.vike.io/v1/hyperliquid/symbols/BTC/cohort-metrics?axis=pnl&grading=realized&labelBasis=point_in_time&hours=1" \
  -H "X-API-KEY: $VIKE_API_KEY" \
  | jq '.freshness'

# who is currently onside: rank by unrealized PnL of open positions, hourly
curl -s "https://data.vike.io/v1/hyperliquid/symbols/BTC/cohort-metrics?axis=pnl&grading=unrealized&hours=24" \
  -H "X-API-KEY: $VIKE_API_KEY"
symbolpathrequired
HL ticker
axisqueryoptional
size | pnl | pnl_abs | tier | pnl_unrealized. Default size
startqueryoptional
ISO-8601 UTC bounds
endqueryoptional
ISO-8601 UTC bounds
openedWithinqueryoptional
24h | 7d | 30d | all. Default all
hoursqueryoptional
Number of hourly buckets. Default 168, max 8760
cursorqueryoptional
Cursor over hours
gradingqueryoptional
realized | realized-pit | unrealized. Which PnL grading labels each wallet, for the axes that carry one (axis=pnl, axis=pnl_unrealized). Default realized on axis=pnl; refused on size, tier, pnl_abs. Every response declares in label_computed WHEN the label was computed — the grading name alone cannot say it.
labelBasisqueryoptional
current | point_in_time. Default depends on the axis: size, tier and pnl_unrealized are always point_in_time, pnl_abs always current. point_in_time (axis=pnl) returns each row's cohort label AS IT WAS that hour, at the cost of five fields. Use it for backtests.
Example response
{
  "axis": "size",
  "label_basis": "point_in_time",
  "metrics": [
    {
      "ts": "2026-09-03T07:00:00+00:00",
      "cohort": "4x whale",
      "position_count": 20,
      "position_count_long": 6,
      "total_position_value": 704156131.5,
      "total_position_value_long": 182556075.6,
      "total_unrealized_pnl": -24295055.1,
      "total_position_size": 9061.33228,
      "total_position_size_long": 2349.1967,
      "bias": -0.4814897793,
      "label_basis": "point_in_time",
      "grading": null
    },
    {
      "ts": "2026-09-03T07:00:00+00:00",
      "cohort": "3x whale",
      "position_count": 26,
      "position_count_long": 14,
      "total_position_value": 265561588.5,
      "total_position_value_long": 171376394.8,
      "total_unrealized_pnl": 20255408.17,
      "total_position_size": 3417.34125,
      "total_position_size_long": 2205.33258,
      "bias": 0.2906715594,
      "label_basis": "point_in_time",
      "grading": null
    }
  ],
  "hours": 6,
  "nextCursor": "eyJtIjoiY29ob3J0X21ldHJpY3MiLCJ0IjoiMjAyNi0wOS0wMyAwMjowMDowMCJ9",
  "grading": null,
  "freshness": {
    "newest_ts": "2026-09-03T07:00:00+00:00",
    "behind_hours": 1,
    "settled_lag_ceiling_hours": 3,
    "stale": false
  }
}

Paginated by hour, not by row. A row limit would cut a bucket in half and return an hour whose cohorts do not sum to its total. hours bounds the buckets; every cohort in a returned bucket comes with it.

No provisional row here. This is bulk history, and a partial hour inside a matrix that will be differenced or z-scored produces a fake move at the right edge. Use /symbols/{symbol}/metrics for the current value.

axis=tier is the per-position ladder, and a grouping only on this endpoint: Cohorts and axes.

By default the pnl cohort is resolved at query time, which is lookahead for a backtest. Pass labelBasis=point_in_time for each row's label as it was that hour; Label basis has the cost.

grading picks the PnL ladder that labels each wallet: Label basis lists the three values and the 2026-08-06 seam.

On a window that reaches the present the envelope carries a freshness block; read the age off freshness.behind_hours. See Freshness.

axis=pnl_unrealized grades positioning, not skill: Cohorts and axes.

Example response
{  "axis": "size",  "label_basis": "point_in_time",  "metrics": [    {      "ts": "2026-09-03T07:00:00+00:00",      "cohort": "4x whale",      "position_count": 20,      "position_count_long": 6,      "total_position_value": 704156131.5,      "total_position_value_long": 182556075.6,      "total_unrealized_pnl": -24295055.1,      "total_position_size": 9061.33228,      "total_position_size_long": 2349.1967,      "bias": -0.4814897793,      "label_basis": "point_in_time",      "grading": null    },    {      "ts": "2026-09-03T07:00:00+00:00",      "cohort": "3x whale",      "position_count": 26,      "position_count_long": 14,      "total_position_value": 265561588.5,      "total_position_value_long": 171376394.8,      "total_unrealized_pnl": 20255408.17,      "total_position_size": 3417.34125,      "total_position_size_long": 2205.33258,      "bias": 0.2906715594,      "label_basis": "point_in_time",      "grading": null    }  ],  "hours": 6,  "nextCursor": "eyJtIjoiY29ob3J0X21ldHJpY3MiLCJ0IjoiMjAyNi0wOS0wMyAwMjowMDowMCJ9",  "grading": null,  "freshness": {    "newest_ts": "2026-09-03T07:00:00+00:00",    "behind_hours": 1,    "settled_lag_ceiling_hours": 3,    "stale": false  }}