Analytics API 413 Entity Too Large on 90-day query

Need some help troubleshooting the 413 Entity Too Large error when querying /api/v2/analytics/interactions/summary with a date range spanning 90 days. The request payload is valid, but the server rejects it immediately.

  • Split the range into multiple 7-day chunks sequentially.
  • Reduced the list of included metrics to only talk-time and hold-time.

What is the recommended way to structure the request or paginate to avoid this limit?

This looks like a payload size limit issue rather than a query complexity problem.

Need some help troubleshooting the 413 Entity Too Large error when querying /api/v2/analytics/interactions/summary with a date range spanning 90 days.

You cannot fetch 90 days in one shot. Use the asynchronous API instead to handle large datasets without hitting request size limits.

let analyticsApi = PureCloudPlatformClientV2.AnalyticsApi()
let request = AnalyticsApiGetInteractionSummaryRequest()
request.dateFrom = "2023-01-01"
request.dateTo = "2023-03-31"
// This returns a job ID immediately, avoiding 413 errors
analyticsApi.getInteractionSummary(request, completion: { response, error in
 if let jobId = response?.id {
 // Poll /api/v2/analytics/jobs/\(jobId) for results
 }
})

You need to step away from the synchronous endpoint entirely. The /api/v2/analytics/interactions/summary endpoint is designed for quick, small lookups, not bulk data extraction. When you send a 90-day range, the server-side validation likely fails before it even processes the query, hence the 413. The suggestion above to use the async API is correct, but let’s look at how to implement that reliably in a ServiceNow script include.

The key is /api/v2/analytics/interactions/summary/query. This returns a job ID immediately. You then poll /api/v2/analytics/jobs/{jobId} until the status changes to completed. Here is a Node.js example using the SDK that handles the polling loop:

const platformClient = require('genesys-cloud-purecloud-platform-client');
const analyticsApi = platformClient.AnalyticsApi;

async function fetchLargeAnalytics() {
 const request = {
 "groupBy": ["user"],
 "dateRange": {
 "startDate": "2023-10-01T00:00:00.000Z",
 "endDate": "2023-12-31T23:59:59.999Z"
 },
 "metrics": ["talk-time", "hold-time"],
 "size": 1000 // Max per page, use pagination for more
 };

 // 1. Submit the async job
 const job = await analyticsApi.postAnalyticsInteractionsSummaryQuery(request);
 let jobId = job.jobId;

 // 2. Poll for completion
 while (true) {
 const status = await analyticsApi.getAnalyticsJob(jobId);
 if (status.status === 'completed') {
 return status.result; // Contains the data
 } else if (status.status === 'failed') {
 throw new Error(`Job failed: ${status.errorMessage}`);
 }
 // Wait 2 seconds before next poll
 await new Promise(r => setTimeout(r, 2000));
 }
}

In ServiceNow, map this logic to a GlideAjax call or a scheduled job. Do not block the UI thread. Also, ensure your OAuth token has the analytics:interaction:view scope. If you hit rate limits on the polling endpoint, add a jitter to your delay. This approach scales to years of data without hitting entity size limits.