Stats
Response
First reply average, median and 90th percentile, how fast tickets got answered, where
they waited, and how many replies a resolution took.
GET
/api/{tenant:minlength(2)}/v{version:apiVersion}/stats/response
- Authorisation
- Minimum role: USER
Request arguments
| Name |
Type |
Source |
| group_ids | Int32[] | Query |
| timeframe | ENUM dashboard_kpi_timeframe | |
| from | DateTime | |
| to | DateTime | |
| compare | Boolean | |
Request body example
Response
- Status
- 200 (OK)
- Type
- DTO_stats_response
- Wrapper
- DTO_response_wrap
- Other statuses
- 400 (BadRequest), 403 (Forbidden)
Response body example
DTO_stats_response
| Name | Type | ReadOnly | Description |
| seconds_per_status | DTO_stats_term[] | | Average time spent in each status before resolution, one row per status. |
| replies_to_resolution_per_group | DTO_stats_term[] | | Average replies before a ticket is resolved, per group. |
| period | DTO_stats_period | | Period |
| first_reply_average_sec | DTO_stats_metric | | Seconds to first reply, averaged over tickets that got one. |
| first_reply_median_sec | DTO_stats_metric | | First reply median sec |
| first_reply_p90_sec | DTO_stats_metric | | First reply p90 sec |
| resolution_estimate_sec | DTO_stats_metric | | The dashboard's long-standing estimate: the sum of the average time spent in each
non-closed status. Not a per-ticket measurement - the UI labels it as an estimate. |
| first_reply_series | DTO_stats_series[] | | Median and p90 first reply, one point per bucket. |
| first_reply_distribution | DTO_stats_term[] | | How fast tickets got their first reply, as disjoint buckets (under 1h, 1-4h, 4-24h,
over 24h). Counts, not shares - the card computes the percentage. |
| replies_to_resolution_average | Double (nullable) | | Average replies before resolution across every group in the slice. |
DTO_stats_term
| Name | Type | ReadOnly | Description |
| id | Int32 | | Entity id when the term refers to one (group, status, mailbox); 0 otherwise. |
| key | String | | Stable key for terms that are enums rather than entities ("EMAIL", "CHAT_BOT"). |
| label | String | | Label |
| count | Int32 | | How many tickets fell into this term. |
| previous_count | Int32 (nullable) | | The term's own count in the comparison window. Null when not comparing. |
| value | Double (nullable) | | A secondary metric where the card shows one (average seconds, a percentage). |
DTO_stats_period
| Name | Type | ReadOnly | Description |
| from | DateTime | | First day of the window, workspace-local. |
| to | DateTime | | Last day of the window, workspace-local. |
| previous_from | DateTime (nullable) | | First day of the comparison window. Null when not comparing. |
| previous_to | DateTime (nullable) | | Last day of the comparison window. Null when not comparing. |
| time_zone | String | | IANA id of the zone every bucket and boundary was cut in. |
| granularity | String | | "hour", "day" or "month" - the width of one point in every series below. |
| timeframe | ENUM dashboard_kpi_timeframe | | Which preset produced this window (CUSTOM when from/to were supplied). |
| compare | Boolean | | True when the previous-period figures are populated. |
DTO_stats_metric
| Name | Type | ReadOnly | Description |
| current | Double (nullable) | | Current |
| previous | Double (nullable) | | The same figure over the previous window. Null when not comparing, or when there is no history. |
DTO_stats_series
| Name | Type | ReadOnly | Description |
| key | String | | Stable key the frontend maps to a colour and a translated label. |
| label | String | | Server-side fallback label, used when the key is dynamic (a group or status name). |
| points | DTO_stats_point[] | | Points |
DTO_stats_point
| Name | Type | ReadOnly | Description |
| label | String | | Short human label for the axis ("Jul 20", "10:00", "Jul 2026"). |
| date | DateTime | | Start of the bucket, workspace-local. |
| value | Double (nullable) | | Null means "no data in this bucket", which a chart draws as a gap, not a zero. |
ENUM dashboard_kpi_timeframe
| Value | Name | Description |
| 0 | UNKNOWN | UNKNOWN |
| 1 | TODAY | TODAY |
| 2 | YESTERDAY | YESTERDAY |
| 3 | THIS_WEEK | THIS_WEEK |
| 4 | LAST_4_WEEKS | LAST_4_WEEKS |
| 5 | LAST_12_WEEKS | LAST_12_WEEKS |
| 6 | ALL_TIME | ALL_TIME |
| 7 | CUSTOM | Stats only: the caller supplies from and to instead. Resolving this without dates is
an error, so the shared GetTimeFrame() extension deliberately refuses it. |
| 8 | LAST_12_MONTHS | LAST_12_MONTHS |
Generated Aug 4, 2026 18:37