401 Unauthorized after token refresh despite valid claims

We’re hitting a 401 Unauthorized on /api/v2/users/me immediately after a successful refresh token exchange. The access token is generated by our Python script in Berlin (CET), but the Genesys API server seems to be rejecting it due to a 3-minute clock skew. Here is the request header we are sending:

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

The JWT exp claim is definitely in the future relative to our local system time. How do we adjust the token generation logic to account for server-side clock drift without hardcoding an offset?

Clock skew is the usual suspect here, but if your exp is clearly in the future, check the iat (issued at) claim. Genesys rejects tokens if the iat is in the future relative to their server time. If your Berlin script’s clock is ahead of the Genesys auth server by more than a few seconds, the token looks forged.

Sync your local NTP source to time.google.com or pool.ntp.org before generating the token. If that doesn’t fix it, try adding a small delay between the refresh call and the API call. Sometimes the token isn’t fully propagated in the cache yet.

Here is a quick check you can run in Python to see the actual time delta:

import jwt
import requests
import datetime

# Decode without verification to inspect claims
decoded = jwt.decode(token, options={"verify_signature": False}, algorithms=["RS256"])

iat = decoded['iat']
exp = decoded['exp']

# Get current UTC time
now = datetime.datetime.utcnow().timestamp()

print(f"IAT: {iat} | EXP: {exp} | NOW: {now}")
print(f"Delta (now - iat): {now - iat} seconds")

# If delta is negative or > 5, your clock is off or token is stale
if now - iat < -5 or now - iat > 5:
 print("WARNING: Significant clock skew detected.")

Also verify the scope in the token payload. If the refresh token didn’t include view:user or similar, the new access token might lack the necessary permissions for /users/me, resulting in a 401 that looks like a time issue.