Exchange action reference
Every action the /exchange endpoint accepts, grouped by job, with who must sign it, its key fields and where it is explained, including undocumented actions seen live.
Every write to HyperCore over the API is a JSON POST to /exchange carrying one action.
Signing schemes, status labels and responses
Section titled “Signing schemes, status labels and responses”Signed by is one of two schemes:
| Value | Scheme | Who can sign | Body |
|---|---|---|---|
| L1 | msgpack of the action, hashed with the nonce, vault and optional expiresAfter, wrapped in EIP-712 domain Exchange, chainId 1337, source "a" mainnet or "b" testnet |
the account’s key or an approved API wallet | {action, nonce, signature, vaultAddress?, expiresAfter?} |
| User | EIP-712 domain HyperliquidSignTransaction, primary type HyperliquidTransaction:<Name>, with hyperliquidChain and signatureChainId inside the action |
the master key only | {action, nonce, signature}; no vaultAddress, no expiresAfter |
- An action carrying
hyperliquidChainandsignatureChainIdis user-signed; everything else is L1. - Status: docs (official docs), observed (not in the docs, seen working on mainnet) or observed (SDK) (present in SDK code).
- Success is
{"status":"ok","response":{"type":..., "data":...}}; failure is{"status":"err","response":"<plain string>"}. Order and cancel errors come per item indata.statuses; strings are in the error catalogue.
Trading
Section titled “Trading”All L1, all signable by an API wallet.
type |
Key fields | Notes | Status | Page |
|---|---|---|---|---|
order |
orders: [{a, b, p, s, r, t, c?}], grouping, builder?: {b, f} |
t is {limit: {tif}} with Alo, Ioc, Gtc or FrontendMarket, or {trigger: {isMarket, triggerPx, tpsl}}. grouping is "na", "normalTpsl", "positionTpsl" or {"p": N} for priority. f in tenths of a bp |
docs | Orders |
cancel |
cancels: [{a, o}], f? |
f is the fast flag; omit it when false. Rejected if any cancel targets a trigger order with f: true |
docs | Orders |
cancelByCloid |
cancels: [{asset, cloid}], f? |
long key names, unlike cancel |
docs | Orders |
modify |
oid (number or cloid), order, a? |
a is always_place; omit it when false. Returns a new oid |
docs | Orders |
batchModify |
modifies: [{oid, order}], a? |
as modify, batched |
docs | Orders |
scheduleCancel |
time? |
dead man’s switch: at least 5 s ahead; omit time to clear; at most 10 triggers per day, reset at 00:00 UTC |
docs | Orders |
twapOrder |
twap: {a, b, s, r, m, t} |
m minutes, t randomise |
docs | TP/SL, TWAP and scale |
twapCancel |
a, t |
t is the TWAP id |
docs | TP/SL, TWAP and scale |
updateLeverage |
asset, isCross, leverage |
integer leverage | docs | Margin |
updateIsolatedMargin |
asset, isBuy, ntli |
ntli integer, 1e6 = 1 USD; isBuy has no effect yet |
docs | Margin |
topUpIsolatedOnlyMargin |
asset, leverage |
targets a leverage (float string) instead of an amount | docs | Margin |
noop |
none | marks the nonce as used; a way to kill an in-flight action | docs | Nonces, expiry and API wallets |
reserveRequestWeight |
weight, destination? |
buys address rate limit at 0.0005 USDC per request from the perp balance; destination skipped in the hash when unset |
docs | Rate limits |
gossipPriorityBid |
slotId, ip, maxGas |
bid for read priority; maxGas in HYPE wei (1e-8 HYPE) from the spot balance |
docs | Priority fees |
Transfers
Section titled “Transfers”type |
Signed by | Key fields | Notes | Status | Page |
|---|---|---|---|---|---|
usdSend |
User | destination, amount, time |
perp USDC to another address; time must equal the nonce |
docs | Transfers |
spotSend |
User | destination, token, amount, time |
token is NAME:0x... |
docs | Transfers |
withdraw3 |
User | destination, amount, time |
primary type HyperliquidTransaction:Withdraw; 1 USD fee; about 5 minutes per the exchange docs |
docs | Transfers |
usdClassTransfer |
User | amount, toPerp, nonce |
spot and perp USDC; append subaccount:0x... to amount for a sub-account |
docs | Transfers |
sendAsset |
User | destination, sourceDex, destinationDex, token, amount, fromSubAccount, nonce |
the general transfer: users, sub-accounts, dexes, spot, and the HyperEVM via a system address. "" is the main perp dex, "spot" is spot |
docs | Transfers |
agentSendAsset |
L1 | as sendAsset, without the chain fields |
agent-signable; destination must equal the source address |
docs | Transfers |
sendToEvmWithData |
User | token, amount, sourceDex, destinationRecipient, addressEncoding, destinationChainId, gasLimit, data, nonce |
calls coreReceiveWithData on the linked contract instead of transfer; destinationChainId is a CCTP domain id |
docs | Moving assets |
On unified and portfolio margin accounts, usdClassTransfer, spotSend and usdSend fail with Action disabled when unified account is active: use sendAsset.
Accounts, agents and abstraction
Section titled “Accounts, agents and abstraction”type |
Signed by | Key fields | Notes | Status | Page |
|---|---|---|---|---|---|
approveAgent |
User | agentAddress, agentName? |
a null name signs as "". Append valid_until <ms> to the name for an expiry, at most 180 days ahead. No revoke action exists |
docs | API wallets |
approveBuilderFee |
User | maxFeeRate, builder |
maxFeeRate is a percent string such as "0.001%"; the docs allow 10 active approvals per user (one SDK caps itself at 3); must be signed by the main wallet |
docs | Builder codes |
userSetAbstraction |
User | user, abstraction |
"disabled", "unifiedAccount" or "portfolioMargin"; user may be a sub-account |
docs | Account modes |
agentSetAbstraction |
L1 | abstraction |
"i" disabled, "u" unifiedAccount, "p" portfolioMargin |
docs | Account modes |
userDexAbstraction |
User | user, enabled |
deprecated; prefer userSetAbstraction |
docs | Account modes |
agentEnableDexAbstraction |
L1 | none | deprecated; only sets null to true |
docs | Account modes |
evmUserModify |
L1 | usingBigBlocks |
routes the account’s HyperEVM transactions to big blocks until unset | docs | Blocks, gas and RPC |
claimRewards |
L1 | none | claims accrued rewards; the docs give no fields. Builder fees are claimed through the referral reward claim | docs | Referrals |
createSubAccount |
L1 | name |
returns the new address as data |
observed | Sub-accounts |
subAccountTransfer |
L1 | subAccountUser, isDeposit, usd |
usd integer, 1e6 = 1 USD |
observed (SDK) | Sub-accounts |
subAccountSpotTransfer |
L1 | subAccountUser, isDeposit, token, amount |
observed (SDK) | Sub-accounts | |
subAccountModify |
L1 | subAccountUser, name |
renames a sub-account | observed (SDK) | Sub-accounts |
setReferrer |
L1 | code |
apply a referral code | observed (SDK) | Referrals |
registerReferrer |
L1 | code |
create a referral code | observed (SDK) | Referrals |
setDisplayName |
L1 | displayName |
empty string removes it | observed (SDK) | not documented |
spotUser |
L1 | toggleSpotDusting: {optOut} |
opt out of daily dust conversion | observed (SDK) | Spot markets |
Multi-sig
Section titled “Multi-sig”type |
Signed by | Key fields | Notes | Status | Page |
|---|---|---|---|---|---|
convertToMultiSigUser |
User | signers, nonce |
signers is a JSON string of {authorizedUsers, threshold}; the string "null" converts back to a normal user. At most 10 authorised users |
docs; fields observed (SDK) | Multi-sig accounts |
multiSig |
the leader, over SendMultiSig{hyperliquidChain, multiSigActionHash, nonce} |
signatureChainId, signatures, payload: {multiSigUser, outerSigner, action} |
wraps any action. Each authorised signer signs the inner action by its own scheme, with multiSigUser and outerSigner lowercase; one nonce for all signers; strip leading zeros from inner r and s |
docs; fields observed (SDK) | Multi-sig actions |
Measured on a testnet 2-of-2: the original key alone gets Multi-sig required, one signer alone Multi-sig threshold not met. Wrapped staking actions must use the typed-data path: cWithdraw signed as L1 is rejected with Invalid multi-sig inner signer.
Vaults
Section titled “Vaults”type |
Signed by | Key fields | Notes | Status | Page |
|---|---|---|---|---|---|
vaultTransfer |
L1 | vaultAddress, isDeposit, usd |
usd integer, 1e6 = 1 USD; agent-signable |
docs | Vaults |
createVault |
L1 | name, description, initialUsd, nonce |
returns the vault address as data; initialUsd 1e6 = 1 USD |
observed | Vaults |
vaultModify |
L1 | vaultAddress, allowDeposits, alwaysCloseOnWithdraw |
observed (SDK) | Vaults | |
vaultDistribute |
L1 | vaultAddress, usd |
usd 0 closes the vault |
observed (SDK) | Vaults |
hip3LiquidatorTransfer |
L1 | dex, ntl, isDeposit |
ntl in 1e-6 collateral tokens, a multiple of 1,000,000,000 (1,000 tokens); only principal is withdrawable |
docs | Operating a perp dex |
Staking
Section titled “Staking”type |
Signed by | Key fields | Notes | Status | Page |
|---|---|---|---|---|---|
cDeposit |
User | wei, nonce |
spot to staking balance; HYPE wei 1e8 | docs, measured | Staking |
cWithdraw |
User | wei, nonce |
staking to spot, through the 7-day unstaking queue | docs, measured | Staking |
tokenDelegate |
User | validator, isUndelegate, wei, nonce |
delegations lock for 1 day | docs | Validators and delegation |
linkStakingUser |
User | user, isFinalize, nonce |
the trading user initiates (false), the staking user finalises (true); permanent |
observed (SDK) | Fees |
primary type StakingLinkDisableTradingUser |
User | tradingUser, nonce |
irreversible: locks the trading user; funds move to the staking user after 1 year | docs | Fees |
Lending
Section titled “Lending”type |
Signed by | Key fields | Notes | Status | Page |
|---|---|---|---|---|---|
borrowLend |
L1 | operation, token, amount |
operation is "supply", "withdraw", "repay" or "borrow"; amount is a decimal string, or explicit null for the full balance. Refused in portfolio margin mode |
observed | Borrowing and lending |
userPortfolioMargin |
User | user, enabled |
observed (SDK) | Portfolio margin |
Outcome positions
Section titled “Outcome positions”type |
Signed by | Key fields | Notes | Status | Page |
|---|---|---|---|---|---|
userOutcome with splitOutcome |
L1 | outcome, amount |
X quote into X Yes plus X No | docs | Split, merge, negate |
userOutcome with mergeOutcome |
L1 | outcome, amount or null |
X Yes plus X No into X quote; null merges the maximum |
docs | Split, merge, negate |
userOutcome with mergeQuestion |
L1 | question, amount or null |
X Yes of every outcome in a question into X quote | docs | Split, merge, negate |
userOutcome with negateOutcome |
L1 | question, outcome, amount |
X No of one outcome into X Yes of every other, fallback included | docs | Split, merge, negate |
Amounts are decimal strings of whole contracts, no trailing zero. Whether an API wallet may sign splits and merges is open: two codebases do, one tool refuses.
Deploying markets
Section titled “Deploying markets”HIP-1 and HIP-2: spotDeploy
Section titled “HIP-1 and HIP-2: spotDeploy”All L1: {"type": "spotDeploy", "<variant>": {...}}. The first five variants run in order.
| Variant | Key fields | Notes | Status |
|---|---|---|---|
registerToken2 |
spec: {name, szDecimals, weiDecimals}, maxGas, fullName? |
the time-sensitive step: gas is charged here | docs |
userGenesis |
token, userAndWei, existingTokenAndWei, blacklistUsers? |
may be sent repeatedly | docs |
genesis |
token, maxSupply, noHyperliquidity? |
maxSupply is a checksum of all genesis calls |
docs |
registerSpot |
tokens: [base, quote] |
also deploys a pair between existing tokens, through its own auction | docs |
registerHyperliquidity |
spot, startPx, orderSz, nOrders, nSeededLevels? |
nOrders 0 when noHyperliquidity |
docs |
setDeployerTradingFeeShare |
token, share |
percent string, may only decrease | docs |
enableQuoteToken |
token |
irreversible, no gas | docs |
disableQuoteToken |
token |
docs | |
enableAlignedQuoteToken, disableAlignedQuoteToken |
token |
documented, but rejected on both networks when probed | docs, observed rejected |
setTokenAnnotation |
token, annotation: {category, description, displayName, keywords} |
at most once per day | docs |
setDeployerLabel |
label |
2 to 4 lowercase characters, once per deployer | docs |
requestEvmContract |
token, address, evmExtraWeiDecimals |
first half of linking; evmExtraWeiDecimals from -2 to 18 |
docs |
finalizeEvmContract (L1, not inside spotDeploy) completes the link: {token, input}, input one of {"create": {"nonce": n}}, "firstStorageSlot" or "customStorageSlot". See linking a token.
HIP-3: perpDeploy
Section titled “HIP-3: perpDeploy”All L1, agent-signable: {"type": "perpDeploy", "<variant>": {...}}. Sort every list of tuples before signing.
| Variant | Key fields | Notes | Status |
|---|---|---|---|
registerAsset2 |
maxGas?, assetRequest: {coin, szDecimals, oraclePx, marginTableId, marginMode}, dex, schema? |
with a non-null schema: {fullName, collateralToken, oracleUpdater?} it creates the dex and lists its first asset in one action; later assets send schema: null. marginMode is strictIsolated, noCross or normal. Nullable keys must be sent as explicit null |
docs |
registerAsset |
as above with onlyIsolated |
legacy | docs |
setOracle |
dex, oraclePxs, markPxs, externalPerpPxs |
at least 2.5 s between calls; expected every 3 s | docs |
setFundingMultipliers |
[[coin, multiplier]] |
0 to 10 | docs |
setFundingInterestRates |
[[coin, rate]] |
8-hour rate, -0.01 to 0.01 | docs |
setFundingClamps |
[[coin, clamp]] |
0 to 0.01, default 0.0003 | docs |
haltTrading |
coin, isHalted |
settles at mark and cancels orders; false resumes. New assets start halted |
docs, observed |
insertMarginTable |
dex, marginTable: {description, marginTiers} |
at most 3 tiers, leverage 1 to 50 | docs |
setMarginTableIds |
[[coin, id]] |
ids non-zero | docs |
setFeeRecipient |
dex, feeRecipient |
docs | |
setOpenInterestCaps |
[[coin, cap or null]] |
null removes a custom cap |
docs |
setSubDeployers |
dex, subDeployers: [{variant, user, allowed}] |
grants one variant to one user | docs |
setMarginModes |
[[coin, mode]] |
docs | |
setDeployerFees |
[[coin, {scale, growthMode}]] |
scale 0 to 3, or 0 up to 10 in growth mode; once per 30 days on mainnet |
docs |
setPerpAnnotation |
coin, category, description, displayName, keywords |
docs | |
disableDex |
the dex name | docs | |
star |
dex, operation |
allowlisted dexes; see the caution below | docs (testnet-only), observed (testnet) |
HIP-4: activateOutcomeDeployer and outcomeDeploy
Section titled “HIP-4: activateOutcomeDeployer and outcomeDeploy”| Action | Signed by | Key fields | Notes | Status |
|---|---|---|---|---|
activateOutcomeDeployer with activate |
L1, master key only | venueName |
irreversible; agents are rejected even when approved. Browser wallets refuse the chainId 1337 domain | docs, measured |
activateOutcomeDeployer with deactivate: null |
L1, master key only | none | permanent; needs 183 days elapsed and no active outcomes | docs |
outcomeDeploy |
L1, agent-signable | venue, operation: {<variant>} |
keys in exactly this order | docs |
outcomeDeploy variants:
| Variant | Key fields | Notes |
|---|---|---|
registerStandaloneOutcomeFromTemplate |
id, keywordToValue, deployerFeeScale |
keywordToValue is a sorted list of [keyword, value] pairs, never an object |
registerQuestionFromTemplate |
questionTemplateInstance, namedOutcomeTemplateInstances |
the fee scale sits on the question instance; a fallback outcome is created automatically |
registerAndAssociateNamedOutcomeFromTemplate |
question, namedOutcomeTemplateInstance |
inherits the question’s fee scale; fallback Yes holders receive the new Yes |
settleOutcome |
outcome, settleFraction, details, nameAndDescription, sideNames |
details must be ""; names must match outcomeMeta exactly |
settleQuestion2 |
question, outcomeSettlements, nameAndDescription |
exactly one outcome at "1"; replaces settleQuestion |
setSubDeployers |
[{variant, user, allowed}] |
the settleQuestion grant authorises settleQuestion2 |
See outcome deployer, templates, settling.
Validators and protocol roles
Section titled “Validators and protocol roles”type |
Signed by | Key fields | Notes | Status |
|---|---|---|---|---|
validatorL1Stream |
L1 | riskFreeRate |
validator vote on the risk-free rate for aligned quote assets, for example "0.04" |
docs |
authorizeAqav2Role |
L1 | token, role |
role is "technical" or "treasury" |
docs |
CSignerAction |
L1 | jailSelf or unjailSelf |
a validator signer jails or unjails itself | observed (SDK) |
CValidatorAction |
L1 | register, changeProfile and other variants |
validator profile management | observed (SDK) |
Undocumented surface
Section titled “Undocumented surface”About 18 undocumented exchange actions and 19 info requests work on mainnet, and the two networks parse different shapes. The server parses before checking the signature, so a dummy signature probes a shape: HTTP 422 Failed to deserialize means wrong; Unable to recover signer, does not exist or Must deposit before performing actions means it parsed. See debugging.
For the two signing schemes byte by byte, see Signing from first principles; for what each rejection means, the Error catalogue. The subset a contract can send is in the CoreWriter action reference.