401 after refresh token exchange - clock skew?

Hey folks,

Hitting a weird snag with our internal Python script that pulls real-time queue stats via the Genesys Cloud API. It works fine for the first few hours, then suddenly starts dropping 401 Unauthorized errors on every request.

The catch is, the refresh token exchange itself succeeds. I get a brand new access token back in the JSON response. But the moment I use that new token to hit /api/v2/interaction/cases, boom. 401.

Here’s the flow:

  1. Access token expires.
  2. Script calls POST /oauth/token with grant_type=refresh_token.
  3. Response is 200 OK with new access_token and expires_in.
  4. Script immediately calls GET /api/v2/interaction/cases with the new token.
  5. Response is 401 Unauthorized with body: {"errors":["Unauthorized"],"messages":["Authorization has been denied for this request."]}

I’ve checked the token payload (decoded the JWT). The exp claim looks valid for the next 3600 seconds. The iat timestamp matches the current server time within a second.

I’m thinking maybe there’s a clock skew issue between our EC2 instance (running the script) and the Genesys auth server? Or maybe the token isn’t actually valid yet?

We’ve got a small window where the token is technically ‘expired’ according to Genesys but ‘valid’ according to our local clock? Or vice versa?

Any ideas on how to debug this without just adding a 5-second sleep after refresh (which feels hacky)?

Here’s the relevant snippet:

import requests

headers = {
 'Authorization': f'Bearer {new_token}',
 'Content-Type': 'application/json'
}

response = requests.get('https://api.mypurecloud.com/api/v2/interaction/cases', headers=headers)
print(response.status_code)
print(response.text)

Status code is 401. Text is the error above.

Token looks good. Endpoint is public. What am I missing?