Skip to content

Nonces & API wallets

How nonces are ordered, how to avoid collisions across processes, and how API wallet pruning works.

Updated Nov 4, 2026Builders2 min read
On this page

Every signed action carries a nonce. The exchange accepts a nonce only if it is greater than the last nonce seen for that signer.

Rules

  • Use milliseconds since the Unix epoch.
  • Nonces must increase monotonically per signer, not per action type.
  • Two actions with the same nonce cannot both be accepted.
  • Nonces older than 24 hours are rejected.
  • A nonce that is too far in the future (more than 10 seconds) is rejected.

One key, one process

If two processes sign with the same key, they will collide. Give each bot its own API wallet, or serialize nonce creation through a single signer service.

code
let lastNonce = 0;
 
function nextNonce() {
  const now = Date.now();
  lastNonce = Math.max(now, lastNonce + 1);
  return lastNonce;
}

For high-throughput systems, use a monotonic counter seeded from the server time and persist it across restarts. Do not use Date.now() alone if two requests can be created in the same millisecond.

API wallet lifecycle

  1. Approve. The master signs approveAgent with the API wallet address and a name.
  2. Use. The API wallet signs orders and cancels. The exchange resolves the account from the approval.
  3. Revoke. The master signs approveAgent with a zero address, or uses the app.
  4. Prune. Unused API wallets are pruned after 30 days of inactivity. Funds are never at risk from pruning; only the permission is removed.

Sub-accounts and vaults

Sub-accounts and vaults do not have keys. The master signs and sets vaultAddress to the sub-account or vault address. Nonces are still ordered per master signer, not per sub-account.

Errors

ErrorCause
Nonce too lowA previous action already used this nonce
Nonce too highClock skew greater than 10 seconds
Duplicate nonceTwo actions submitted with the same nonce
API wallet not approvedMissing or revoked approval

Was this page helpful?