Set Up Copying
Choose an exposure level and traders (we suggest one for your level), then sign the WakeTrades trading key (Hyperliquid approveAgent, EIP-712) and accept the Terms. Copying and the 14-day free trial start as soon as an alert channel is linked.
1. Choose an Exposure Level, Then Traders
Which level for your balance? An account needs a minimum balance to copy, because Hyperliquid has a minimum order size: 1,100 USDC at Prudent, 550 at Balanced, 300 at Risky. Below it, copies under the minimum open at 11 USDC, larger than the level's share. GET /api/v1/levels with your session token (or ?equity= in USDC) returns recommendedLevel: the most prudent level whose minimum your balance covers; under every minimum, risque with belowAllMinimums: true, since Risky stays closest to your leaders' proportions (Recommended Level). It is advice: any level can be saved.
PUT /api/v1/settings. During sign-up, send the level first, alone:
{ "level": "equilibre", "lang": "en" }
The account stays in setup and the answer adds "next": "GET /leaders/suggested". No trader in mind? GET /api/v1/leaders/suggested?level=equilibre suggests a trader of our latest Monthly Report for that level (advanced uses risque's list), with figures from the report over the last 90 days. It is the most active of #3 to #5 on the level's list (most positions opened in the 30 days before the report; never #1 or #2), skipping any trader already suggested for a more prudent level; the exact rule is in Suggested Traders. One suggestion per level, for every account; at Risky, where 2 leaders are strongly recommended, choose the second one yourself (the full lists are in the monthly report with a paid plan):
{ "level": "equilibre", "list": "equilibre", "rank": 5, "address": "0x…", "month": "2026-10",
"stats": { "winRatePct": 58, "profitFactor": 1.6, "tradesPerMonth": 24, "medianHoldHours": 9.5 }, "note": "…",
"liveCheck": "GET /api/v1/leader/0x…/positions", "suggestions": [ { "rank": 5, "address": "0x…", "…": "…" } ] }
The report's figures are month-end: before choosing, read the trader's open positions now with liveCheck (GET /api/v1/leader/{address}/positions): a trader can hold a large losing position today. Positions a leader already holds when you start copying are never copied, only their new trades. The rest of the list comes with a plan. 404 no_suggestion means no report is published yet: choose a trader yourself by address and check it with GET /api/v1/leader/{address}. Then send the leaders (the suggested address or your own choice); the next step needs at least one:
{ "leaders": ["0xLEADER…"], "level": "equilibre", "lang": "en" }
leaders: Hyperliquid addresses to copy, in order of priority. At most 3 (5 atadvanced): more gives400 too_many_leaders. A list already longer, after a move to a level with a lower maximum, is kept: the first ones are followed, the extra ones wait. Atrisque, at least 2 are strongly recommended (one leader is allowed).level:prudent,equilibre(Balanced),risque(Risky) oradvanced(every plan, free trial included). See The Four Exposure Levels;GET /api/v1/levelsgives the same rules as JSON.riskAck: trueis required to move to Risky with more than 10,000 USDC on the account (409 risk_ack_requiredotherwise).- Every leader must have a Hyperliquid account (
unknown_leader).
Settings, leaders included, can be changed the same way at any time.
Balance. Each leader is copied at their position × your balance ÷ theirs × the level's size ÷ 3. A copy under Hyperliquid's minimum order opens at 11 USDC instead of being skipped (skipped only when the coin's smallest size step would make it more than 22 USDC), so on a small balance copies are larger than the level's share. Plan for at least 1,100 USDC at Prudent, 550 at Balanced and 300 at Risky (why); GET /api/v1/preview gives tooSmallPct for your balance and first leader, level by level. When at least 90% of a followed leader's trades would open at the floor, the answer (here and in step 4) adds a non-blocking warning with code: "copies_too_small" (details).
Advanced Settings
At level advanced, PUT /api/v1/advanced changes the settings, starting from Risky's. Fields you leave out keep their value.
{ "sizePct": 50, "maxExposureX": 10, "maxOpenPositions": null, "alertsPct": [15, 25], "autoStopPct": 20, "followAdds": true, "copyLeaderTpSl": true }
sizePct: size of your copies, in % of the leaders' size (5 to 300; 100 = Risky).maxExposureX: total exposure cap, in times your balance, ornullfor no cap.maxOpenPositions: maximum of open copies (integer), ornullfor no limit.PUT /api/v1/max-positionssets the same value.alertsPct: drawdown alerts from the account's highest balance,[heads-up, alert].autoStopPct: automatic stop: at this drawdown, every copy closes and copying pauses.nullfor none.followAdds: copy your leaders' adds.copyLeaderTpSl: copy their take profit and stop loss.markets,minMarketLeverage,maxLeverage,sides,copyStopPct,dailyLossPct: which markets and sides new copies open on, a leverage cap, your own stop on each copy, and a daily loss limit. All off by default: see Advanced Settings.tp1Pct/tp1ClosePct,tp2Pct/tp2ClosePct,slPct/slClosePct,breakEvenAfterTp1: your own take profits and stop loss on each new copy, as a PnL % of the copy (leverage included), each closing the share you choose; after a partial close the copy keeps following the leader on what is left. All off by default.
Advanced is open with every plan, free trial included. PUT /api/v1/max-positions at another level answers 400 advanced_only.
2. Get the Trading Key's Address
POST /api/v1/agent returns { "agentAddress", "agentName": "WakeTrades", "hyperliquidChain": "Mainnet" }. WakeTrades generates this key on its server; the agent never sees its private key and only authorizes its address. Copy hyperliquidChain from this answer into the action and the typed data: "Mainnet" on waketrades.com, "Testnet" on a test environment.
3. Sign the Approval (EIP-712)
The agent signs Hyperliquid's approveAgent action with its own wallet. Build the action:
{
"type": "approveAgent",
"hyperliquidChain": "Mainnet",
"signatureChainId": "0xa4b1",
"agentAddress": "<agentAddress>",
"agentName": "WakeTrades valid_until <now + 179 days, in ms>",
"nonce": <now, in ms>
}
and sign this typed data (same values):
{
"domain": { "name": "HyperliquidSignTransaction", "version": "1", "chainId": 42161, "verifyingContract": "0x0000000000000000000000000000000000000000" },
"primaryType": "HyperliquidTransaction:ApproveAgent",
"types": {
"HyperliquidTransaction:ApproveAgent": [
{ "name": "hyperliquidChain", "type": "string" },
{ "name": "agentAddress", "type": "address" },
{ "name": "agentName", "type": "string" },
{ "name": "nonce", "type": "uint64" }
]
},
"message": { "hyperliquidChain": "Mainnet", "agentAddress": "<agentAddress>", "agentName": "WakeTrades valid_until …", "nonce": … }
}
signatureChainId is the chain the wallet signs on, and the typed data's domain.chainId must be the same number: Hyperliquid rebuilds the domain from signatureChainId.
| Network | hyperliquidChain |
signatureChainId |
domain.chainId |
|---|---|---|---|
| Mainnet (waketrades.com) | "Mainnet" |
"0xa4b1" (Arbitrum One) |
42161 |
| Testnet | "Testnet" |
"0x66eee" (Arbitrum Sepolia), or "0xa4b1" |
421614, or 42161 |
Any chain id works if both values match; the same rule applies to payments (GET /pay/prepare?chainId=). Then send it:
POST /api/v1/agent/approve with { "action": { … }, "signature": { "r": "0x…", "s": "0x…", "v": 27 } }
WakeTrades checks that the action authorizes its own key, under its name, on the right network and with a recent nonce, then relays it to Hyperliquid, which checks the signature.
Python (eth-account):
signed = Account.sign_typed_data(PRIVATE_KEY, full_message=typed_data) # typed_data as above, with an EIP712Domain type
signature = {"r": f"0x{signed.r:064x}", "s": f"0x{signed.s:064x}", "v": signed.v} # 64 hex digits each: hex() drops leading zeros
JavaScript (viem):
import { parseSignature } from "viem";
const sig = parseSignature(await account.signTypedData({ domain, types, primaryType, message }));
const signature = { r: sig.r, s: sig.s, v: Number(sig.v) };
No wallet library: signTypedData(typedData) from the short @noble/curves example returns { r, s, v } directly.
4. Accept the Terms and Confirm the Key
POST /api/v1/agent/verify with { "tosAccepted": true }.
- By sending
tosAccepted: true, the agent accepts the Terms of use on behalf of the wallet's owner. 409 agent_not_registered_yet: Hyperliquid hasn't registered the key yet. Retry after 10 seconds.- If a webhook is already linked, copying and the 14-day free trial start now (
"state": "trial"). Otherwise the state isawaiting_telegram: link a webhook next (Webhooks) and the trial starts then. A new wallet whose webhook host already had a free trial gets none: the answer carries"noTrial": "webhook_host_used"and the state istrial_expired(pay to copy, Pay With USDC). - The answer can include a non-blocking
warning(copies_too_small), as in step 1.
5. Switch to a Unified Account
POST /api/v1/account/unified with the body {}, right after step 4.
- At Prudent, Balanced and Risky, new copies open only on a Hyperliquid Unified Account with no position opened outside WakeTrades. Until then, each new trade of your leaders is skipped (
skip:not_unified, ormanual_positionsfor positions opened outside WakeTrades) and anaccount_blockedevent is sent at most once a day. At Advanced, a standard account copies, except the xyz markets (stocks, indices, commodities), which always need a Unified Account. - WakeTrades switches the account with its trading key: no wallet signature. The answer is
{ "mode": "unifiedAccount", "unified": true }, and anaccount_unifiedevent is sent. An account already unified is left as is. - On Hyperliquid, your USDC moves from Perps to Spot, where it backs every market; your balance doesn't change.
GET /api/v1/meshows the result:unified: true,status.accountMode: "unifiedAccount". While the account isn't unified,status.noticesholds"standard_account".409 key_required: the trading key isn't approved yet (step 4).502 switch_failed: Hyperliquid refused; switch it yourself (Switch to a Unified Account).
6. Choose the Order Mode
status.orderMode in GET /api/v1/me says how copies enter. New accounts start in limit: a post-only order at the leader's entry price. Unfilled after 1 minute, it is cancelled and the copy opens at market, unless the price is more than 1% from the leader's entry; if the leader exits first, nothing is copied and a limit_missed event is sent. To enter at market right away (skipped only beyond 1% from the leader's entry):
PUT /api/v1/order-mode with { "mode": "market" } (Order Mode)
7. Read Back: Can Copies Open?
GET /api/v1/me → copiesOnHold. { "held": false, "reasons": [], "coins": [] } means your leaders' next trades will be copied. Otherwise each reason says what to do: not_unified (step 5), manual_positions (close the positions listed in coins), paused, trial_expired, plan_expired, key_invalid, no_leaders, no_margin, not_activated, platform_paused (all reasons).
If Hyperliquid Refuses the Key
502 hyperliquid_refused with a reason:
| Reason | What to do |
|---|---|
no_deposit |
The Hyperliquid account has no deposit yet. Deposit USDC, then sign again. |
too_many_agents |
The account already has 3 named API wallets. Revoke one on Hyperliquid, then sign again. |
other |
See detail (Hyperliquid's own message). |
Renew the Key
The key is valid 180 days. A key_expiring event (with days left) arrives about once a week during the last 30 days. Repeat steps 2 to 4: the old key keeps trading until Hyperliquid registers the new one.