/coins/{coin}/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/coins/{coin}/cohort-metricsThe full cohort matrix for one coin — every bucket on an axis, hourly.
/coins/{coin}/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.
# the full size matrix for BTC in one call: every account-value tier, six hourly buckets
curl -s "https://data.vike.io/v1/hyperliquid/coins/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/coins/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/coins/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/coins/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/coins/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/coins/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/coins/BTC/cohort-metrics?axis=pnl&grading=unrealized&hours=24" \
-H "X-API-KEY: $VIKE_API_KEY"coinpathrequiredaxisqueryoptionalsize | pnl | pnl_abs | tier | pnl_unrealized. Default sizestartqueryoptionalendqueryoptionalopenedWithinqueryoptional24h | 7d | 30d | all. Default allhoursqueryoptionalcursorqueryoptionalgradingqueryoptionalrealized | 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.labelBasisqueryoptionalcurrent | 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.{
"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
/coins/{coin}/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.