Orders: place, modify, cancel, batch, dead man's switch
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.
Placing orders
Section titled “Placing orders”The order action
Section titled “The order action”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.
Time in force
Section titled “Time in force”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.
Triggers
Section titled “Triggers”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
Section titled “Grouping”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.
Builder field
Section titled “Builder field”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).
Statuses in the response
Section titled “Statuses in the response”"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).
Batches
Section titled “Batches”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.
Changing and cancelling orders
Section titled “Changing and cancelling orders”Modify and batchModify
Section titled “Modify and batchModify”{"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 |
Cancel and cancelByCloid
Section titled “Cancel and cancelByCloid”{"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.
Dead man’s switch
Section titled “Dead man’s switch”{"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.
Slicing a large order with TWAP
Section titled “Slicing a large order with TWAP”{"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)"}} |
The numbers
Section titled “The numbers”| 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 |
What the app’s order types send
Section titled “What the app’s order types send”| 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 |
Running orders from a bot
Section titled “Running orders from a bot”- Reconcile by cloid: oids change on modify and are unknown after a timeout, and
orderStatustakes a cloid. - While quoting, arm
scheduleCanceland cancel all on shutdown, or restingAloorders fill unhedged. - Set
pon 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
noopwith its nonce; the docs rate this abovecancel.
Rejections to design around
Section titled “Rejections to design around”f: falseon a cancel ora: falseon 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
expiresAfterrejection costs 5 times the usual address budget. - CoreWriter’s limit order (action 1) knows only
Alo,GtcandIoc: noFrontendMarketfrom the HyperEVM. - On outcome markets
Iocfills 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.