Exchange Wire Formats

Hyperliquid Spot wire format

How Hyperliquid spot messages become rows in our Parquet files. Each data type below shows a real message next to the rows we publish for it, with the source and the rule for every column. Hover a line or a column to see how they connect.

Checked against our pipeline

These messages were captured from Hyperliquid spot on 2026-10-05. Our test suite replays each one through the production collector parser and postprocessor, and fails if the published rows differ from the rows on this page. Files written before a change to the pipeline can differ; see Known Gaps & Corrections.

Spot subscriptions carry "spot": true. Hyperliquid identifies most spot markets as @<index> (HYPE/USDC is @107); we publish them under the pair name with _, for example HYPE_USDC. The examples use PURR/USDC, the one spot market Hyperliquid names by its pair.

  • Public WebSocket: wss://api.hyperliquid.xyz/ws
  • Info REST (market metadata): https://api.hyperliquid.xyz/info

Exchange API reference: hyperliquid.gitbook.io. Conventions shared by every exchange are on the wire formats overview.

Trades

One row per fill from the trades subscription for each market.

  • WebSocket trades

Trade

WebSocket message · tradesreceived 2026-10-05 19:27:53.011457 UTC
{
"channel": "trades",
"data": [
{
"coin": "PURR/USDC",
"side": "A",
"px": "0.15967",
"sz": "1055.0",
"time": 1791228472658,
"hash": "0x10fa35a3dfc5ea3512730445ea37be0201fe00897ac90907b4c2e0f69ec9c41f",
"tid": 816377306689042,
"users": ["0x9266865bb6afb4c4f618544dd3b8c970f17aa664", "0xc6df8428e2b9bade2485e9733da37f423b7238aa"]
}
]
}

Published row

received_time1791228473011457000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Hyperliquid.
event_time1791228472658data[].timeCopied. Milliseconds. Hyperliquid sends one time per trade, so event_time equals trade_time.
symbolPURR_USDCdata[].coinThe market's pair in upper case with / replaced by _. Hyperliquid names spot markets @<index> (HYPE/USDC is @107), except PURR/USDC; the collector maps each index to its base and quote token names from spotMeta.
trade_id816377306689042data[].tidCopied. Hyperliquid's tid is a hash of the buyer's and seller's order IDs, not a sequence number: it does not increase and cannot reveal gaps.
price0.15967data[].pxCopied as the exact decimal string Hyperliquid sent.
quantity1055.0data[].szCopied as the exact decimal string. Base asset units.
trade_time1791228472658data[].timeCopied. Milliseconds.
is_buyer_makertruedata[].sideside is the aggressor: A (ask, seller aggressed) gives true, B (bid, buyer aggressed) gives false.
order_typemarket—Always market. Hyperliquid does not send an order type; the constant marks the row as a taker fill.

Recent trades sent after a subscribe

The first trades message after a subscribe repeats the market's latest 30 trades, which on quiet markets can be hours or months old. This one arrived 46 seconds into the hour. Trades timed more than 5 seconds before the hour started are dropped; trades from the last 5 seconds of the previous hour are published in this hour unless that hour already published them.

Abridged: The message held 30 trades: 4 from more than 5 seconds before the hour, 4 from its last 5 seconds and 22 from this hour. Two of each are shown.

WebSocket message · tradesreceived 2026-10-05 20:00:46.348537 UTC
{
"channel": "trades",
"data": [
{
"coin": "PURR/USDC",
"side": "B",
"px": "0.15543",
"sz": "80.0",
"time": 1791230361434,
"hash": "0xf08ba9f8823c8bb8f2050445eaa01e0201dd00de1d3faa8b9454554b413065a3",
"tid": 586859438661648,
"users": ["0x19ae423cbb2b06701a64896d12bb318e26e3e64f", "0x2ad22b8c322e3322461aa339f60193576aa34698"]
},
{
"coin": "PURR/USDC",
"side": "B",
"px": "0.15536",
"sz": "321.0",
"time": 1791230362732,
"hash": "0xffcb89c730ed035b01450445eaa03102036100accbe0222ea3943519efe0dd46",
"tid": 270882739007052,
"users": ["0xa5954b9a62ecde4a077c8c12ab66c8093917fde0", "0x9266865bb6afb4c4f618544dd3b8c970f17aa664"]
},
{
"coin": "PURR/USDC",
"side": "A",
"px": "0.1549",
"sz": "644.0",
"time": 1791230397375,
"hash": "0xf58f8171d9341951f7090445eaa22402042f00577437382499582cc49837f33c",
"tid": 344755378042620,
"users": ["0x9266865bb6afb4c4f618544dd3b8c970f17aa664", "0xc5549b1aac5a98a9f4bebe37cc70cd48c064d514"]
},
{
"coin": "PURR/USDC",
"side": "B",
"px": "0.155",
"sz": "1124.0",
"time": 1791230397912,
"hash": "0x132c735ed531f0db14a60445eaa22b02058c004470350fadb6f51eb19435cac5",
"tid": 1123349272790135,
"users": ["0xc6df8428e2b9bade2485e9733da37f423b7238aa", "0x9266865bb6afb4c4f618544dd3b8c970f17aa664"]
},
{
"coin": "PURR/USDC",
"side": "A",
"px": "0.1549",
"sz": "35.0",
"time": 1791230400602,
"hash": "0xeceeb6ef08083168ee680445eaa24e02125200d4a30b503a90b76241c70c0b53",
"tid": 359068625617933,
"users": ["0x9266865bb6afb4c4f618544dd3b8c970f17aa664", "0xd440715f2ce6f7ed1924f282e0096c863e7049f7"]
},
{
"coin": "PURR/USDC",
"side": "A",
"px": "0.15489",
"sz": "199.0",
"time": 1791230400602,
"hash": "0xeceeb6ef08083168ee680445eaa24e02125200d4a30b503a90b76241c70c0b53",
"tid": 252307041241746,
"users": ["0x50fef8d71afce6404d0cbb2a8bb0df65f87b1685", "0xd440715f2ce6f7ed1924f282e0096c863e7049f7"]
}
]
}

Published rows · 4

received_time1791230446348537000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Hyperliquid.
event_time1791230397375data[].timeCopied. Milliseconds. Hyperliquid sends one time per trade, so event_time equals trade_time.
symbolPURR_USDCdata[].coinThe market's pair in upper case with / replaced by _. Hyperliquid names spot markets @<index> (HYPE/USDC is @107), except PURR/USDC; the collector maps each index to its base and quote token names from spotMeta.
trade_id344755378042620data[].tidCopied. Hyperliquid's tid is a hash of the buyer's and seller's order IDs, not a sequence number: it does not increase and cannot reveal gaps.
price0.1549data[].pxCopied as the exact decimal string Hyperliquid sent.
quantity644.0data[].szCopied as the exact decimal string. Base asset units.
trade_time1791230397375data[].timeCopied. Milliseconds.
is_buyer_makertruedata[].sideside is the aggressor: A (ask, seller aggressed) gives true, B (bid, buyer aggressed) gives false.
order_typemarket—Always market. Hyperliquid does not send an order type; the constant marks the row as a taker fill.

Notes

  • hash and users (buyer and seller addresses) are not published. Some fills carry an all-zero hash.
  • One message can hold several fills of one taker order (same time, side and hash); each fill is its own row with its own tid.
  • After every subscribe, Hyperliquid first sends the market's most recent trades (about 30), however old, without marking them as a replay. On a reconnect the collector drops replayed trades it already wrote. The postprocessor drops trades timed more than 5 seconds before the start of the file's hour, exact duplicates, and trades already published in an earlier hour.
  • Before the 2026-09 data-integrity release, a replayed trade could be published again in a later hour's file. Deduplicate older history on (symbol, trade_id, trade_time): Hyperliquid documents tid as unique only together with the coin and the time.

Column types and descriptions: Trades schema.

Order Book

One row per price level of each l2Book snapshot.

  • WebSocket l2Book

Every l2Book message is a full snapshot of the top of the book, not a delta. Each one becomes one snapshot row per level.

Abridged: Hyperliquid sent 20 bid and 20 ask levels; the best 3 of each are shown.

WebSocket message · l2Bookreceived 2026-10-05 19:18:01.709503 UTC
{
"channel": "l2Book",
"data": {
"coin": "PURR/USDC",
"time": 1791227881323,
"levels": [
[
{
"px": "0.15963",
"sz": "1000.0",
"n": 1
},
{
"px": "0.15962",
"sz": "2165.0",
"n": 3
},
{
"px": "0.15952",
"sz": "1263.0",
"n": 1
}
],
[
{
"px": "0.15983",
"sz": "2879.0",
"n": 2
},
{
"px": "0.15985",
"sz": "103.0",
"n": 1
},
{
"px": "0.15998",
"sz": "610.0",
"n": 1
}
]
]
}
}

Published rows · 6

received_time1791227881709503000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Hyperliquid.
event_time1791227881323data.timeCopied. Milliseconds.
transaction_time1791227881323data.timeCopied from the same time. Milliseconds.
symbolPURR_USDCdata.coinThe market's pair in upper case with / replaced by _. Hyperliquid names spot markets @<index> (HYPE/USDC is @107), except PURR/USDC; the collector maps each index to its base and quote token names from spotMeta.
event_typesnapshot—snapshot for every l2Book message.
first_update_idnull—Null. Hyperliquid books carry no update IDs.
final_update_id1791227881323data.timeThe snapshot's time. Hyperliquid has no update ID, so the time identifies the snapshot.
prev_final_update_idnull—Null. Snapshots do not chain.
last_update_id1791227881323data.timeThe snapshot's time, as in final_update_id.
sidebiddata.levels[0]data.levels[1]bid for levels in levels[0], ask for levels in levels[1]. One row per level.
price0.15963data.levels[0][].pxdata.levels[1][].pxCopied as the exact decimal string.
quantity1000.0data.levels[0][].szdata.levels[1][].szCopied as the exact decimal string: the total resting size at that price. Base asset units.
order_count1data.levels[0][].ndata.levels[1][].nCopied. Number of resting orders at that price.

Notes

  • Each snapshot replaces the whole book: rebuild your book from the rows of each final_update_id. A snapshot holds at most 20 levels per side at full price precision. Hyperliquid documents at most one push per 0.5 seconds; in October 2026 a market's snapshots arrive about every 5.4 seconds (about 670 per hour).
  • A snapshot with no levels on either side publishes one row with side noop and price and quantity 0, which clears the book. Files written before the October 2026 pipeline update have no row for an empty snapshot.
  • A snapshot holding a level with a zero, negative or unparsable price or size is withheld whole instead of being published as a partial book. Before the October 2026 pipeline update such a snapshot could be published as a partial or empty book.
  • Files can start with a checkpoint snapshot of the book carried over from the previous hour: its received_time is the hour start, transaction_time is null, and event_time, final_update_id and last_update_id are the time of the snapshot the book came from.

Column types and descriptions: Order Book schema.

Mark Price

One row per activeSpotAssetCtx message for each market.

  • WebSocket activeSpotAssetCtx

The collector subscribes to activeAssetCtx for each spot market; Hyperliquid answers on the activeSpotAssetCtx channel.

WebSocket message · activeSpotAssetCtxreceived 2026-10-05 19:18:01.768875 UTC
{
"channel": "activeSpotAssetCtx",
"data": {
"coin": "PURR/USDC",
"ctx": {
"prevDayPx": "0.17128",
"dayNtlVlm": "2160182.4432799988",
"markPx": "0.15971",
"midPx": "0.159735",
"circulatingSupply": "594788239.0212099552",
"coin": "PURR/USDC",
"totalSupply": "594788250.3277299404",
"dayBaseVlm": "12955450.0"
}
}
}

Published row

received_time1791227881768875000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Hyperliquid.
event_time1791227881768—Our receive clock in milliseconds (received_time / 1,000,000). Asset contexts carry no exchange timestamp.
symbolPURR_USDCdata.coinThe market's pair in upper case with / replaced by _. Hyperliquid names spot markets @<index> (HYPE/USDC is @107), except PURR/USDC; the collector maps each index to its base and quote token names from spotMeta.
mark_price0.15971data.ctx.markPxCopied. If markPx is missing, midPx is used.
index_pricenull—Null. Hyperliquid's spot contexts carry no oracle price (oraclePx).
estimated_settle_pricenull—Null. Spot markets do not settle.
funding_ratenull—Null. Spot markets have no funding.
next_funding_timenull—Null. Spot markets have no funding.

Notes

  • Hyperliquid does not document how often it pushes spot asset contexts. In October 2026 a push arrives about once per second, so a market has about 3,500 rows per hour. Every push becomes a row, whether or not a value changed.
  • The 24h fields (prevDayPx, dayNtlVlm, dayBaseVlm), midPx (unless markPx is missing), circulatingSupply and totalSupply are not published.
  • A context with neither markPx nor midPx is not published.
  • Files written before the October 2026 pipeline update have event_time in nanoseconds (the receive clock, equal to received_time). Divide those values by 1,000,000.

Column types and descriptions: Mark Price schema.

Not published

  • Ticker: Hyperliquid has no 24h ticker channel; the 24h fields of the asset contexts are not published.
  • Open Interest: Spot markets have no open interest.
  • Liquidations: Spot markets have no liquidations.