Skip to content
TriedDocs
Account

Query analytics

Run a chart query: one metric over a date range, with breakdowns, filters and an optional previous-period comparison.

POSThttps://api.tried.com.au/analytics/query

Computes one metric over calls created in a date range and returns a total plus a daily series per breakdown group. The Analytics page charts use this endpoint. Dashboard members can call it even though it is a POST.

Request#

Field Type Required Description
metric string Yes call_count, call_duration (seconds), call_cost (dollars), success_rate (percent), negative_sentiment_rate (percent), e2e_latency (ms) or chat_count.
measurement string No count (default), sum, avg, median, p50, p90, min, max or rate. Applies to call_duration, call_cost and e2e_latency. With count or rate those metrics use their own default: sum for cost, avg for duration and latency.
breakdowns string[] No Up to 5 dimensions. Each is none, agent, direction, call_type, disconnection_reason, user_sentiment, call_successful, or a field path analysis.<field>, metadata.<key> or variable.<key>. Default [].
breakdown string No Single dimension, kept for older charts. Used only when breakdowns is empty. Default none.
from integer No Start, Unix ms. Default 30 days before to.
to integer No End, Unix ms. Default now.
tz string No IANA time zone for the daily points. Default Australia/Sydney.
filters object No See below. All filters must match.
compare_previous boolean No Also compute the same window immediately before from. Default false.

filters fields, all optional:

Field Type Description
agent_ids string[] Calls from these agents.
call_type string[] Call types to include.
direction string[] inbound, outbound and so on.
disconnection_reason string[] Disconnection reasons to include.
user_sentiment string[] Sentiments to include.
call_successful boolean or null true, false, or null (default) for both.
fields object[] Up to 20 filters on post-call extraction, metadata or dynamic variables. Each has source (analysis, metadata or variable, default analysis), key (1 to 128 characters), op (default eq) and value (string, number, boolean or an array of those). Operators: eq, neq, contains, not_contains, gt, gte, lt, lte, exists, not_exists, in.

Example request#

curl -X POST https://api.tried.com.au/analytics/query \
  -H "Authorization: Bearer $TRIED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "call_count",
    "measurement": "count",
    "breakdowns": [
      "agent"
    ],
    "from": 1792195200000,
    "to": 1792368000000,
    "tz": "Australia/Sydney",
    "filters": {
      "direction": [
        "inbound"
      ]
    },
    "compare_previous": true
  }'
const res = await fetch("https://api.tried.com.au/analytics/query", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "metric": "call_count",
    "measurement": "count",
    "breakdowns": [
      "agent"
    ],
    "from": 1792195200000,
    "to": 1792368000000,
    "tz": "Australia/Sydney",
    "filters": {
      "direction": [
        "inbound"
      ]
    },
    "compare_previous": true
  }),
});
const chart = await res.json();
import os, requests

res = requests.post(
    "https://api.tried.com.au/analytics/query",
    headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
    json={
        "metric": "call_count",
        "measurement": "count",
        "breakdowns": [
            "agent",
        ],
        "from": 1792195200000,
        "to": 1792368000000,
        "tz": "Australia/Sydney",
        "filters": {
            "direction": [
                "inbound",
            ],
        },
        "compare_previous": True,
    },
)
chart = res.json()

Response#

200 OK

{
  "from": 1792195200000,
  "to": 1792368000000,
  "total": 42,
  "previous_total": 35,
  "previous_from": 1792022400000,
  "previous_to": 1792195200000,
  "change_percent": 20,
  "breakdowns": [
    "agent"
  ],
  "series": [
    {
      "key": "agent_4b7e2c9a1f3d5e8b0c6a2d1f",
      "label": "Clinic receptionist",
      "total": 30,
      "previous_total": 24,
      "change_percent": 25,
      "points": [
        {
          "date": "2026-10-17",
          "value": 12
        },
        {
          "date": "2026-10-18",
          "value": 18
        }
      ]
    },
    {
      "key": "agent_9d1f3a5c7e2b4d6f8a0c1e3b",
      "label": "After-hours line",
      "total": 12,
      "previous_total": 11,
      "change_percent": 9.09,
      "points": [
        {
          "date": "2026-10-17",
          "value": 5
        },
        {
          "date": "2026-10-18",
          "value": 7
        }
      ]
    }
  ]
}
Field Type Description
total number Metric over all matching calls, rounded to 2 decimals.
previous_total number or null Same metric for the previous window, or null without compare_previous.
previous_from, previous_to, change_percent integer, integer, number or null Present only with compare_previous. change_percent is null when the previous total is 0.
breakdowns string[] Dimensions used, without none.
series object[] One entry per group, largest total first. key joins the group's values with /; label swaps agent IDs for agent names. With no breakdown there is one series with key all.
series[].points object[] One { date, value } per day that has calls, in tz.

With metric: "chat_count" the response counts chats by start time and ignores filters and breakdowns: one series with key all and label Chats, previous_total: null and breakdowns: [].

Errors#

Status When
400 Body validation failed, for example metric: Invalid enum value... or breakdowns: Array must contain at most 5 element(s).
401 Missing or invalid API key.
403 The key's IP allowlist or scopes reject the request. This route needs the analytics scope.
429 Rate limit exceeded. See Rate limits.

See Errors for the body format.

Retell compatibility#

Retell's public API reference has no analytics endpoints, so this route has no Retell SDK equivalent.