Nonce and Retries
The VNX API has no Idempotency-Key; request safety comes from the monotonic nonce on every signed request plus client-supplied unique references like clordid.
Overview
Network blips, timeouts, and process restarts must never cause a duplicate order or transfer. VNX does not use an idempotency key. Instead, two mechanisms protect you:
The monotonic nonce. Every
/private/*request carries an always-increasingx-app-nonce. VNX rejects any request whose nonce is not greater than the last one it saw for your public key, so a replayed (captured) request with an old nonce is refused.Client-supplied unique references. For orders you send your own
clordid(client order ID); reusing logic around that reference lets you detect and avoid duplicates on your side.
The API is also rate-limited to 1 request/second per public key, and there are no webhooks — you confirm outcomes by polling the relevant query endpoint.
Key benefits
Replay protection by default — the nonce alone blocks captured-request replays.
Client-owned references —
clordidgives you a stable handle to reconcile orders without a server-issued key.Predictable pacing — the 1 req/sec limit makes safe retry timing simple to reason about.
How nonce safety works
Each request is signed over the URI path, the canonical-JSON body, and the nonce (see Authentication).
The nonce must be a strictly increasing
uint64(UNIX milliseconds recommended).VNX tracks the highest nonce seen per public key and rejects anything not higher.
A captured request cannot be replayed: its nonce is no longer greater than the latest one.
Because the nonce changes per request, a genuine retry is a new request with a fresh, higher nonce and a fresh signature — not a byte-for-byte resend.
Retrying safely
The rate limit is 1 request/sec per public key, so design retries around it:
2xx — success; do not retry.
4xx (client errors) — fix the request; do not blindly retry.
429 (rate limited) — you exceeded 1 req/sec; back off and retry no faster than the limit.
5xx / network error before response — retry with a new, higher nonce and a fresh signature, using exponential backoff with jitter while respecting 1 req/sec.
For state-changing calls where you cannot tell whether the first attempt landed (e.g. a timeout on addOrder), use your clordid to check before resending: poll queryOrders / queryTrades and only resubmit if the order is absent.
Related
Last updated
