API servers and how state reaches you
API servers follow a node, keep a local copy of HyperCore state, answer reads from it, and reply to a transaction only once it executes in a committed block.
Every REST or WebSocket call you make goes to an API server. How it answers tells you what a reply, a timeout or a read really means.
Writes are answered after commit
Section titled “Writes are answered after commit”A signed /exchange action goes to the API server, then its node, which gossips it into HyperBFT. The reply comes after commit, so resting or filled describes executed state, not a receipt.
Latency is the hop to the API server, mempool inclusion and commit (figures below). Ordering is far less noisy: in the docs’ experiments, sends under 10 ms apart landed in a predictable order on chain.
What this means for you. A timeout, 5xx or 429 on an action is an unknown outcome, not a failure: check by client order id before resending.
Reads come from the server’s copy
Section titled “Reads come from the server’s copy”/info and WebSocket answer from the API server’s copy, as current as its node’s last update. They return current state (balances, books, positions, open orders), not history. Several responses are bounded (below); no public stream carries every fill. History lives in node outputs and archives (historical data).
Say your bot polls l2Book. Each call weighs 2 against 1200 per minute per IP, so 600 polls a minute, 10 a second, use the whole budget. An order batch of 80 weighs 1 + floor(80 / 40), which is 3.
Use WebSocket for anything you would poll. One measured bot blocked its own order placement because order preparation hit /info first; moving the book to WebSocket cut it to about 0.15 requests per second.
The servers run in Tokyo
Section titled “The servers run in Tokyo”They run on AWS in Tokyo, as established by one production trading setup. The docs’ latency figures assume a co-located client but name no region. Distance to Tokyo is the latency cost you control most directly.
Your own node is faster for reads
Section titled “Your own node is faster for reads”The docs recommend a non-validating node against a reliable peer: its outputs are faster and more granular than the API, enough to build a book locally. Streaming transactions before they are included in client blocks is faster still, but without execution results (running a node, optimising latency).
The numbers
Section titled “The numbers”| Limit, per IP address | Value |
|---|---|
| REST weight | 1200 per minute |
exchange request weight |
1 + floor(batch_length / 40) |
info weight: l2Book, allMids, clearinghouseState, orderStatus, spotClearinghouseState, exchangeStatus |
2 |
info weight: userRole |
60 |
info weight: other documented requests |
20 |
| WebSocket connections | 10 |
| New WebSocket connections | 30 per minute |
| WebSocket subscriptions | 1000 |
| Messages sent over WebSocket | 2000 per minute |
| In-flight WebSocket posts | 100 |
Address-based limits and buying more capacity: rate limits.
| Latency or bound | Value |
|---|---|
| Commit | usually 2 blocks, in pipelined HyperBFT |
| Order, co-located client (docs) | median 0.2 s, 99th percentile 0.9 s |
| Cancel or post-only order (docs) | about 380 ms |
| Tokyo to Ireland hedge (measured) | 350 to 500 ms: about 110 ms network transit plus four serialised round trips |
| Streaming from a node before client-block inclusion | saves 70 to 150 ms |
| Suggested node hardware | at least 32 logical cores, 128 GB RAM, 500 MB/s disk throughput |
userFills, historicalOrders |
at most the 2000 most recent entries; paginate by time |
outcomeMeta |
unsettled outcomes only; a settled one drops within about a minute |
Explorer userDetails |
last 300 actions, with an error field, including actions sent from the HyperEVM |
Handling limits and dropped sockets
Section titled “Handling limits and dropped sockets”- A 429 carries no
Retry-Afterheader; back off with jitter. - Per the docs, API servers may drop WebSocket clients without warning. Missed data arrives in the reconnect snapshot; WebSocket posts are not replayed.
- A WebSocket post can fail with “too many pending post requests”.
- An unsupported subscription gets an
errorchannel frame, not silence. ThewebData2subscription is dead; thewebData2info request still works. - Set
TCP_NODELAYon the socket.
The API, not the docs, decides what exists
Section titled “The API, not the docs, decides what exists”On mainnet 18 exchange actions and 19 info requests work undocumented, and some documented ones are rejected. The action is parsed before the signature is checked, so a dummy signature separates a wrong shape (HTTP 422 Failed to deserialize) from a valid one (Unable to recover signer, does not exist or Must deposit before performing actions). A 422 can be plain text: read the body as text before parsing JSON.
For subscriptions, posts and heartbeats, see WebSocket. For what distance costs, see Latency, priority and infrastructure.