Could someone explain the pagination mechanism for the analytics details query endpoint? I am building a Grafana data source plugin and need to aggregate full conversation datasets.
Call /api/v2/analytics/conversations/details/query with size=100.
Receive nextPageToken in the response header.
Retry with the token.
The nextPageToken expires rapidly. Does this endpoint support offset-based pagination like other GC APIs, or must I handle token expiration in the fetch loop?
This looks like a misunderstanding of the cursor pagination model; nextPageToken is ephemeral by design to prevent race conditions, so you must chain requests immediately in a loop rather than storing tokens for later batch processing.
async function fetchAllDetails(queryParams: any) {
let allDetails = [];
let nextPageToken = undefined;
do {
const response = await platformClient.AnalyticsApi.postAnalyticsConversationsDetailsQuery({
body: { ...queryParams, nextPageToken }
});
allDetails.push(...response.entity.conversations);
nextPageToken = response.entity.nextPageToken;
} while (nextPageToken);
return allDetails;
}
Implement this synchronous loop in your renderer process to ensure the token remains valid throughout the aggregation cycle.
How I usually solve this is by chaining requests immediately in a Python loop to avoid token expiry. Storing tokens for batch processing breaks the cursor logic.
Warning: Do not mix page and nextPageToken parameters.
This is typically caused by the ephemeral nature of the nextPageToken in cursor-based pagination. The token expires quickly to prevent race conditions, so you must chain requests immediately in a loop. Do not store tokens for later batch processing.
async function fetchAllConversations(apiClient, initialParams) {
let allResults = [];
let currentParams = { ...initialParams };
do {
const response = await apiClient.AnalyticsApi.postAnalyticsConversationsDetailsQuery(currentParams);
allResults = allResults.concat(response.body.entities);
if (response.headers['nextpagetoken']) {
currentParams.nextPageToken = response.headers['nextpagetoken'];
} else {
break;
}
} while (response.headers['nextpagetoken']);
return allResults;
}
Ensure you pass the nextPageToken from the headers directly into the next request body. Mixing offset parameters with cursor tokens breaks the query logic.