Analytics API Pagination: `pageCount` vs `pageNumber` discrepancy in Kotlin SDK

Looking for advice on handling pagination logic when querying conversation details via the Analytics API. I am building a background sync service in my Android app using Kotlin and the Genesys Cloud Platform SDK (com.genesyscloud:genesys-cloud-core). The goal is to fetch all conversation records for a specific queue within a 24-hour window to update local analytics caches.

The issue arises when the pageSize is large (e.g., 500) but the total result set is smaller than the page size. According to the documentation, pageCount should reflect the total number of pages available. However, when I send a request with pageSize=500 and the result set contains only 100 items, the response returns pageCount=1, which is correct. But when I attempt to fetch the next page by incrementing pageNumber to 2, the API returns an empty list instead of a 404 or a clear boundary error, and pageCount remains 1. This makes it difficult to implement a robust do-while loop in Kotlin that checks response.pageCount > currentPage.

Here is the JSON payload I am sending to /api/v2/analytics/conversations/details/query:

{
 "dateFrom": "2023-10-25T00:00:00.000Z",
 "dateTo": "2023-10-26T00:00:00.000Z",
 "viewId": "my-custom-view-id",
 "pageSize": 500,
 "pageNumber": 1,
 "groupBy": ["routing.queue.id"]
}

In my Kotlin code, I am using the AnalyticsApi().queryConversationsDetails(...) method. The response object QueryConversationDetailsResponse provides getCount() and getTotalCount(), but the pagination metadata seems inconsistent when the final page is not full. Should I be relying on getCount() < pageSize to determine if I have reached the end, or is there a specific flag in the paging object that indicates no more results? I want to avoid making unnecessary API calls that return empty lists, which impacts my app’s battery life and API rate limits.

Make sure you treat pageCount as the definitive total rather than trusting pageNumber in the response metadata. The Kotlin SDK often misaligns these during sparse dataset queries. Iterate until pageNumber exceeds pageCount to ensure complete retrieval without infinite loops or missing records in your local cache.

The simplest way to resolve this is… to stop guessing and check the raw JSON. pageNumber is zero-indexed in the SDK response, so it always lags behind pageCount. Loop until pageNumber >= pageCount. See Pagination Logic for the spec.

The best way to fix this is to ignore the SDK’s internal pageNumber tracking entirely. It often deserializes metadata incorrectly when the total result set is sparse.

  1. Use a simple while loop that fetches the next page token from the response.
  2. Terminate when the nextPage field is null.
var nextPage = initialResponse.nextPage
while (nextPage != null) {
 val response = analyticsApi.getConversations(nextPage = nextPage)
 nextPage = response.nextPage
}

Make sure you validate the nextPage token existence rather than relying on page count arithmetic. The suggestion above is sound, but sparse datasets often cause pageCount to round up incorrectly.

I encountered similar metadata deserialization issues in custom WebSocket handlers. Always terminate on null token.

while (nextPage != null) { fetchPage(nextPage) }