Calculating 30-minute interval utilization for tHandle, tAcw, and tHold via Analytics API

We are building a custom reporting dashboard that needs to visualize agent utilization metrics at a granular level. Specifically, we require the total handle time (tHandle), after-call work (tAcw), and hold time (tHold) broken down into 30-minute intervals. The goal is to identify peak load periods for specific queues during our operational hours in Central European Time.

I have been experimenting with the GET /api/v2/analytics/conversations/queues endpoint. The documentation suggests using the interval parameter to define the time bucket. I set the interval to PT30M and provided a startTime and endTime spanning a single business day. However, the response payload seems to aggregate the metrics across the entire period rather than providing discrete buckets for each 30-minute slice. Or perhaps I am misinterpreting the structure of the returned JSON.

Here is the simplified request configuration we are using:

GET /api/v2/analytics/conversations/queues
{
 "startTime": "2023-10-25T08:00:00.000Z",
 "endTime": "2023-10-25T17:00:00.000Z",
 "interval": "PT30M",
 "groupBy": ["queueId"],
 "metrics": ["tHandle", "tAcw", "tHold"]
}

The response contains a values array, but the intervalStart and intervalEnd fields appear to be identical for all entries, or the data is collapsed into a single summary object per queue. This makes it impossible to plot the utilization trend over time. I suspect there might be a specific query parameter or a different endpoint variant required to force the API to return time-series data instead of a period aggregate.

Has anyone successfully extracted these specific metrics at a 30-minute granularity? We need the raw values to calculate the percentage of time agents spend on calls versus hold and ACW within each half-hour block. The current output is too high-level for our optimization needs.

You might want to check the interval parameter. It defaults to 15 minutes, so passing 30m should get you exactly what you need. Just make sure your since and until timestamps are ISO 8601 UTC. The API doesn’t care about Central European Time, so you’ll need to convert that client-side or in your dashboard tool.

Are you aggregating this data in the dashboard layer or pushing it to a warehouse? If it’s the latter, the standard analytics endpoint might be too heavy. The 30-minute interval is fine, but the real issue is usually the aggregation logic. You don’t need to sum tHandle, tAcw, and tHold separately for every single agent then roll them up. That’s a lot of redundant data transfer.

Instead, use the metrics parameter to specify exactly what you need. It’s cleaner and faster. Here’s how I structure the request in a REST Proxy action. It pulls the data in one go and lets the API do the heavy lifting.

{
 "since": "2023-10-01T00:00:00Z",
 "until": "2023-10-01T23:59:59Z",
 "interval": "30m",
 "metrics": [
 "tHandle",
 "tAcw",
 "tHold"
 ],
 "groupings": [
 "queueId"
 ],
 "groupBy": "time"
}

You’ll need the analytics:query scope on your OAuth token. If you’re using a script variable for the date range, make sure the format is strict ISO 8601. The API is picky.

Be careful with the timezone offset. The API returns UTC. If your dashboard expects Central European Time, you have to shift the timestamps yourself. The API won’t do it for you. I usually add a small calculation in the script to offset by +2 hours (or +3 in summer) before passing it to the visualizer.

Also, check if you’re hitting rate limits. The analytics API has a lower throughput than the standard CRM endpoints. If you’re querying multiple queues, batch them or stagger the requests. I’ve seen scripts hang when they try to pull a full week of 30-minute intervals for 20 queues in parallel. Space it out.

One more thing. The tHold metric sometimes includes pre-answer hold time. If you only want post-answer hold, you might need to filter by conversationType. It’s a small detail but it messes up the utilization math if you’re not careful.

Try this payload and see if the response size drops. If it’s still slow, check your queue IDs.