Skip to main content
Every POST /exchange request includes a nonce — an integer that the server uses to prevent replay attacks. Because the nonce is embedded in the signed message, an attacker who intercepts a valid signed request cannot resubmit it: the chain records the nonces each signing address has used and rejects a repeat. That same property is what makes re-sending an identical signed request after a timeout safe — see Timeouts and retries.

What Is the Nonce?

The nonce is an int64 (64-bit signed integer) included at the top level of every POST /exchange envelope alongside action and signature. It is part of the signed message, so any tampering with the nonce value will invalidate the signature.
Use the current Unix timestamp in milliseconds. This is a natural choice because it is:
  • Monotonically increasing — subsequent requests naturally have higher nonces.
  • Unique — millisecond resolution makes accidental collisions unlikely in normal usage.
  • Self-documenting — you can decode the approximate time of any request from its nonce.
Millisecond timestamps are sufficient for most use cases. If you need to fire more than one request per millisecond, increment the nonce by 1 for each additional request within the same millisecond.

Code Examples

Rules

A Unix millisecond timestamp satisfies all of these by construction, which is why it is the recommended source.

Rejections

Sign requests from one address in sequence, not in parallel. Because each nonce must exceed the last one accepted, two requests signed concurrently can arrive out of order and the lower one is rejected. Assign nonces from a single serialised point per signing address. To parallelise, give each worker its own agent wallet — separate addresses have separate nonce sequences.

Rapid Succession Requests

If you need to submit multiple requests faster than one per millisecond, read the current timestamp once and increment:

Timeouts and retries

This is where a client is most likely to execute an action twice. A timeout or a lost response tells you nothing about whether the request was applied.
Never re-sign a timed-out request with a fresh nonce before reconciling. A new nonce makes it a new, valid request — if the original did land, you have now executed it twice. This is the single most common way an automated client double-trades.
The safe procedure:
1

Re-send the identical signed payload

Byte for byte — the same action, the same nonce, the same signature. If the original was applied, this one is rejected as nonce already used and nothing happens twice. Retrying the same bytes is always safe; it is the only retry that is.
2

Treat the rejection as inconclusive

nonce already used means “this nonce was consumed”, not “your order rested”. It does not tell you the outcome of the original request.
3

Reconcile by querying

Establish what actually happened from the read side, never by inference.
4

Only then decide

Issue a new signed request with a fresh nonce only once the query shows the original did not take effect.
Always set the client order ID c on orders you may need to reconcile. Without it, matching a submitted order to what you find in userOrders after a lost response is guesswork.
The alpha test invitation code is single-use and consumed during registration. If a registerAccount response is lost, check accountByAddress before requesting another code — the original may have succeeded and spent the code.