How to chunk a 90-day Analytics API query when hitting 413 Entity Too Large

What’s the right way to break up a long date range before the Analytics API throws a 413? We’re firing a GET to /api/v2/analytics/conversations/summary with a 90-day window and the request body keeps getting rejected. The payload looks standard enough, but the server drops it hard.

{
 "dateFrom": "2024-01-01T00:00:00.000Z",
 "dateTo": "2024-03-31T23:59:59.999Z",
 "groupings": ["queue"],
 "metrics": ["conversationCount"],
 "pageSize": 500
}

Tokio handles the request fine, but past 60 days the response is just a flat 413. We’ve tried lowering pageSize and dropping groupings. Barely moves the needle. Looks like we need to slice the window into smaller chunks and merge the results downstream. Checking if there’s a recommended chunk size. We’re looping through date ranges in a tokio task, but the rate limits are getting tight when we split it into daily slices. Still tweaking the merge logic.

The 413 error isn’t usually about the request body size for the summary endpoint, it’s about the response payload exceeding the server’s limit. When you ask for 90 days of data with specific groupings, Genesys tries to build that entire dataset in memory before sending it back. It’s a hard ceiling.

The standard fix is to chunk the date range. You don’t need a complex library for this, just a simple loop that splits your 90-day window into smaller, manageable blocks. I usually stick to 14-day chunks. It’s a safe bet that keeps the response size down without hitting the API rate limits too hard.

Here is how I handle it in a basic script. You’ll need to adjust the dateFrom and dateTo in the loop for each iteration.

import requests
from datetime import datetime, timedelta

def fetch_analytics_chunks(base_url, access_token, start_date, end_date, chunk_days=14):
 headers = {
 'Authorization': f'Bearer {access_token}',
 'Content-Type': 'application/json'
 }
 
 current_start = start_date
 all_data = []
 
 while current_start < end_date:
 # Calculate the end of the current chunk, ensuring we don't exceed the total end date
 chunk_end = min(current_start + timedelta(days=chunk_days), end_date)
 
 payload = {
 "dateFrom": current_start.isoformat() + "Z",
 "dateTo": chunk_end.isoformat() + "Z",
 "groupings": ["queue"],
 "metrics": ["conversationCount"]
 }
 
 print(f"Fetching chunk: {current_start.date()} to {chunk_end.date()}")
 
 try:
 response = requests.post(
 f"{base_url}/api/v2/analytics/conversations/summary",
 headers=headers,
 json=payload
 )
 
 if response.status_code == 200:
 data = response.json()
 all_data.extend(data.get("data", []))
 print("Chunk successful")
 elif response.status_code == 413:
 print("Still getting 413. Try reducing chunk_days.")
 break
 else:
 print(f"Error {response.status_code}: {response.text}")
 
 except Exception as e:
 print(f"Request failed: {e}")
 
 # Move to the next chunk
 current_start = chunk_end
 
 return all_data

# Usage example
start = datetime(2024, 1, 1)
end = datetime(2024, 3, 31)
# results = fetch_analytics_chunks("https://api.mypurecloud.com", "YOUR_TOKEN", start, end)

One thing to watch out for is the groupings parameter. If you are grouping by agent or skill, the data volume spikes much faster than just queue. You might need to drop the chunk size to 7 or even 3 days if you see the response times creeping up.

Also, make sure you are aggregating the results on your end. The API won’t sum up the 14-day chunks for you. You’ll have to loop through all_data and sum the conversationCount for each queue ID manually. It’s a bit of extra work, but it beats hitting the 413 wall.

I run this kind of job during off-peak hours to avoid throttling, but for a one-off report, the chunking logic above should clear the path. The key is just keeping the date window tight enough that the resulting JSON object doesn’t trigger the server’s size limit.