Skip to content

Learn

Exchange APIs

Timestamp tolerance compared across exchange APIs

Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs.

Every venue that signs requests also checks that the request is fresh, and every one of them does it differently. The format differs (integer milliseconds, ISO 8601, epoch seconds), the width of the window differs, some venues treat a request from the future more harshly than a late one, and each returns its own error code. Get any of it wrong and the failure reads as an authentication problem.

Clock sync and timestamp errors covers how to diagnose drift. This page is the per-venue reference: the rule each venue documents, the code it returns, and the venue-specific detail that catches people who already know how the others work.

The matrix

VenueTimestamp field and formatWindowRequest ahead of server timeError
Binance Spottimestamp parameter, milliseconds or microsecondsrecvWindow: optional, default 5000 ms, maximum 60000 msRejected at 1 second or more ahead-1021
Binance USDⓈ-MAs SpotrecvWindow default 5000 ms; we did not find a stated maximumSame 1-second rule-1021
Bybit V5X-BAPI-TIMESTAMP header, millisecondsX-BAPI-RECV-WINDOW: optional, default 5000 msMust be less than 1000 ms ahead10002
OKX RESTOK-ACCESS-TIMESTAMP, ISO 8601 UTC with millisecondsRejected if more than 30 seconds from server timeSame 30-second tolerance50102; a malformed value is 50112
OKX WebSocket loginUnix epoch secondsLogin request expires 30 seconds after its timestamp—Not documented in our fact card
Hyperliquidnonce, recommended to be the current time in millisecondsMust beat the smallest of the signer’s recent nonces, be unused, and fall inside a validity window around block timeCovered by the validity windowWe did not find a nonce-specific error string

Alpaca and IBKR do not appear because neither signs requests: Alpaca sends credentials as headers, and IBKR’s TWS API is a socket to a logged-in application. There is no timestamp to get wrong.

Where the venues actually differ

Binance: early is worse than late

Binance documents its check as pseudocode:

if (timestamp < (serverTime + 1 second) && (serverTime - timestamp) <= recvWindow)

A request can be up to recvWindow milliseconds late, but a request 1 second or more ahead of server time fails regardless of recvWindow. That is why -1021 INVALID_TIMESTAMP has two messages: “Timestamp for this request is outside of the recvWindow.” and “Timestamp for this request was 1000ms ahead of the server’s time.” A fast clock fails even at the maximum window, so widening recvWindow does nothing for it. Binance recommends a window of 5000 ms or less.

On spot, recvWindow accepts up to three decimal places, for microsecond precision. On USDⓈ-M futures the same inequality applies and the default is the same, but we did not find a maximum on the futures General Info page. Do not carry the spot 60000 ms ceiling over to futures code. See Binance API error -1021.

Bybit: the same shape, and the window is signed

Bybit’s guide states the rule as an inequality:

server_time - recv_window <= timestamp < server_time + 1000

Structurally that is Binance’s rule: late by up to the window, less than a second early. The difference is that Bybit puts recv_window inside the signature pre-hash, alongside the timestamp and API key. The window value is authenticated, and the value you sign must be the value you send.

The guide says a smaller window “is more secure”, recommends keeping local time NTP-synchronised, and exposes server time at GET /v5/market/time. A request outside the window returns 10002, “The request time exceeds the time window range.” The same error table also lists -1, “request expired: o@0, now[] diff[]”; we did not find further explanation of it. See Bybit API error 10002.

OKX: a wider window with a stricter format

Thirty seconds is far more forgiving than a 5000 ms default, which moves the usual failure from drift to format. OKX wants ISO 8601 UTC with milliseconds, for example 2020-12-08T09:08:57.715Z, and its docs name local timezone offset as the most common cause of 50102.

OKX separates the two failures: a timestamp that is well-formed but too far from server time returns 50102, “Timestamp request expired.”; a malformed one returns 50112, “Invalid OK-ACCESS-TIMESTAMP.” The docs recommend syncing via GET /api/v5/public/time before placing orders.

WebSocket login uses epoch seconds, not ISO 8601. A timestamp helper shared between REST and WebSocket code will be wrong for one of them. See OKX API error 50102.

Hyperliquid: a nonce is a replay guard, not a freshness check

Hyperliquid has no receive window. Every /exchange request carries a nonce, and the docs recommend using the current millisecond timestamp. The rules:

  1. The venue stores a set of the highest recent nonces per signer. A new nonce must be larger than the smallest in that set and never used before.
  2. The nonce must fall within a validity window relative to the block’s timestamp. The set size and the window are on the nonces and API wallets page.
  3. Nonces are tracked per signer. With an API wallet, the signer is the agent address, so sub-accounts signed by the same API wallet share one nonce set. The docs’ advice is a separate API wallet per sub-account or process.

Freshness in the CEX sense is the optional expiresAfter field, a millisecond timestamp that some actions accept. User-signed actions such as USDC transfers do not support it, and actions cancelled for a stale expiresAfter are charged more heavily against the address-based rate limit.

The docs also warn that once an API wallet is deregistered and its nonce state pruned, previously signed actions can be replayed. Generate new wallets rather than reusing addresses. See Hyperliquid API setup.

“Action already expired” is a different thing: Hyperliquid’s support FAQ documents it for the web app, and we did not find it mapped to the API’s expiresAfter.

What to do in code

Run NTP and measure the delta. At startup, fetch the venue’s server time, compare it with local time and log the difference. Bybit and OKX document their server-time endpoints above; the clock-sync page covers Binance.

Generate the timestamp once per request. OKX requires the pre-hash timestamp to equal the header value, and Bybit signs the timestamp too. A second call to the clock between signing and sending is a mismatch.

Format per venue, not per project. Integer milliseconds for Binance and Bybit, ISO 8601 with milliseconds for OKX REST, epoch seconds for OKX WebSocket login. Put the formatter inside each venue’s signer.

Do not widen the window to fix drift. On Binance and Bybit it cannot help a fast clock, and on every venue it trades away replay protection to hide a broken clock.

On Hyperliquid, one API wallet per process with an atomic nonce counter that can be fast-forwarded to the current millisecond, as the docs suggest for porting CEX bots.

Treat timestamp errors as non-retryable. -1021, 10002 and 50102 will recur until the clock is fixed; a retry loop only adds rate-limit pressure. See authentication errors across exchanges.

FAQ

What is the maximum recvWindow on Binance?

On Binance Spot, recvWindow defaults to 5000 ms and has a maximum of 60000 ms, and Binance recommends 5000 ms or less. For USDⓈ-M futures the default is also 5000 ms, but we did not find a maximum stated on the futures General Info page, so do not assume the spot ceiling applies.

Why are my requests rejected when my clock is ahead?

Binance and Bybit both reject a request whose timestamp is a second or more ahead of server time, independently of the receive window. A fast clock therefore fails even with the largest allowed window. Synchronise the clock with NTP rather than adjusting the window.

How much clock skew does OKX allow?

OKX rejects REST requests whose timestamp differs from server time by more than 30 seconds, returning 50102. The format must be ISO 8601 UTC with milliseconds; a malformed value returns 50112 instead. WebSocket login uses Unix epoch seconds and expires 30 seconds after its timestamp.

How does Hyperliquid check request timestamps?

Hyperliquid uses a nonce, recommended to be the current millisecond timestamp. It must be higher than the smallest of the signer’s stored recent nonces, never reused, and inside a validity window around block time. Nonces are tracked per signer, so processes sharing one API wallet share one nonce set.