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
{"channel": "trades","data": [{"coin": "PURR/USDC",→ symbol"side": "A",→ is_buyer_maker"px": "0.15967",→ price"sz": "1055.0",→ quantity"time": 1791228472658,→ event_time · trade_time"hash": "0x10fa35a3dfc5ea3512730445ea37be0201fe00897ac90907b4c2e0f69ec9c41f","tid": 816377306689042,→ trade_id"users": ["0x9266865bb6afb4c4f618544dd3b8c970f17aa664", "0xc6df8428e2b9bade2485e9733da37f423b7238aa"]}]}
Published row
event_time equals trade_time./ 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.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.side is the aggressor: A (ask, seller aggressed) gives true, B (bid, buyer aggressed) gives false.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.
{"channel": "trades","data": [{"coin": "PURR/USDC",→ symbol"side": "B",→ is_buyer_maker"px": "0.15543",→ price"sz": "80.0",→ quantity"time": 1791230361434,→ event_time · trade_time"hash": "0xf08ba9f8823c8bb8f2050445eaa01e0201dd00de1d3faa8b9454554b413065a3","tid": 586859438661648,→ trade_id"users": ["0x19ae423cbb2b06701a64896d12bb318e26e3e64f", "0x2ad22b8c322e3322461aa339f60193576aa34698"]},{"coin": "PURR/USDC",→ symbol"side": "B",→ is_buyer_maker"px": "0.15536",→ price"sz": "321.0",→ quantity"time": 1791230362732,→ event_time · trade_time"hash": "0xffcb89c730ed035b01450445eaa03102036100accbe0222ea3943519efe0dd46","tid": 270882739007052,→ trade_id"users": ["0xa5954b9a62ecde4a077c8c12ab66c8093917fde0", "0x9266865bb6afb4c4f618544dd3b8c970f17aa664"]},{"coin": "PURR/USDC",→ symbol"side": "A",→ is_buyer_maker"px": "0.1549",→ price"sz": "644.0",→ quantity"time": 1791230397375,→ event_time · trade_time"hash": "0xf58f8171d9341951f7090445eaa22402042f00577437382499582cc49837f33c","tid": 344755378042620,→ trade_id"users": ["0x9266865bb6afb4c4f618544dd3b8c970f17aa664", "0xc5549b1aac5a98a9f4bebe37cc70cd48c064d514"]},{"coin": "PURR/USDC",→ symbol"side": "B",→ is_buyer_maker"px": "0.155",→ price"sz": "1124.0",→ quantity"time": 1791230397912,→ event_time · trade_time"hash": "0x132c735ed531f0db14a60445eaa22b02058c004470350fadb6f51eb19435cac5","tid": 1123349272790135,→ trade_id"users": ["0xc6df8428e2b9bade2485e9733da37f423b7238aa", "0x9266865bb6afb4c4f618544dd3b8c970f17aa664"]},{"coin": "PURR/USDC",→ symbol"side": "A",→ is_buyer_maker"px": "0.1549",→ price"sz": "35.0",→ quantity"time": 1791230400602,→ event_time · trade_time"hash": "0xeceeb6ef08083168ee680445eaa24e02125200d4a30b503a90b76241c70c0b53","tid": 359068625617933,→ trade_id"users": ["0x9266865bb6afb4c4f618544dd3b8c970f17aa664", "0xd440715f2ce6f7ed1924f282e0096c863e7049f7"]},{"coin": "PURR/USDC",→ symbol"side": "A",→ is_buyer_maker"px": "0.15489",→ price"sz": "199.0",→ quantity"time": 1791230400602,→ event_time · trade_time"hash": "0xeceeb6ef08083168ee680445eaa24e02125200d4a30b503a90b76241c70c0b53","tid": 252307041241746,→ trade_id"users": ["0x50fef8d71afce6404d0cbb2a8bb0df65f87b1685", "0xd440715f2ce6f7ed1924f282e0096c863e7049f7"]}]}
Published rows · 4
event_time equals trade_time./ 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.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.side is the aggressor: A (ask, seller aggressed) gives true, B (bid, buyer aggressed) gives false.market. Hyperliquid does not send an order type; the constant marks the row as a taker fill.Notes
hashandusers(buyer and seller addresses) are not published. Some fills carry an all-zerohash.- One message can hold several fills of one taker order (same
time,sideandhash); each fill is its own row with its owntid. - 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 documentstidas 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.
{"channel": "l2Book","data": {"coin": "PURR/USDC",→ symbol"time": 1791227881323,→ event_time · transaction_time · final_update_id · last_update_id"levels": [[→ side{→ side"px": "0.15963",→ side · price"sz": "1000.0",→ side · quantity"n": 1→ side · order_count},{→ side"px": "0.15962",→ side · price"sz": "2165.0",→ side · quantity"n": 3→ side · order_count},{→ side"px": "0.15952",→ side · price"sz": "1263.0",→ side · quantity"n": 1→ side · order_count}],[→ side{→ side"px": "0.15983",→ side · price"sz": "2879.0",→ side · quantity"n": 2→ side · order_count},{→ side"px": "0.15985",→ side · price"sz": "103.0",→ side · quantity"n": 1→ side · order_count},{→ side"px": "0.15998",→ side · price"sz": "610.0",→ side · quantity"n": 1→ side · order_count}]]}}
Published rows · 6
time. Milliseconds./ 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.snapshot for every l2Book message.time. Hyperliquid has no update ID, so the time identifies the snapshot.time, as in final_update_id.bid for levels in levels[0], ask for levels in levels[1]. One row per level.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
sidenoopandpriceandquantity0, 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_timeis the hour start,transaction_timeis null, andevent_time,final_update_idandlast_update_idare thetimeof 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.
{"channel": "activeSpotAssetCtx","data": {"coin": "PURR/USDC",→ symbol"ctx": {"prevDayPx": "0.17128","dayNtlVlm": "2160182.4432799988","markPx": "0.15971",→ mark_price"midPx": "0.159735","circulatingSupply": "594788239.0212099552","coin": "PURR/USDC","totalSupply": "594788250.3277299404","dayBaseVlm": "12955450.0"}}}
Published row
received_time / 1,000,000). Asset contexts carry no exchange timestamp./ 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.markPx is missing, midPx is used.oraclePx).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(unlessmarkPxis missing),circulatingSupplyandtotalSupplyare not published. - A context with neither
markPxnormidPxis not published. - Files written before the October 2026 pipeline update have
event_timein nanoseconds (the receive clock, equal toreceived_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.