/archive/datasets
The index of the Hyperliquid Parquet file archive — every UTC day that has a fills or positions file, with rows, bytes and the snapshot count, the column schema of both datasets, and the entry for the 5-minute latest positions file.
GET https://data.vike.io/v1/hyperliquid/archive/datasetsThe index of the Hyperliquid file archive: every UTC day that has a file, per dataset, with the file's row
count and size, the column schema of both datasets, and the entry for the latest positions file. It is the
only way to see what exists. There is no folder to browse and no file has a URL of its own: a file is obtained
from /archive/url, which answers with a temporary link.
Two datasets, one Parquet file per UTC day each, from 2026-05-01:
| Dataset | What one file holds | First day |
|---|---|---|
fills | Every fill of every wallet that day, sorted by asset, fill_ts, trade_id, wallet. | 2026-05-01 |
positions | Every 5-minute snapshot of every open position that day, sorted by asset, wallet, snapshot_ts. | 2026-05-08, a partial day |
Positions start on 2026-05-08 because that is the first day the 5-minute snapshots exist. A third file,
latest/positions.parquet, holds the current open positions of every asset and is replaced every 5 minutes. How to
download and read all three is in Download the Hyperliquid file archive.
# what the archive holds: every day with its rows and bytes, the schema of both datasets, and the latest positions file
curl -s "https://data.vike.io/v1/hyperliquid/archive/datasets" \
-H "X-API-KEY: $VIKE_API_KEY"
# the newest day that has a positions file, with its snapshot count
curl -s "https://data.vike.io/v1/hyperliquid/archive/datasets" \
-H "X-API-KEY: $VIKE_API_KEY" \
| jq '[.dates[] | select(.streams.positions)][0]'
# the days whose positions file holds fewer than 250 snapshots: the source has them, the file is not padded
curl -s "https://data.vike.io/v1/hyperliquid/archive/datasets" \
-H "X-API-KEY: $VIKE_API_KEY" \
| jq -r '.dates[] | select(.streams.positions) | select(.streams.positions.snapshots < 250) | "\(.date) \(.streams.positions.snapshots)"'
# how fresh the latest positions file is, and how big
curl -s "https://data.vike.io/v1/hyperliquid/archive/datasets" \
-H "X-API-KEY: $VIKE_API_KEY" \
| jq '.latest.positions | {snapshot_ts, generated_at, rows, bytes}'The route takes no parameters. This is the capture of the index, cut for the page: dates held 173 entries, so
the newest two are kept, and each dataset's schema list is cut to its first two columns (the full lists are
under The columns). The envelope and the latest entry are complete.
{
"dates": [
{
"date": "2026-10-20",
"streams": {
"fills": {
"rows": 13405172,
"bytes": 401098335
}
}
},
{
"date": "2026-10-19",
"streams": {
"fills": {
"rows": 12022655,
"bytes": 358509915
},
"positions": {
"rows": 102738790,
"bytes": 1639446104,
"snapshots": 253
}
}
}
],
"schema": {
"fills": [
{
"name": "fill_ts",
"type": "DateTime64(3, 'UTC')",
"meaning": "Execution time of the fill, UTC, millisecond precision."
},
{
"name": "wallet",
"type": "String",
"meaning": "Trader address, lowercase 0x-hex."
}
],
"positions": [
{
"name": "snapshot_ts",
"type": "DateTime('UTC')",
"meaning": "Snapshot instant, UTC, whole minutes: the START of the ingestion cycle that wrote the row, not the instant of the node state it reads (typically 5-10 minutes earlier). Cycles are usually 5-7 minutes apart and irregular; a source outage leaves a longer gap. The day's `snapshots` count in the manifest says how many there are."
},
{
"name": "wallet",
"type": "String",
"meaning": "Trader address, lowercase 0x-hex."
}
]
},
"url_endpoint": "/v1/hyperliquid/archive/url",
"latest": {
"positions": {
"snapshot_ts": "2026-10-21T10:13:00Z",
"generated_at": "2026-10-21T10:17:15Z",
"rows": 427884,
"bytes": 29578173,
"assets": 341,
"note": "The current open positions of every asset, one row per (wallet, asset, direction), refreshed about every 5 minutes. The columns are those of the daily `positions` file (meanings under `schema.positions`). `snapshot_ts` is per row: the ingestion cycle that last wrote the position. A position that closed within the last 15 minutes can still be present with an older `snapshot_ts`, the same rule as /v1/hyperliquid/positions; keep the rows at the file's `snapshot_ts` for the newest cycle only. There is no `opened_at`: /v1/hyperliquid/positions fills it per page, and joining it here costs 3x the rest of the run. Sorted by (asset, wallet, direction) in row groups of about 65,000 rows with min/max statistics (one asset is 1-2 of them). The file is REPLACED every ~5 minutes: download it whole (about 30 MB); a ranged read can straddle a replacement and fail, so retry it.",
"url_endpoint": "/v1/hyperliquid/archive/url?dataset=positions&date=latest"
}
}
}Reading the index
datesis newest first. Each entry has the day and astreamsobject with one key per dataset that has a file that day.rowsis the number of rows in the file andbytesits size, so you can budget a download before asking for the link.snapshotsappears onpositionsonly: the number of distinctsnapshot_tsvalues in that day's file, counted from the file itself. Read it before you aggregate. A day holds roughly 250 to 290 snapshots, and some hold far fewer because the source has fewer (see the callout on this page).- A day appears once it is complete. Yesterday's files are published in the early UTC morning; the newest day
can therefore carry a
fillsfile before itspositionsfile, as the capture shows for 2026-10-20. latest.positionsis present while that file exists.snapshot_tsis the newest ingestion cycle in it andgenerated_atis when the file was written;rows,bytesandassetsdescribe the file as of that moment. The file is replaced about every 5 minutes, so these values move: ask the index again rather than caching them.url_endpointis where a file is asked for. The index carries no URL for any file, because none exists.
Fewer than 250 snapshots means a gap in the source, not a missing piece of the file
A positions file is never padded. Eleven days hold fewer than 250 snapshots: 2026-05-08 (71, a partial first day),
2026-06-08 (226), 2026-06-26 to 2026-06-29 (124 to 134 each), 2026-06-30 (248), 2026-08-12, 2026-08-13 and
2026-08-17 (236 to 238) and 2026-09-28 (248). The source did not capture the rest. The snapshots field is how a
client tells a thin day from a normal one without opening the file; the
download guide lists the other facts worth
knowing about the data.
The columns
Both lists are the schema key of the response, in file order.
fills
| Column | Type | Meaning |
|---|---|---|
fill_ts | DateTime64(3, 'UTC') | Execution time of the fill, UTC, millisecond precision. |
wallet | String | Trader address, lowercase 0x-hex. |
asset | String | Instrument as Hyperliquid names it: BTC on the main dex, dex:NAME (e.g. xyz:SP500) for a builder-deployed perp. |
side | String | buy or sell: the direction of THIS wallet's order. |
size_token | Float64 | Fill size in base-asset units, unsigned (the direction is side). |
price | Float64 | Execution price, USD. |
size_usd | Float64 | Notional of the fill, size_token * price, USD. |
fee | Float64 | Fee charged in fee_token; negative is a maker rebate. |
fee_token | String | Token the fee is denominated in, e.g. USDC. |
is_maker | Bool | True when this wallet's order was resting on the book. |
order_id | UInt64 | Hyperliquid order id (oid) of this wallet's order. |
trade_id | UInt64 | Hyperliquid trade id (tid). Both counterparties of one trade carry the same value; a fill is identified by (wallet, fill_ts, trade_id). |
crossed | Bool | True when this fill crossed the book (the taker side). |
closed_pnl | Float64 | Realized PnL in USD the node booked on this fill; 0 for a fill that opens or adds to a position. |
dex_name | String | Perp dex the asset trades on: HL for the main dex, else the builder dex (e.g. XYZ). |
start_position | Float64 (nullable) | Signed position in the asset immediately BEFORE this fill (negative is short). NULL for fills before 2026-09-29, when the column was added; 0.0 is a real value (flat before the fill). |
positions
| Column | Type | Meaning |
|---|---|---|
snapshot_ts | DateTime('UTC') | Snapshot instant, UTC, whole minutes: the START of the ingestion cycle that wrote the row, not the instant of the node state it reads (typically 5-10 minutes earlier). Cycles are usually 5-7 minutes apart and irregular; a source outage leaves a longer gap. The day's snapshots count in the manifest says how many there are. |
wallet | String | Trader address, lowercase 0x-hex. |
asset | String | Instrument as Hyperliquid names it: BTC on the main dex, dex:NAME (e.g. xyz:SP500) for a builder-deployed perp. Called symbol in /v1/hyperliquid/positions. The prefix is authoritative: judge the dex by it, not by dex_name. |
direction | Int8 | 1 long, -1 short. The only place the side is stored: size_token and size_usd are never negative. |
size_token | Float64 | Position size in base-asset units, unsigned (the side is direction). |
size_usd | Float64 | Notional of the position at mark_price, size_token * mark_price, USD, unsigned. |
entry_price | Float64 | Average entry price of the position, USD. |
mark_price | Float64 | Mark price when the row was written, USD. |
liquidation_price | Float64 | Liquidation price, USD; 0 when the position has none (e.g. a well-collateralised cross-margin position). |
unrealized_pnl | Float64 | Unrealized PnL in USD, direction * (mark_price - entry_price) * size_token. |
leverage | Float32 | Leverage of the position as a multiple (10 = 10x). 0 when none was recorded, which happens on cross-margin rows. |
margin_used | Float64 | Margin the position ties up, USD: size_usd / leverage, or size_usd itself where leverage is 0. |
size_cohort | String | Account-value size tier of the wallet WHEN THE ROW WAS WRITTEN (shrimp, 2x shrimp, fish, ... up to 4x whale: 12 absolute-dollar thresholds assigned at ingestion), as stored: a point-in-time label, not today's grading. The same field and vocabulary as size_cohort in /v1/hyperliquid/positions. |
leverage_type | String | cross or isolated. |
dex_name | String | Perp dex the asset trades on: HL for the main dex, else the builder dex (e.g. XYZ). Rows written while a clearinghouse was not yet registered hold the literal clsN (e.g. cls10) and keep it; the asset prefix is authoritative. |
state_ts | DateTime('UTC') | The instant the state-derived columns (size, entry, mark, unrealized_pnl, leverage, margin_used, direction) describe, read from the node's state file; snapshot_ts is the WRITE time of the ingestion cycle, typically 5-10 minutes later (liquidation_price is re-read from the node at write time and belongs to snapshot_ts). 1970-01-01 00:00:00 means the row came from no state file (the per-wallet API fallback) or was written before 2026-08-22, when the column was added. Do not anchor a projection of the row on it: use snapshot_ts. |
liq_progress | Float64 | How far the mark has moved from entry toward liquidation, clamped to 0..1: 0 at or in profit versus entry (or no liquidation price), 1 at or through the liquidation price. When a cross-margin liquidation price has drifted past entry it falls back to liquidation_price / mark_price (long) or mark_price / liquidation_price (short). The same SQL as liq_progress in /v1/hyperliquid/positions. |
opened_at, which /v1/hyperliquid/positions fills in per page, is not in these files. The latest file has
the same 17 columns.
Related
/archive/url— the temporary link to one of these files.- Download the Hyperliquid file archive — fetch a file and read it.
/positions— the same positions through the API, current or by window, cursor-paged./wallets/{address}/fills— one wallet's fills through the API.
/ohlcv/export
Streams the same single page as NDJSON — one header line naming what answered, then one line per bar.
/archive/url
Asks for a temporary download link to one Hyperliquid archive file — a fills or positions day, or the 5-minute latest positions file. The link needs no key, names exactly one file and works for 300 seconds.