Get KPIs
POST/report/kpi
Build a tabular KPI report. version: 2 (CLI: --version 2) is required because it selects the current table response; the published request schema does not expose the legacy shape. Use /report/time instead to chart one KPI over time. Report permissions apply to every requested KPI, and results are limited to teams the caller may view. A caller whose highest stats:list scope is self gets only their own numbers: filter.teams is ignored, filter.users is replaced with the caller, and a filter.users list that leaves out the caller is refused.
Set grouping (CLI: --grouping) to one of {"type":"user"}, {"type":"company"}, {"type":"team","level":1}, {"type":"time","period":"hour|day|week|month|quarter|year"}, {"type":"manager","level":1} (level optional), {"type":"state"}, {"type":"city"}, {"type":"zip"}, {"type":"customField","customFieldId":"CF.xxxxxxxx"}, or {"type":"programTask"}. Calendar groups use the querying user's timezone. Grouping chooses the rows but does not itself add a label cell. Add {"value":"groupBy"} to kpis (normally first): its row cell is a user, team, company, or task object when the group key is such an ID, the bucket-start epoch milliseconds for time, or otherwise the scalar group value. Its totalRow cell is "Total". Without groupBy, rows contain only metric cells and no group label.
Pass kpis (CLI: --kpis) as an ordered array of {"value":"...","accumulator":"..."} objects. Run terros report column and copy the returned value and accumulator; availability depends on permissions, reporting configuration, and selected workflows/programs. Important forms include setter|S.xxxxxxxx|count, closer|S.xxxxxxxx|count, action|A.xxxxxxxx|count, custom-field values such as cf|setter|count|CF.xxxxxxxx|S.xxxxxxxx, saved ratios such as Ratio.xxxxxxxx (and legacy ratio|<numerator>|<denominator>), and user fields user.firstAccessDate, user.lastAccessDate, user.count, and user.teams. Use terros workflow get to inspect accessible stage/action IDs and terros customField list for custom-field IDs; do not invent IDs. Action summaries such as action.daysWorked, action.hoursWorked, action.headcount, and action.accounts are also supported when returned by terros report column.
Setter and closer counts count accounts that entered the named stage and attribute them to the account's setter or closer. They use the stage-entry date, not the account last-action date, and do not mean "currently in this stage" unless searchByCurrentStatus: true is supplied. Copy the accumulator from terros report column: sum adds row values and suits additive metrics such as action occurrences; distinct or query runs a separate company-grouped query for totals that must not be derived by adding rows, such as distinct account counts and ratios recalculated at total scope.
Recorder-on time: request recording.activeMinutes for integer minutes rounded to the nearest minute after summing sessions in each cell. It includes wall-clock elapsed time since startedAt for open sessions, recalculated on each request. An open session whose updatedAt is more than 2 hours old is treated as stale and adds 0. Completed sessions use recordedDurationMs when available, otherwise endedAt - startedAt. Request recording.activeSeconds for the unrounded seconds total when displaying <1 min for positive totals below 60 seconds (rounded minutes alone cannot distinguish these from zero). Use accumulator query to round once at total scope. recording.activeHours retains its legacy completed-session whole-hour behavior, and conversation.activeHours is unchanged. The existing recording retention/report window is unchanged.
CLI example: terros report kpi --version 2 --grouping '{"type":"user"}' --kpis '[{"value":"groupBy"},{"value":"recording.activeMinutes","accumulator":"query"},{"value":"recording.activeSeconds","accumulator":"query"}]'. The CLI returns the same numeric values and units as the API.
Date fields are inclusive instants when a KPI supports date filtering. They filter the date field for that KPI: for example, workflow actions use their action timestamp, account-created/assigned/status KPIs use the corresponding account date, and setter/closer stage counts use stage-entry time—not account last-action time. User access/count fields ignore this report date range, so the dates do not have one universal account-creation or last-action meaning across all KPI types. On the account-history path, which serves setter/closer stage counts and account custom-field and ratio KPIs, startDate and endDate are independently optional: start-only applies a lower bound, end-only applies an upper bound, both apply a closed range, and neither applies no date filter. UTC epoch milliseconds (a number below 100000000000 is read as epoch seconds), or an ISO 8601 string. A string ending in Z or a ±HH:MM, ±HHMM or ±HH offset after its time, such as 2026-01-15T10:00:00+0700, is that instant; one without a time zone, such as 2026-01-15, is read as America/Los_Angeles time. Zone-less strings use America/Los_Angeles, not the querying user's timezone. Equal start/end values select only that instant, not a whole day. For one calendar day, send its start and inclusive end, for example 2026-01-01T00:00:00.000Z through 2026-01-01T23:59:59.999Z.
The response arrays align positionally with kpis: rows[rowIndex][kpiIndex] and totalRow[kpiIndex] are values for kpis[kpiIndex]. Join kpis[kpiIndex].value to columns or leaderboardColumns from terros report column for its label, description, type, and formatters. Ratios are calculated per row and are not additive, so a ratio's totalRow cell is null when no supported accumulator defines a total; avg averages row ratios, while distinct/query recalculates the ratio from total-scope inputs. Location (states, cities, zipCodes, polygon), custom field (customFields) and assignment (users) filters narrow only the columns whose accountFilterScope from terros report column lists them. While one of those filters is set, a saved or legacy ratio whose inputs disagree on whether it applies returns null in every row and in totalRow.
Example (synthetic IDs, one UTC day):
terros report kpi --version 2 --grouping '{"type":"user"}' --kpis '[{"value":"groupBy"},{"value":"action|A.xxxxxxxx|count","accumulator":"sum"},{"value":"setter|S.xxxxxxxx|count","accumulator":"distinct"}]' --filter.startDate '2026-01-01T00:00:00.000Z' --filter.endDate '2026-01-01T23:59:59.999Z'
For that example, rows[i][0] is the user object and totalRow[0] is "Total"; indexes 1 and 2 hold the action and setter counts, with a summed and separately queried total respectively.
Request
Responses
- 200
- default
- 4XX
Success
Error
Unauthorized