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.

Your first request

Foundation

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

Start with reads: they’re the safe place to learn the info endpoint. They pay no fee and change nothing. They also give you what every order depends on: a market’s position in meta, its szDecimals, and its book’s price levels.

Terminal window
curl -s -X POST https://api.hyperliquid.xyz/info \
-H 'Content-Type: application/json' \
-d '{"type":"meta"}'

Abridged from the docs’ example; live values differ, so read them from the API:

{
"universe": [
{ "name": "BTC", "szDecimals": 5, "maxLeverage": 50 },
{ "name": "ETH", "szDecimals": 4, "maxLeverage": 50 },
{ "name": "HPOS", "szDecimals": 0, "maxLeverage": 3, "onlyIsolated": true }
]
}
Field Meaning
position in universe The asset id orders use. BTC, first in the list, is asset 0 on mainnet.
name The coin string that info requests and WebSocket subscriptions use.
szDecimals Decimals a size may have; also caps price decimals, see precision.
maxLeverage The leverage ceiling. Some entries also carry isDelisted, onlyIsolated or marginMode.

The full response also carries marginTables. {"type":"metaAndAssetCtxs"} adds a second array, in the same order, with each market’s markPx, oraclePx, funding, openInterest, dayNtlVlm and more. Add "dex":"<name>" to either request to list a builder-deployed HIP-3 perp dex instead of the first one.

Terminal window
curl -s -X POST https://api.hyperliquid.xyz/info \
-H 'Content-Type: application/json' \
-d '{"type":"l2Book","coin":"BTC"}'

The docs’ example response:

{
"coin": "BTC",
"time": 1754450974231,
"levels": [
[
{ "px": "113377.0", "sz": "7.6699", "n": 17 },
{ "px": "113376.0", "sz": "4.13714", "n": 8 }
],
[
{ "px": "113397.0", "sz": "0.11543", "n": 3 }
]
]
}

levels holds bids, then asks, each from the best price:

Field Meaning
px Price of the level
sz Total size resting there, in units of the coin
n Number of orders at the level

nSigFigs (2, 3, 4 or 5) aggregates levels to fewer significant figures; mantissa (1, 2 or 5) is allowed only with nSigFigs of 5.

Other coin strings: @107 for HYPE spot on mainnet, dex:COIN for HIP-3, #<number> for an outcome side.

Terminal window
ADDR=0x0000000000000000000000000000000000000000 # replace with the account to inspect
curl -s -X POST https://api.hyperliquid.xyz/info \
-H 'Content-Type: application/json' \
-d "{\"type\":\"clearinghouseState\",\"user\":\"$ADDR\"}"

The docs’ example, with one isolated ETH position:

{
"assetPositions": [
{
"position": {
"coin": "ETH",
"szi": "0.0335",
"entryPx": "2986.3",
"leverage": { "type": "isolated", "value": 20, "rawUsd": "-95.059824" },
"liquidationPx": "2866.26936529",
"marginUsed": "4.967826",
"positionValue": "100.02765",
"unrealizedPnl": "-0.0134"
},
"type": "oneWay"
}
],
"marginSummary": {
"accountValue": "13109.482328",
"totalMarginUsed": "4.967826",
"totalNtlPos": "100.02765",
"totalRawUsd": "13009.454678"
},
"withdrawable": "13104.514502",
"time": 1708622398623
}

The docs’ example also carries cumFunding, maxLeverage, returnOnEquity, crossMarginSummary and crossMaintenanceMarginUsed. The notation:

Field Meaning
szi Signed size: positive long, negative short
Ntl Notional: price times size, in USD
Px A price
withdrawable What can leave the account now
time Snapshot time, in milliseconds
const INFO = "https://api.hyperliquid.xyz/info";
async function info<T>(body: object): Promise<T> {
const res = await fetch(INFO, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const text = await res.text(); // a 422 arrives as plain text, not JSON
if (!res.ok) throw new Error(`${res.status}: ${text}`);
return JSON.parse(text) as T;
}
type Meta = { universe: { name: string; szDecimals: number; maxLeverage: number }[] };
type Level = { px: string; sz: string; n: number };
type Book = { coin: string; time: number; levels: [Level[], Level[]] };
type Account = { withdrawable: string; assetPositions: { position: { coin: string; szi: string } }[] };
const meta = await info<Meta>({ type: "meta" });
const asset = meta.universe.findIndex((m) => m.name === "BTC"); // the asset id orders use
console.log(asset, meta.universe[asset].szDecimals);
const book = await info<Book>({ type: "l2Book", coin: "BTC" });
const [bids, asks] = book.levels;
console.log(bids[0].px, asks[0].px); // best bid and best ask, as strings
const account = await info<Account>({
type: "clearinghouseState",
user: "0x0000000000000000000000000000000000000000", // the account to inspect
});
console.log(account.withdrawable, account.assetPositions.length);

Every number is a string: keep it one or parse it into a decimal type, never a float (see precision).

Request Rate-limit weight Notes
l2Book 2 At most 20 levels per side
clearinghouseState 2 One perp dex per request; dex defaults to the first
meta 20 Changes rarely: cache it
metaAndAssetCtxs 20 Live contexts; for frequent updates use the WebSocket

One IP’s weights share a budget of 1200 per minute. Time-range requests return at most 500 elements; page by passing the last timestamp returned as the next startTime.

Put your address in step 3 to read your account with no key or login; HyperCore positions, orders and fills are public for any address. Read liquidationPx, the protocol’s own figure, rather than recomputing it.

When a read comes back empty or unexpected

Section titled “When a read comes back empty or unexpected”
  • An API wallet’s address returns an empty result: it only signs for the account.
  • Under unified account or portfolio margin, the spot and perps trading balance is in spotClearinghouseState, not clearinghouseState (account modes).
  • Outcome positions are spot balances: read spotClearinghouseState.
  • App names can differ: BTC/USDC in the app is UBTC/USDC on HyperCore (the docs’ example).
  • An unparseable body returns HTTP 422 as plain text beginning Failed to deserialize; hence the helper reads text first.
  • Testnet is https://api.hyperliquid-testnet.xyz, with different asset ids, token indices and dex lists.

For every coin string and asset id, see Asset ids and naming. For the same data as a stream, see WebSocket.