Skip to content
BuildBuild on HyperCore16 pages
Architecture: info, exchange, WebSocketFoundationHyperliquid's API has three surfaces: an unsigned read endpoint, a signed write endpoint, and a WebSocket that streams data and can carry both.Your first requestFoundationReading Hyperliquid needs no key, no account and no risk: three unsigned POST requests return the list of markets, an order book and any address's positions.Asset ids and namingPractitionerOrders name a market by an integer asset id and info requests by a coin string, and perps, spot, HIP-3 and outcomes each derive both by a different rule.Precision: tick size, lot size, significant figuresPractitionerA HyperCore price has at most 5 significant figures and a decimal cap set by szDecimals, a size at most szDecimals decimals, and outcomes use a 0.00001 grid.Signing from first principlesExpertL1 actions sign a keccak hash of their msgpack bytes, user-signed actions sign readable EIP-712 data, and one wrong byte in either recovers a stranger's address.Nonces, expiry and API walletsPractitionerHyperCore keeps each signer's 100 highest nonces and accepts a new one only if unused, above the smallest, and within 2 days before and 1 day after block time.Orders: place, modify, cancel, batch, dead man's switchPractitionerAn order is a signed action carrying a batch of compact orders; modify, cancel, TWAP and the dead man's switch are separate actions, each with its own response.Transfers and withdrawalsPractitionerEvery HyperCore transfer is a signed action: sends and withdrawals need the account's own key, and an API wallet's transfer actions keep value inside the account.Multi-sig actionsExpertA multi-sig action carries enough authorised users' signatures over one nonce and one named leader, in an envelope only the leader signs and submits.WebSocket: subscriptions, post requests, heartbeatsPractitionerOne WebSocket streams book, trade and account updates as blocks execute and carries signed actions, but drops without warning and forgets every subscription.Rate limits and user limitsPractitionerHyperliquid meters each IP by request weight, 1200 per minute, and each address by actions: 10,000 plus one per USDC traded.Priority fees and the activation feeExpertHyperliquid sells latency in two burned auctions, read priority per IP and write priority per order, and charges 1 quote token to activate a new account.Error responsesPractitionerHyperliquid reports errors at four layers, from HTTP status to a string inside a successful response, and several name a cause other than the real one.Debugging signatures and wire shapesExpertA signature over wrong bytes still verifies, so HyperCore recovers a stranger's address and says it does not exist; the fix is almost always the encoding.Optimising latencyExpertMost of an order's round trip is consensus; code wins by streaming reads, cutting serial round trips, using the fast order class and never stalling orders.Data: historical, node and explorerPractitionerThe API keeps only recent history; a full record needs pagination, archived node data or your own node, and each trade counted once by its trade id.
BuildBuild on the HyperEVM9 pages
What the HyperEVM is, and is notFoundationThe HyperEVM is Hyperliquid's smart contract environment: it reads HyperCore state and queues HyperCore actions, but never executes them atomically.Blocks, gas and RPCPractitionerThe HyperEVM produces small blocks every second and big blocks every minute, prices gas with EIP-1559 in HYPE, and serves a JSON-RPC with no historical state.Moving assets between HyperCore and the HyperEVMPractitionerLinked tokens cross between HyperCore and the HyperEVM via per-token system addresses, with a decimal offset and a 200k-gas fee when leaving HyperCore.Linking a tokenExpertLinking binds a HyperCore token to one ERC20 through the spot deployer's request and the contract deployer's finalisation; the protocol checks almost nothing else.Reading HyperCore: precompilesExpertRead precompiles are 21 fixed addresses, 0x800 to 0x814, that return HyperCore state as of the EVM block's construction, and only at the latest block.Writing to HyperCore: CoreWriterExpertCoreWriter turns a contract call into a HyperCore action for the caller's own account, run after the EVM block, with no result returned and no revert on refusal.Execution order and timingExpertEach L1 block runs the EVM block, then EVM to HyperCore transfers, then CoreWriter actions; on mainnet most actions land within half a second, vault transfers in about 4 s.PatternsExpertA contract that touches HyperCore stays solvent by recording an intent, sending the action, and settling only on HyperCore state that visibly moved.Footguns, measuredExpertTwelve ways a HyperEVM contract loses money or silently does nothing when it touches HyperCore, each with the on-chain evidence and the fix.

Data: historical, node and explorer

Practitioner

The API keeps only recent history; a full record needs pagination, archived node data or your own node, and each trade counted once by its trade id.

The info endpoint forgets. userFills returns only your 2000 most recent fills (other caps in the numbers), and no public stream carries every user’s fills: the trades feed gives each coin’s trades with both counterparties, but no fees or builder codes.

Counting rows correctly matters as much as finding them. Say a taker buys 10,000 USDC of a perp from one maker. You get two fill rows of 10,000 USDC notional, a taker row and a maker row, sharing one tid. Sum every row and you count 20,000 USDC; count one notional per tid and you get 10,000.

Miscounting like this (two rows per match, shared hashes, outcome fills that never touched the book) is why public volume numbers disagree.

Source Holds Limits
Info endpoint per-user fills, orders, funding, ledger; per-market trades and candles see the caps below; time-range responses paginate
S3 bucket hyperliquid-archive L2 book snapshots (market_data) and asset contexts (asset_ctxs) uploaded about monthly; no guarantee of timeliness; data may be missing; no candles or spot asset data; the requester pays transfer costs
S3 bucket hl-mainnet-node-data fills by block, older fills and trades, explorer blocks, L1 transactions, non-trade events the requester pays transfer costs
Your own node everything the node writes under ~/hl/data about 100 GB of logs per day
Explorer userDetails one address’s L1 actions, typed, with an error field the 300 most recent

Inside hl-mainnet-node-data:

Prefix Holds
node_fills_by_block current fills, written by a node run with --write-fills --batch-by-block
node_fills older fills, in the API format
node_trades older trades, not in the API format
explorer_blocks, replica_cmds historical blocks and L1 transactions
misc_events_by_block transfers, staking and funding

Time-range requests return at most 500 elements or distinct blocks; use the last timestamp returned as the next startTime.

{"type": "userFillsByTime", "user": "0x0000000000000000000000000000000000000000", "startTime": 1681222254710, "aggregateByTime": false}
  • startTime and optional endTime are inclusive milliseconds, so pages overlap at the boundary: deduplicate.
  • History requests cost extra IP weight per 20 items returned (rate limits).
  • Query with the account’s own address; an API wallet’s address returns nothing.

A fill carries coin, px, sz, side, time, startPosition, dir, closedPnl, oid, feeToken and:

Field Meaning
crossed true for the taker
fee negative is a rebate
builderFee optional, already included in fee
hash the L1 transaction hash, shared by every partial fill of one transaction: never a fill key
tid the trade id, the key to deduplicate on. The docs define it as a 50-bit hash of the buyer’s and seller’s order ids, and use (block_time, coin, tid) as the globally unique trade id

aggregateByTime: true merges one crossing order’s partial fills into fewer rows; don’t mix pulls with and without it.

Coin names differ by market (asset ids):

Market coin
Validator-operated perps plain name
HIP-3 perps dex:COIN
Spot pairs @N or PURR/USDC
Outcome sides #N

A node writes hourly files. A node_trades record holds both sides: side_info[0] is the buyer, side_info[1] the seller:

{
"coin": "COMP",
"side": "B",
"time": "2024-07-26T08:26:25.899",
"px": "51.367",
"sz": "0.31",
"hash": "0xad8e0566e813bdf98176040e6d51bd011100efa789e89430cdf17964235f55d8",
"trade_dir_override": "Na",
"side_info": [
{"user": "0xc64cc00b46101bd40aa1c3121195e85c0b0918d8", "start_pos": "996.67", "oid": 12212201265, "twap_id": null, "cloid": null},
{"user": "0x768484f7e2ebb675c57838366c02ae99ba2a9b08", "start_pos": "-996.7", "oid": 12212198275, "twap_id": null, "cloid": null}
]
}
Output under ~/hl/data Contents
replica_cmds/{start_time}/{date}/{height} blocks parsed as transactions
periodic_abci_states/{date}/{height}.rmp state snapshots every 10,000 blocks
node_trades/hourly/{date}/{hour} trades, both sides per record
node_order_statuses/hourly/{date}/{hour} every order status change, with the full order
node_raw_book_diffs/hourly/{date}/{hour} book changes: new {sz}, update {origSz, newSz}, or remove
misc_events/hourly/{date}/{hour} staking deposits, delegations and withdrawals, validator rewards, funding, ledger updates

Ledger updates cover withdrawals and deposits (the Arbitrum bridge), vault flows, liquidations, InternalTransfer (a perp USDC transfer), sub-account and spot transfers, spot genesis, RewardsClaim (builder and referrer fees), AccountActivationGas, PerpDexClassTransfer and DeployGasAuction. A funding event carries coin, usdc, szi, fundingRate and nSamples.

From an abci state snapshot a node can compute an L4 book (every resting order at every level, in time order, trigger orders last); applying the order status stream keeps it live. Priority fee records in node data are listed on priority fees.

The explorer: what the chain did with your action

Section titled “The explorer: what the chain did with your action”
POST https://rpc.hyperliquid.xyz/explorer
{"type": "userDetails", "user": "0x..."}

It shows what the chain recorded for an action whose reply you never saw, or one sent through CoreWriter, which never reports back to the HyperEVM. A CoreWriter action HyperCore understood appears typed; one it did not appears nowhere. EVM transactions appear as evmRawTx.

The type name tells the two routes apart; recorded on testnet from one account:

CoreWriter action 15 {"type":"SystemBoleAction","operation":"supply","token":0,"wei":1000000000000}
HTTP borrowLend {"type":"borrowLend","operation":"supply","token":0,"amount":"5"}

CoreWriter send-asset actions, such as a contract’s transfer back to the HyperEVM, appear as SystemSendAssetAction. Explorer requests cannot go over the WebSocket.

Cap Value
userFills 2000 most recent
userFillsByTime 2000 per response; 10,000 most recent reachable
historicalOrders, userTwapSliceFills 2000 most recent
candleSnapshot 5000 most recent candles
Time-range responses 500 elements or distinct blocks
Explorer userDetails 300 most recent actions
Explorer request weight 40
Node state snapshots every 10,000 blocks
Node output about 100 GB per day

For a complete tax or accounting record, record fills as they happen or export them before they pass the caps above.

  • Record from day one: subscribe to userFills, persist every fill keyed on tid, backfill gaps with userFillsByTime pages (WebSocket).
  • For venue-wide data, read the node bucket or run a node.
  • Use the explorer for forensics, not bookkeeping: one Safe sent 278 actions in half an hour, so its 300-action window reached back barely further.
  • Build funding, transfer and staking histories from misc_events, not balance changes.
  • Outcome markets produce structural fills with dir Split Outcome, Merge Outcome, Negate Outcome, Merge Question and Settlement; only Buy and Sell crossed the book. Structural fills were about a fifth of all outcome fills, and settlement fills never carry a builder code.
  • On outcome markets dayNtlVlm is per side and the two sides sum to dayBaseVlm; adding both sides’ dayNtlVlm double counts.
  • The node archive can hold one side of a trade only: from 2 to 15 May, only 33.3 per cent of 874k archived trades had both sides. Volume from single-sided archives needs a stated correction.

For the source of the deepest data, see Running a node. For reading the error field the explorer returns, see Error responses.