For the complete documentation index, see llms.txt. This page is also available as Markdown.

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 uint256

  • Generation: 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 uint256 managed by token contract

  • Source: 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

Rule
Value
Description

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:

Limit
Value
Applies to

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

Error
Cause
Solution

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