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.

Orders: place, modify, cancel, batch, dead man's switch

Practitioner

An 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.

Every order, change and cancel you send is a signed, nonced transaction ordered by consensus, because the order book is protocol state. The reply arrives once its block commits: an execution result, not an acknowledgement.

Place, modify and cancel each take a list, so one signature covers many orders. The wire has no market type, fill-or-kill or good-til-date: a market order is a limit order with a worst price.

The docs’ example buys 0.2 of asset 4 at up to 1100, resting any remainder:

{
"type": "order",
"orders": [
{"a": 4, "b": true, "p": "1100", "s": "0.2", "r": false, "t": {"limit": {"tif": "Gtc"}}}
],
"grouping": "na"
}
Key Meaning Type
a asset id (asset ids) number
b is buy boolean
p limit price, and the worst price for triggers and market orders decimal string
s size in base units decimal string
r reduce only boolean
t {"limit": {"tif": ...}} or {"trigger": {...}} object
c client order id (cloid), optional 128-bit hex string

The body is {action, nonce, signature}, plus optional vaultAddress (for a sub-account or vault) and expiresAfter. Key order and decimal strings are hashed: see signing and precision.

tif On first touching the book Use
Gtc fills what it can, rests the rest ordinary limit orders
Ioc fills what it can, cancels the rest taking liquidity; partial fills are kept
Alo cancelled instead of matching post-only quoting
FrontendMarket behaves like Ioc, labelled a market order market orders with a worst price in p

The exchange docs list only Alo, Ioc and Gtc, yet their orderStatus example returns "tif": "FrontendMarket" with "orderType": "Market", and SDKs accept all four.

A trigger replaces the limit object:

{"trigger": {"isMarket": true, "triggerPx": "1050", "tpsl": "sl"}}

Triggers fire on the mark price; p is still the worst acceptable fill. A TP/SL without r: true is rejected in pre-validation.

grouping Meaning
"na" no link between the orders
"normalTpsl" TP/SL children tied to a parent order in the same batch, fixed at the parent’s size
"positionTpsl" TP/SL tied to the existing position
{"p": N} order priority: a fee of N / 100,000,000 of notional buys earlier execution for IOC or queue position for ALO (priority fees)

normalTpsl children are placed only if the parent fully fills, or partially fills and is then cancelled for insufficient margin; cancelling a partly filled parent cancels them. Priority grouping needs every order on a non-outcome asset, and all Ioc or all non-reduce-only Alo.

An optional "builder": {"b": "0x...", "f": 10} beside grouping pays builder b; f is in tenths of a basis point (10 is 1 bp). The user first approves a maximum with approveBuilderFee from the main wallet (builder codes).

"ok" can still carry per-order errors: read every entry of statuses, one per order.

{"status": "ok", "response": {"type": "order", "data": {"statuses": [
{"resting": {"oid": 77738308}},
{"filled": {"totalSz": "0.02", "avgPx": "1891.4", "oid": 77747314}},
{"error": "Order must have minimum value of $10."}
]}}}

SDK types also carry bare "waitingForTrigger", "waitingForFill" and "success", and a cloid in resting when one was sent. A request rejected whole returns {"status": "err", "response": "<string>"} (errors).

Payload-only errors (an empty batch, a non-reduce-only TP/SL, an order too far from the reference price, some tick errors) return one error for the whole batch: apply it to every order. Batch with the docs’ recipe; costs are on rate limits.

{"type": "modify", "oid": 77738308, "order": {"a": 4, "b": true, "p": "1101", "s": "0.2", "r": false, "t": {"limit": {"tif": "Alo"}}}}

Modify works only on resting limit orders:

Rule Detail
oid an order id or a cloid
batchModify "modifies": [{"oid": ..., "order": {...}}]
Result a new oid; success can be a bare {"status": "ok"} with no statuses
Queue size-only keeps priority; a price change goes to the back at the new level
a: true (always place) the new order is placed even if the cancel half fails
a omitted the new order must be a non-trigger Alo, or a Gtc that would not execute, converted to Alo
{"type": "cancel", "cancels": [{"a": 4, "o": 77738308}], "f": true}
{"type": "cancelByCloid", "cancels": [{"asset": 4, "cloid": "0x1234567890abcdef1234567890abcdef"}], "f": true}

The keys differ: a and o, versus asset and cloid. Each status is "success" or {"error": "Order was never placed, already canceled, or filled."}.

f is the fast flag, recommended by the docs on every cancel. A fast cancel of a trigger order is rejected, so send those in their own action without f. It does nothing else yet; a future upgrade will prioritise only f cancels in the mempool.

{"type": "scheduleCancel", "time": 1713825896591}

At time (milliseconds) every open order is cancelled with status scheduledCancel; omitting time clears it. Each firing counts as a trigger, against the daily limit under The numbers. Re-arm on a heartbeat so it fires only if your process stops.

{"type": "twapOrder", "twap": {"a": 0, "b": true, "s": "10", "r": false, "m": 60, "t": false}}
{"type": "twapCancel", "a": 0, "t": 77738308}

m is the running time in minutes; t randomises suborder size. It runs on HyperCore, not in your process, and appears in twapStates and userTwapSliceFills. Note the singular status:

Result Response
Placed {"status": {"running": {"twapId": N}}}
Bad duration {"status": {"error": "Invalid TWAP duration: 1 min(s)"}}
Item Value
Cloid 128-bit hex string, for example 0x1234567890abcdef1234567890abcdef
Builder fee f tenths of a bp; at most 0.1% on perps, 1% on spot
Priority rate N / 100000000 of notional
scheduleCancel.time at least 5 s ahead; 10 firings per day, reset 00:00 UTC
TWAP running time 5 minutes to 7 days; $100 minimum total
TWAP suborders at most every 30 s; 3% maximum slippage each; catch-up capped at 3x the normal suborder
TWAP randomise suborder size varied by up to 20% either way
Minimum order value $10 on perps; 10 quote tokens on spot
Open orders 1000 plus 1 per 5M USDC of volume, at most 5000
Reduce-only and trigger orders rejected when placed with at least 1000 other open orders
IP weight per order action 1 + floor(n / 40)
Address budget per batch n
Market TP/SL slippage tolerance 10%
Suggested batch cadence every 0.1 s
In the UI On the wire
Market FrontendMarket with a worst price
Stop, take triggers
TP/SL on an order normalTpsl
TP/SL on a position positionTpsl
Scale one batch of limits, a status per level
Chase an Alo order repriced by your browser tab; it stops when the tab closes
TWAP runs on HyperCore itself
  • Reconcile by cloid: oids change on modify and are unknown after a timeout, and orderStatus takes a cloid.
  • While quoting, arm scheduleCancel and cancel all on shutdown, or resting Alo orders fill unhedged.
  • Set p on market orders deliberately: one production app used mark plus or minus 3 per cent. Outcome bounds are 0.99999 to buy, 0.00001 to sell.
  • To stop an order in flight, sign a noop with its nonce; the docs rate this above cancel.
  • f: false on a cancel or a: false on a modify is rejected when hashed: omit the key.
  • Modify errors are a top-level string, not a status: Price would cross book.
  • A stale expiresAfter rejection costs 5 times the usual address budget.
  • CoreWriter’s limit order (action 1) knows only Alo, Gtc and Ioc: no FrontendMarket from the HyperEVM.
  • On outcome markets Ioc fills partially and cancels the rest; FOK, GTD and priority grouping are rejected.

For each order from a trader’s side, see Order types and time in force. For the rules every p and s must pass, see Precision.