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.

Nonces, expiry and API wallets

Practitioner

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

A nonce stops a signed action from working twice, so a transfer’s receiver can’t replay it and drain the sender. Ethereum’s per-address counter (exactly the previous nonce plus one) would break an order book: thousands of orders and cancels a second can’t stay in sequence once two cross in flight.

HyperCore keeps recent nonces per signer instead: out of order is fine, twice is not. Say your bot signs three orders at nonces t, t + 1 and t + 2, where t is the current millisecond, and the third lands first. The other two still pass: unused, and above the smallest stored nonce. Resend t + 1 after it lands and it’s refused.

Each API wallet has its own set.

HyperCore stores each signer’s 100 highest nonces. A new nonce must:

  1. be larger than the smallest of those 100,
  2. never have been used, and
  3. lie inside (T - 2 days, T + 1 day), where T is the block timestamp in milliseconds.

The signer is whoever’s key signed: the account, or its API wallet. Sub-accounts and vaults signed for by one API wallet share that wallet’s nonce set.

Rule 3 makes the docs’ recommended nonce, the current time in milliseconds, close to mandatory: fixtures with a fixed 1700000000000 produce correct hashes the exchange rejects. Rule 1 tolerates reordering: with steady millisecond nonces, a late action survives roughly until 100 newer ones land.

Design What happens Good for
Date.now() on every call Two actions in the same millisecond get the same nonce; the second is refused Nothing concurrent
Atomic counter: start at the current millisecond, add 1 per call, jump forward to the current time when it falls more than 300 ms behind Unique and increasing across threads One process, many threads
max(now, last + 1) kept per signer and network, with a lock so requests leave in nonce order Unique per signer, and arrival order matches nonce order One process, several signers
One API wallet per process Separate signers, separate nonce sets, nothing to coordinate Several processes

Processes sharing one wallet collide: nonces are per signer, not per process. So does one API wallet trading two sub-accounts in parallel. The docs’ recipe for porting a strategy from a centralised exchange, robust to out-of-order arrival within 2 seconds:

  1. One API wallet per trading process; separate wallets for separate sub-accounts.
  2. Batch orders and cancels every 0.1 seconds, IOC and GTC apart from ALO: all-ALO batches are prioritised by the validators.
  3. The trading logic sends orders and cancels to the batching task.
  4. Each batch’s nonce comes from an atomic counter, fast-forwarded to the current millisecond when needed.

{"type":"noop"} only marks its nonce used. Signed with an in-flight action’s nonce, it races it; if it lands first, the original is refused. The docs rate this above a cancel for in-flight orders.

An L1 action may carry expiresAfter, a millisecond timestamp after which it is rejected; user-signed actions cannot. It is in the signed hash, and narrows the nonce window’s 2 days for orders priced for the moment of signing. An action cancelled as expired costs 5 times the usual address-based rate limit.

The account’s own key approves one with the user-signed approveAgent:

{
"type": "approveAgent",
"signatureChainId": "0xa4b1",
"hyperliquidChain": "Mainnet",
"agentAddress": "0x0000000000000000000000000000000000000001",
"agentName": "bot1 valid_until 1724776000000",
"nonce": 1717000000000
}

It is signed as HyperliquidTransaction:ApproveAgent(string hyperliquidChain,address agentAddress,string agentName,uint64 nonce). A wallet approved by a master account can sign for the master or any of its sub-accounts.

Topic Rule
Named and unnamed Without agentName it is the unnamed API wallet, and the name signs as the empty string; with one it is named. Names are 1 to 16 characters.
Expiry Append valid_until <timestamp in ms> to the name; at most 180 days in the future.
Replacement A new unnamed wallet deregisters the old unnamed one; reusing a name deregisters its holder. There is no revoke action: replacement, expiry and the master running out of funds are how a wallet goes away.
Pruning and replay A deregistered or expired wallet, or one whose master has no funds, may be pruned with its used-nonce state, after which its old signed actions could replay. Never re-approve an old address: generate a new key every time.
Reading Info requests need the account’s address, not the wallet’s. userRole on a wallet returns {"role":"agent","data":{"user":"0x..."}}. The undocumented extraAgents lists {address, name, validUntil}, and returns null, not [], when there are none.
Per network approveAgent signs hyperliquidChain, so a testnet approval is unknown on mainnet.
Actions
API wallet can sign L1 actions: orders, cancels, modifies, scheduleCancel, updateLeverage, vaultTransfer, borrowLend, agentSetAbstraction, HIP-3 perpDeploy, HIP-4 deploy and settle actions, and agentSendAsset, whose destination must equal the source
Account key only User-signed actions: usdSend, spotSend, sendAsset, withdraw3, usdClassTransfer, cDeposit, cWithdraw, tokenDelegate, approveAgent, approveBuilderFee, userSetAbstraction
Exception activateOutcomeDeployer is an L1 action but rejects API wallet signatures, even from an approved wallet
Unresolved Whether userOutcome split and merge accept an API wallet signature: two codebases sign them with one, a third refuses to

Account modes show the split on the wire:

Action Signer Values
userSetAbstraction account "disabled", "unifiedAccount", "portfolioMargin"
agentSetAbstraction API wallet "i", "u", "p", for the same three modes
userAbstraction (reads it back) unsigned info request "unifiedAccount", "portfolioMargin", "disabled", "default", "dexAbstraction"

In a multi-sig action only the leader’s nonce set is checked and updated; if the leader is an authorised user’s API wallet, that wallet’s nonce is used.

Parameter Value
Nonces kept per signer the 100 highest
Nonce window (T - 2 days, T + 1 day), T the block timestamp in ms
Recommended nonce current time in milliseconds
expiresAfter millisecond timestamp; an action rejected as stale costs 5x the address rate limit
API wallets per account, per the docs 1 unnamed, up to 3 named, plus 2 named per sub-account
API wallet name 1 to 16 characters, not counting the valid_until suffix
Longest approval 180 days ahead
Batch cadence suggested by the docs every 0.1 s

Give each bot process its own API wallet, never your funds key: a leaked API wallet can trade but not withdraw. Set a valid_until so a forgotten key expires.

For keeping API wallets safe, see API wallets and agents. For scheduleCancel, the dead man’s switch, see Orders.