Hyperliquid API wallets (agent keys), explained

Hyperliquid has no exchange-style API keys. You approve a separate signing key instead, and it can trade but not take your money out.

Updated Fact-checked November 4, 2026 9 sources
Short answer

A Hyperliquid API wallet, also called an agent wallet, is a separate key your main wallet approves to sign trading actions for it. It can place, modify and cancel orders, but the official SDK says it has no permission to withdraw or transfer funds, and builder-fee approvals must come from the main wallet. An account can have 1 unnamed and up to 3 named API wallets, plus 2 more named ones per sub-account. A named one can expire after at most 180 days.

On a centralized exchange, a bot gets an API key and secret with permission tick-boxes. Hyperliquid is a blockchain, so every action is a signed message, and the thing that signs is a wallet key. To keep your main wallet’s key off a server, Hyperliquid lets the main wallet approve another key to sign for it. That second key is an API wallet. The docs also call it an agent wallet (nonces and API wallets).

What an API wallet can and can’t do

Hyperliquid signs actions with two different schemes (signing). Trading actions such as orders and cancels are “L1 actions”, and an approved API wallet can sign them. Actions that send money to another address or grant permissions are “user-signed” and need the main wallet, apart from a few variants the docs mark “(agent)”.

An API wallet canAn API wallet can’t
Place, modify and cancel orders, and set a scheduled cancel (dead man’s switch)Withdraw to another chain
Change leverage and isolated marginSend USDC or tokens to another address
Trade for the master account or any of its sub-accounts (via vaultAddress)Approve a builder fee: “must be signed by the user’s main wallet, not an agent/API wallet” (builder codes)
Move collateral between the account’s own perp dexes and spot (agentSendAsset; the destination must be the same account)Approve another API wallet (the SDK refuses: “You should not create an agent using an agent”)
Deposit into staking (the “(agent)” variant)

The withdraw rule comes straight from the official SDK’s agent example: the agent “does not have permission to transfer or withdraw funds” (basic_agent.py). In the same SDK, orders, cancels, leverage changes and the scheduled cancel are all signed with the L1-action scheme an agent uses (exchange.py). agentSendAsset and the staking deposit are marked as agent-signable in the exchange endpoint docs.

"Can't withdraw" does not mean "safe to leak". Anyone holding an API wallet key can open and close positions on your account. At high leverage or in a thin market, that can lose all the account's margin. Treat the agent key like a password. Keep it on the server that trades, and revoke it when that server is retired.

How to create one

  1. In the official app. The app at app.hyperliquid.xyz can create a named API wallet and asks your main wallet to sign the approval. The SDK’s own example points to this option (“you can also create a named agent using the frontend”). Save the private key it shows you somewhere safe.
  2. With the official Python SDK. Exchange.approve_agent(name) generates a random key locally, signs an approveAgent action with your main wallet and returns the new key (exchange.py).

Illustrative only, not run by us. The shape of the approval with the official SDK, on testnet. Run the approval once, from a machine you trust, with the main key. Then deploy only the agent key.

# ILLUSTRATIVE ONLY: testnet. Main key from the environment.
import os
import eth_account
from hyperliquid.exchange import Exchange
from hyperliquid.utils import constants

main = eth_account.Account.from_key(os.environ["HL_MAIN_KEY"])
ex = Exchange(main, constants.TESTNET_API_URL)

result, agent_key = ex.approve_agent("my-bot")   # named agent
print(result)          # {'status': 'ok', ...} on success
# Store agent_key in your server's secret store, not in code.

# Later, on the server, sign as the agent for the main account:
agent = eth_account.Account.from_key(agent_key)
bot = Exchange(agent, constants.TESTNET_API_URL,
               account_address=main.address)

The raw approveAgent action carries agentAddress, an optional agentName and a nonce. Append valid_until <timestamp> to the name to make it expire, at most 180 days out (exchange endpoint).

How many you can have

The approveAgent docs allow 1 unnamed API wallet and up to 3 named ones per account, plus 2 more named ones per sub-account. The sub-accounts page puts it as “starts at 3 for all master accounts and increases by 2 per sub-account” (sub-accounts), counting the named ones. Approving a new unnamed wallet replaces the old unnamed one. Approving a named wallet with a name already in use replaces that one.

Reading data: always use the account address

An API wallet holds no funds and has no positions; it only signs. If you query clearinghouseState, openOrders or a user WebSocket feed with the agent’s address, you get an empty result. The docs call this “a common pitfall” (info endpoint). Pass the master account or sub-account address instead.

To check what an address is, send {"type":"userRole","user":"0x…"}. It answers missing, user, agent (with the owner’s address in data.user), vault or subAccount. For HLP Strategy A on 4 November 2026 it returned {"role":"vault"}. This request costs 60 rate-limit weight, so don’t poll it.

Nonces: why bots need one key per process

Hyperliquid doesn’t use Ethereum’s “next nonce = previous + 1”. It keeps the 100 highest nonces per signer. A new action’s nonce must be higher than the smallest of those 100, must not have been used before, and must fall between 2 days before and 1 day after the block’s time (docs). Everyone uses the current time in milliseconds.

Nonces are tracked per signer, which is the API wallet when an agent signs. So:

  • Use one API wallet per trading process. Two processes sharing a key will collide.
  • Use separate API wallets for separate sub-accounts. One agent signing for several sub-accounts shares a single nonce set across all of them.
  • Inside a process, batch orders and cancels about every 0.1 seconds and take nonces from an atomic counter. The docs suggest batching ALO (post-only) orders apart from IOC and GTC, because validators prioritize ALO-only batches.

Pruning, and why you never reuse an agent address

An API wallet and its nonce history can be pruned when it is replaced by a new approval, when it expires, or when the account that approved it has no funds left. Hyperliquid’s docs warn that once the nonce set is pruned, previously signed actions can be replayed. So never re-approve an old agent address: generate a fresh key each time (docs).

Fees and referrals still follow the account

An API wallet trades for the master account, so the master account’s fee tier, HYPE staking discount and referral discount apply. Hyperliquid’s referral discount (4% off fees for the first $25M of volume) does not apply to sub-accounts or vaults, because they count as separate accounts (referrals). Check your exact costs with the fee calculator.

Hyperliquid’s terms restrict users in the United States, Ontario and other places, whether they use the app or the API (details).

Questions people ask

How do I get a Hyperliquid API key?

Hyperliquid has no API key and secret. You generate a new wallet key and approve it from your main wallet with the approveAgent action, either in the official app or with the SDK's approve_agent(). Your bot then signs with that key. Reading data needs no key at all.

Can a Hyperliquid API wallet withdraw funds?

No. The official Python SDK's agent example says the agent "does not have permission to transfer or withdraw funds". Withdrawals are user-signed actions that need the main wallet. An agent key can still trade, so a leaked one can lose the account's margin through bad trades.

How many API wallets can a Hyperliquid account have?

Per the approveAgent docs: 1 unnamed and up to 3 named API wallets per account, plus 2 more named ones per sub-account. Approving a new unnamed wallet replaces the old unnamed one.

Why does my Hyperliquid API return an empty account?

You are probably querying the API wallet's address. API wallets hold nothing; they only sign. Pass the master account or sub-account address to clearinghouseState, openOrders and the user WebSocket feeds.

Sources

  1. Hyperliquid Docs — Nonces and API wallets
  2. Hyperliquid Docs — Exchange endpoint (approveAgent, agent-signed actions)
  3. Hyperliquid Docs — Builder codes (approval must be signed by the main wallet)
  4. Hyperliquid Docs — Sub-accounts (API wallet allowance)
  5. Hyperliquid Docs — Signing (two signing schemes)
  6. Hyperliquid Docs — Info endpoint (userRole, user address pitfall)
  7. Hyperliquid Docs — Referrals (discount does not apply to sub-accounts or vaults)
  8. hyperliquid-python-sdk — examples/basic_agent.py
  9. hyperliquid-python-sdk — exchange.py (approve_agent, signing helpers)