Skip to navigation

Deposits & Withdrawals

Funding configuration

GET /config

The single source of truth for deposit destinations and withdrawal thresholds.

{
"data": {
"deposit": {
"hypercore": { "address": "0x…", "min_amount": "1" },
"arbitrum": { "min_amount": "5" }
},
"withdrawal": { "min_amount": "10", "new_wallet_fee": "1" },
"trader_share": 1
},
"success": true,
"timestamp": 1787067314951
}
FieldMeaning
deposit.hypercore.addressThe address you deposit to via a Hyperliquid spot transfer. The sender’s wallet decides which account gets credited
deposit.*.min_amountBelow this, a transfer is detected but not credited
withdrawal.min_amountSmallest withdrawal the API will accept
withdrawal.new_wallet_feeHyperliquid’s one-time activation fee, charged only on the first-ever credit to a destination with no HyperCore history
trader_shareThe fee-savings split — a fraction in 0..1, 1 today

Read the deposit address from /config at runtime — never hardcode it. It is elided from the sample above for that reason.

Track deposits

GET /account/{account_id}/deposit-history

Takes your account_id; a plain wallet address is rejected here. Accepts limit, offset, from, and to.

Returns data: { account, deposits: [] }, newest first. Poll it to follow a transfer you just sent through to credit.

FieldMeaning
tx_hashThe transfer that was detected
amountAmount transferred
sourcesend · spotTransfer · internalTransfer
statusDETECTED → CONFIRMED, or BELOW_MIN if it was under the minimum
detected_at / credited_atWhen it was seen, and when it hit your balance

Request a withdrawal

POST /account/withdraw

Withdrawals are signed by your main wallet, never the trading key:

Withdraw(address user, address destination, uint256 amount, string hyperflowEnvironment, uint256 nonce)

Two fields need care when signing:

  • destination — your own wallet on the default HyperCore rail, or the EVM recipient on the Arbitrum rail.
  • amount — USDC base units, 6 decimals. 25 USDC signs as 25000000, while the request body carries the same value as the decimal string "25".

Request body

{
"account_id": "0x…",
"amount": "25",
"signature": { "r": "0x…32 bytes…", "s": "0x…32 bytes…", "v": 27 },
"nonce": "1787067314957",
"signature_chain_id": 999
}

This is the one endpoint that takes the signature split into { r, s, v } rather than a single hex string.

Of the five signed members, three are not in the body: user is the wallet your account_id derives from, destination is described below, and hyperflowEnvironment is "Mainnet" on this base URL.

On the default HyperCore rail, send no destination field at all — sign your own wallet address as destination and the server verifies against it.

On the Arbitrum (EVM) rail, add two more fields:

FieldValue
destination_chain_id42161 on mainnet, 421614 on testnet
destination_recipientThe same address you signed as destination

The EVM rail is offered only to email / embedded-wallet accounts. A normal EOA withdraws to its own HyperCore wallet.

The response

A valid request returns status: "REQUESTED" together with a withdrawal_id.

A request that fails validation returns status: "REJECTED" — still a 200 — with one of these reasons:

reasonMeaning
BELOW_MINUnder withdrawal.min_amount
BELOW_MIN_AFTER_FEEWould fall under the minimum once the new-wallet fee is deducted; new_wallet_fee carries the amount
ABOVE_MAXOver the per-transaction ceiling — not published in /config
DAILY_LIMIT_EXCEEDEDOver your rolling daily allowance — not published
RATE_LIMITEDToo many requests in a short window

Follow the lifecycle

GET /withdrawal-history/{withdrawalId}
GET /account/{account_id}/withdrawal-history?limit=&offset=&from=&to=

The single form is a top-level route, not under /account. The list form returns data: { account, withdrawals: [] } — no total. One withdrawal looks like this:

{
"withdrawal_id": "…",
"amount": "25",
"l1_send_amount": "25",
"destination": "0x…",
"status": "COMPLETED",
"failure_reason": null,
"l1_tx_hash": "0x…",
"created_at": 1787067314951,
"completed_at": 1787067319004
}

The l1_ prefix means Hyperliquid’s L1 — the chain the transfer actually settles on.

The happy path is REQUESTED → ACCEPTED → PROCESSING → COMPLETED. Four states are terminal:

Terminal statusMeaning
COMPLETEDSent. l1_send_amount is the amount that actually left, net of any new-wallet fee, and l1_tx_hash is the on-chain transfer
REJECTEDTurned down after acceptance. An insufficient-balance verdict is asynchronous — it appears here, not in the submit response
REFUNDEDDebited, then returned in full to your balance
FAILEDCould not be completed

Between ACCEPTED and COMPLETED every withdrawal passes the platform’s multi-signature review, which adds a short delay before funds leave custody.

The first-ever credit to a destination wallet with no HyperCore history incurs Hyperliquid’s one-time $1 USDC activation fee.