How to Fix OKX API Error 50102: Calibrate Your Server Time

 / 
OKX
 / 
1

The OKX API error 50102 has one main cause: the OK-ACCESS-TIMESTAMP you send with your request is more than 30 seconds off from OKX's server time. The server sees the request as expired and rejects it.

To fix it, follow two steps: first, get the exact OKX server time, then make sure your local time stamp drift stays within the allowed range.

Step 1: Get OKX Server Time and Calculate the Offset

Call the official OKX public time endpoint GET /api/v5/public/time. The response includes the server time in ISO 8601 format. Grab your local system time at the same moment. Subtract one from the other to find the offset. You'll then know how far your clock drifts from OKX.

Step 2: Format Your Timestamp Correctly – Millisecond Precision

Fix the way your code creates the timestamp. OKX requires the OK-ACCESS-TIMESTAMP header to be a strict ISO 8601 UTC string with millisecond precision: YYYY-MM-DDTHH:MM:SS.SSSZ. Exactly three digits for milliseconds. If your format looks like 2024-06-15T12:34:56.789000Z (with microseconds) or missing the trailing Z, the request will be rejected. After calibration, your generated timestamp must differ from OKX server time by less than 30 seconds and match the exact 3-millisecond ISO 8601 format.

Important: The timestamp used in the prehash string for your signature must be exactly the same as the value in the OK-ACCESS-TIMESTAMP header – same format, same millisecond digits. Any mismatch causes a signature failure.

Adapting Third-Party SDKs

Some SDKs offer a use_server_time=True parameter that auto-fetches OKX time. However, the SDK may internally return a Unix millisecond timestamp, while the API expects an ISO 8601 string. This mismatch leads to error 50102. Check your SDK version or manually convert the timestamp to ISO 8601 format.

Manual Timestamp Generation for HTTP Headers

When generating timestamps, do not use datetime.now() without a timezone – it defaults to your local system time, which is often wrong. Always force UTC and truncate to milliseconds. Here's a Python example:

import datetime as dt
def get_time() -> str:
now = dt.datetime.now(dt.timezone.utc)
# truncate microseconds to milliseconds
now_ms = now - dt.timedelta(microseconds=now.microsecond % 1000)
return now_ms.strftime('%Y-%m-%dT%H:%M:%S.') + f'{now_ms.microsecond // 1000:03d}Z'

This code truncates the time to exactly three millisecond digits and appends the Z for UTC.

Common Pitfalls

The biggest trap is local system clock drift, especially on cloud virtual machines running trading bots. Virtualized clocks easily drift away from real time. Another common issue is the SDK's use_server_time=True – you might think it's synced, but the timestamp format might still be a Unix millisecond number instead of an ISO 8601 string, causing a format mismatch.

Follow-Up Checks

If the local time offset is more than one second, sync your system clock with NTP first. On Windows, enable the time service synchronization. On Linux/macOS, run sudo ntpdate -s time.apple.com. After syncing, test with a small API call (like fetching your account balance) to confirm error 50102 is gone. If it still appears, check your signature string – the timestamp in the signature prehash must be exactly the same string you put in the header. Never generate it twice.