Genesys Cloud API 401 after token refresh due to clock skew

We’re hitting a weird 401 Unauthorized error on our Android app when using the Genesys Cloud Web Messaging SDK. The issue seems to be related to clock skew between our device time and the Genesys Cloud servers.

Here’s the setup: We’re using the standard OAuth 2.0 flow with the genesyscloud SDK for Kotlin. Everything works fine initially. The app gets an access token, and we can start conversations without any issues. However, after the access token expires (usually around 1 hour), the SDK attempts to refresh the token using the refresh token.

The refresh request itself succeeds, and we get a new access token and refresh token back. But immediately after that, any subsequent API calls (like sending a message or updating conversation status) fail with a 401 error. The error message is pretty generic: Invalid token.

I’ve been debugging this by logging the timestamps. It looks like the device’s system clock is slightly ahead of the server’s clock (by about 5-10 seconds). When the SDK tries to use the newly refreshed token, the server rejects it because the issued_at timestamp in the token is in the “future” relative to the server’s clock.

Here’s a snippet of the error log we’re seeing:

try {
 val response = genesysCloudApi.conversations().messaging().sendConversationMessage(
 conversationId,
 messageBody
 )
 Log.d(TAG, "Message sent successfully: $response")
} catch (e: ApiException) {
 Log.e(TAG, "Failed to send message", e)
 // Output: com.genesiscloud.api.ApiException: 401 Unauthorized
}

And the token refresh response looks normal:

{
 "access_token": "eyJhbGci...",
 "token_type": "Bearer",
 "expires_in": 3600,
 "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
 "scope": "conversation:read conversation:write"
}

I’ve tried manually adjusting the device’s clock to match the server time (using ntpdate or similar tools for testing), and the issue goes away. But obviously, we can’t expect our users to do that.

Is there a way to configure the SDK or the OAuth flow to handle this clock skew? Or should we be implementing some kind of clock synchronization mechanism on the device side before making API calls?

We’re using Kotlin 1.8 and the latest version of the Genesys Cloud SDK for Android. Any insights would be appreciated.