Cohort history
One cohort's hourly long, short and bias summed over every symbol, from 2026-04-07; include=leverage adds the cohort's perp bias and exposure against its equity.
GET https://data.vike.io/v1/hl-cohorts/segments/{cohort}/historyOne cohort's long, short and bias per hour, summed over every symbol: the cohort's history across
the whole book, newest hour first. Two axes, size and pnl, and axis is required — any other
axis is a 400. The labels are point-in-time on both: size is stored on the position row, and
pnl is the realized ladder as it stood at the time — the hour's own label from 2026-08-06, the
day's before it — which the envelope's label_computed declares.
Nothing before data_from (2026-04-07) is served.
/segments/{cohort}/summary is the same cohort
at the latest snapshot; this is its hourly series.
# the last week of whale positioning across the whole book, newest hour first
curl -s "https://data.vike.io/v1/hl-cohorts/segments/whale/history?axis=size" \
-H "X-API-KEY: $VIKE_API_KEY"
# smart money's hourly bias over 30 days: a pnl label needs axis=pnl, and the slug stands in for the label
curl -s "https://data.vike.io/v1/hl-cohorts/segments/3x_smart/history?axis=pnl&hours=720" \
-H "X-API-KEY: $VIKE_API_KEY" \
| jq '[.series[] | {ts, bias}]'
# a pinned month: start and end are ISO-8601 UTC, and end is inclusive
curl -s "https://data.vike.io/v1/hl-cohorts/segments/4x_whale/history?axis=size&start=2026-09-01T00:00:00Z&end=2026-09-30T23:00:00Z" \
-H "X-API-KEY: $VIKE_API_KEY"
# a short page: the newest 24 hours of the default week; has_more says older ones remain
curl -s "https://data.vike.io/v1/hl-cohorts/segments/4x_whale/history?axis=size&limit=24" \
-H "X-API-KEY: $VIKE_API_KEY"
# the page before it: END is the oldest ts of the call just above minus 1 second
curl -s "https://data.vike.io/v1/hl-cohorts/segments/4x_whale/history?axis=size&limit=24&end=$END" \
-H "X-API-KEY: $VIKE_API_KEY"
# leverage per hour beside long and short: the cohort's perp bias and exposure against its own equity
curl -s "https://data.vike.io/v1/hl-cohorts/segments/4x_whale/history?axis=size&hours=48&include=leverage" \
-H "X-API-KEY: $VIKE_API_KEY" \
| jq '[.series[] | {ts, bias, perp_bias, equity_exposure, equity_covered_share}]'cohortpathrequiredaxis, from /cohorts / /segmentsaxisqueryrequiredsize | pnl: this endpoint serves history for these two only. Required.startqueryoptionalhours newest hours.endqueryoptionalstart, the window is the hours newest hours at or before it.hoursqueryoptionalstart is omitted. Default 168, max 8760.limitqueryoptionalhas_more says there are older ones (page back with end = the oldest ts minus 1 second; end is inclusive).includequeryoptionalleverage, default none (nothing extra is read). Adds to every row perp_bias = (long - short) / equity, equity_exposure = (long + short) / equity and equity_covered_share = main-dex notional of the counted wallets / main-dex notional of the whole cohort: unbounded ratios (above 1 = more than 1x of equity), native perp account only (main-dex positions of wallets with a known positive native equity, each wallet once; builder-DEX positions are not included). An hour with no stored row, and any hour before leverage.data_from (2026-08-11), is null on all three (never 0). perp_bias and equity_exposure are also null when no counted wallet has a positive equity; equity_covered_share is null when the cohort holds no main-dex notional and a real 0 when it holds some but no wallet is counted. Hours rebuilt from fills rather than read from snapshots are null. An unknown token is a 400.{
"axis": "pnl",
"cohort": "3x smart",
"label_basis": "point_in_time",
"data_from": "2026-04-07T00:00:00+00:00",
"series": [
{
"ts": "2026-10-24T06:00:00+00:00",
"long_usd": 3539759197.0,
"short_usd": 4440124719.0,
"bias": -0.112829,
"position_count": 21418,
"perp_bias": -0.4575988062,
"equity_exposure": 4.688357438,
"equity_covered_share": 0.9999966347
},
{
"ts": "2026-10-24T05:00:00+00:00",
"long_usd": 3544735940.0,
"short_usd": 4438182428.0,
"bias": -0.11192,
"position_count": 21441,
"perp_bias": -0.4526158507,
"equity_exposure": 4.692875987,
"equity_covered_share": 0.9997107427
}
],
"has_more": false,
"label_computed": {
"grading": "realized",
"label_basis": "point_in_time",
"when": "before 2026-08-06, reconstructed from fills on 2026-08-17; from 2026-08-06, frozen on the position row at its own hour",
"lookahead": false,
"resolution": "daily before 2026-08-06, hourly after",
"source": "hourly cohort snapshots",
"detail": "Two point-in-time definitions meeting at 2026-08-06. Before it: day D's label is the wallet's rank by cumulative closed PnL as of the END of D-1, reconstructed from fills by the 2026-08-17 rebuild — so a label is constant across D's 24 hours. From it: the hourly rollup stamps the dictionary value as of that hour onto the row, so the label moves within a day. Neither half can see the future, but a series crossing the seam changes its label RESOLUTION, which a difference or a turnover count will read as a regime change that is an artefact.",
"caveat": "Rows before 2026-08-06 carry no label frozen at write time: their label is the daily reconstruction described above, not a value stamped on the row at its own hour. From 2026-08-06 the label is frozen on the row and does not change."
},
"leverage": {
"data_from": "2026-08-11T00:00:00+00:00",
"scope": "native perp account only; main-dex positions of wallets with a known positive native equity",
"note": "hours rebuilt from fills are null"
}
}The response
| Field | What it is |
|---|---|
axis | size or pnl. |
cohort | The cohort's label. A slug in the path comes back as the label it stands for (3x_smart → 3x smart). |
label_basis | Always point_in_time. |
data_from | 2026-04-07T00:00:00+00:00, the first hour served on either axis. |
label_computed | axis=pnl only: when the labels were computed — hourly from 2026-08-06; before it daily, day D graded on the cumulative realized PnL as of the end of D−1. Absent on size, a stored column with no grading to describe. |
series | One row per hour, newest first. |
has_more | true when the window holds older rows than limit returned. |
leverage | include=leverage only: data_from, scope and note, below. |
Each row of series:
| Field | What it is |
|---|---|
ts | The hour, ISO-8601 UTC. |
long_usd, short_usd | The cohort's long and short notional in that hour, USD, summed over every symbol. |
bias | (long − short) / (long + short), a ratio in [−1, +1]. null when both are 0. |
position_count | Positions, that is (wallet, symbol) pairs — not a wallet count. The aggregate keeps one count per symbol, which cannot be de-duplicated across symbols. |
The window and paging
The window is start as given, or else the hours newest hours at or before end (default 168,
max 8760). Only settled hours are served: the hour in progress never is. At most limit rows come
back (default and max 5000), newest first; has_more says older ones exist. Page back with end =
the oldest ts minus 1 second: end is inclusive, so passing the oldest ts itself repeats that
row. A start more than 8760 hours before end (or now, when end is omitted) is a 400.
include=leverage
A comma list; leverage is its only token, and anything else is a 400. Without it the response
has none of these three fields and nothing extra is read. With it, every row of
series gains three ratios for its hour:
| Field | Definition |
|---|---|
perp_bias | (long − short) / equity |
equity_exposure | (long + short) / equity |
equity_covered_share | main-dex notional of the counted wallets / main-dex notional of the whole cohort |
They are the native perp account only. A wallet is counted when it holds a main-dex position
that hour and has a known, positive native perp equity; long and short are the counted wallets'
main-dex notional, and equity is their native perp account value, each wallet once. Builder-DEX
positions are not included. equity_covered_share is how much of the cohort's main-dex notional
those counted wallets hold, so it says how much of the cohort the other two ratios describe.
These are the three fields /segments/{cohort}/summary serves for the latest snapshot, here per
hour. The ratios are unbounded: above 1 means more than 1x of equity.
The envelope declares the block:
{
"data_from": "2026-08-11T00:00:00+00:00",
"scope": "native perp account only; main-dex positions of wallets with a known positive native equity",
"note": "hours rebuilt from fills are null"
}When a ratio is null, never 0:
- every hour before
leverage.data_from(2026-08-11) isnullon all three, and a window wholly before it does not read the leverage table at all; - an hour with no stored leverage row is
nullon all three; - an hour rebuilt from fills is
nullon all three: the equity stored for it is not a measurement, so it is left out at read time, andleverage.notesays so; - with a row,
perp_biasandequity_exposurearenullwhen no counted wallet has a positive equity, andequity_covered_shareisnullwhen the cohort holds no main-dex notional. A cohort that holds main-dex notional but has no counted wallet gets a real0share.
has_more and the paging are the series' own; include does not change them.
Errors
| Status | When |
|---|---|
400 | axis is not size or pnl, start or end is not ISO-8601, start is more than 8760 hours before end, or include names a token other than leverage. The body is {"detail": "…"}. |
404 | cohort is not a label or slug of axis. The body names the axis only: {"detail": "unknown cohort for axis 'size'"}. |
422 | axis is missing, or hours is above 8760 or limit above 5000. |
401 / 429 | No or bad credential, or the hourly budget or the per-minute cap is spent — see Authentication and Rate limits. |
503 | The store behind it is unavailable. |
The ladders and their labels are on Cohorts and axes; when a label was computed is on Label basis.