Nonce & Rate Limits
Nonce generation and rate limiting specifications for request authentication and replay attack prevention.
Overview
Every signed request requires a nonce (millisecond timestamp). The system validates nonces using time window validation, replay prevention, and rate limiting.
Nonce Types
Wallet Nonce
Used for: Orders, Withdrawals, Leverage Updates, Authentication, Cancel Orders
Format: Millisecond timestamp as
uint256Generation: Current Unix time in milliseconds
const nonce = Date.now();let nonce = U256::from(chrono::Utc::now().timestamp_millis() as u64);Each wallet nonce can only be used once. Generate a fresh timestamp for each operation.
Token Contract Nonce
Used for: ERC-2612 Permit signatures (deposits only)
Format: Sequential
uint256managed by token contractSource: Fetch from token contract before signing
The nonce for Permit signatures must be fetched from the token contract. Using Date.now() for deposit nonces will cause validation failure.
Wallet Nonce Validation
Validation Rules
Time Window
5 minutes
Nonce must be within 5 minutes of current server time
Future Tolerance
1 minute
Tolerance for clock skew between client and server
Server Restart
Server start time
Nonce must be after server restart
Uniqueness
Per wallet
Each nonce can only be used once per wallet
Valid nonce range:
Rate Limiting
Two independent limits apply per wallet:
Request rate
20 requests/second (rolling 1-second window)
Wallet-authenticated requests — REST and WebSocket, including orders and subscriptions
Signed request budget
3,000 signed requests per 5-minute rolling window
All signed operations (orders, replaces, cancels, withdrawals, leverage updates)
The request rate is hard-enforced over a rolling 1-second window: a request is rejected if 20 have already been made in the trailing second.
The signed request budget allows a sustained rate of ~10 signed operations/second. Each signed operation consumes one nonce; the budget frees up as nonces age out of the 5-minute window. A wallet that exhausts its budget is rejected with error code 4035 SUSTAINED_RATE_LIMIT_EXCEEDED until older nonces expire.
Cancels keep working: cancel and cancel-all operations are granted 2x the signed request budget, so a wallet that has exhausted its sustained budget can still pull its resting orders.
Signed requests consume their nonce before the request rate check, so requests rejected for exceeding the request rate still count against the signed request budget.
Unauthenticated read endpoints
Read endpoints that take a wallet as a query parameter — account summary, open orders, max order size, required margin, funding history, trade/order reporting, and PnL history — are not subject to the per-wallet request rate. They carry no signature, so anyone could name any wallet, and a per-wallet limit on them would let one caller consume another wallet's allowance.
These endpoints are rate limited per client IP at the edge instead. Treat them as a shared budget across everything you call from one address, and prefer polling them no faster than your UI actually needs. max_order_size in particular is a search over placement validation rather than a cached read: call it when a user asks for a maximum, not on a timer. If you know the size you want and need the collateral for it, use required_margin — it is a single evaluation and far cheaper.
Common Errors
Nonce too old (outside 300000ms window)
Nonce older than 5 minutes
Generate fresh timestamp
Nonce too far in future
System clock ahead of server
Synchronize system clock
Nonce already used (replay attack detected)
Nonce reused
Generate new nonce
Nonce predates server start
Nonce from before server restart
Generate new nonce
Rate limit exceeded (4029)
More than 20 requests/second
Reduce request rate
Sustained request rate exceeded (4035)
Signed request budget exhausted
Back off; budget frees as nonces age past 5 minutes. Cancels have 2x headroom and keep working
Order not found or already closed (4041)
Cancel/replace raced a fill or cancel
Benign — treat as already-closed, do not retry or alert
Signature verification failed (deposits)
Incorrect token contract nonce
Fetch fresh nonce from contract
For complete error code reference, see Error Codes.
Last updated