Group and count answers “how many of each” without pulling the records themselves.
Every resource has it.
groupId is the value you grouped by, so its type follows the field: a string for
type, a UUID for computed.projectId, a boolean for isArchived.
Group by more than one field
Pass an array for a compound grouping. groupId then holds the combination:
Nested paths work
Any path you can filter on, you can group on:
Array fields need unnestGroupByField
Grouping by an array field counts whole arrays by default, which is rarely what you
want. Set unnestGroupByField to count each value separately:
Without it, ["urgent", "rework"] is one group. With it, urgent and rework each
get their own count, and a record with both tags counts once in each.
Filters apply
Every filter the list endpoint takes works here too, so you can scope a breakdown
the same way you would scope a query:
groupByField is required, and it only accepts field-name characters. A value
with anything else in it is rejected with 400.
Grouping from a list endpoint
group-and-count is the supported way to group, and it is the right tool when you
want counts. List endpoints also accept a groupBy parameter, which is what you
need for sums, averages, and other aggregates.
A grouped read must carry a select naming the grouped fields and the aggregates
you want, because everything a grouped query returns has to be one or the other:
Aggregates are objects, so they only fit in a POST /{resource}/query body:
Each aggregate takes an aggregate function, an alias to return it under, and a
field for every function except COUNT. The functions are COUNT,
COUNT_DISTINCT, SUM, MIN, MAX, and AVG.
A grouped query must select only grouped fields or aggregate expressions:
groupBy does not combine with a join that selects fields — those come back
as un-grouped expressions. Group on the resource’s own fields instead.
- Models that always project computed or joined fields cannot use
groupBy.
deliverable is one of them, so a grouped deliverable read returns 400.
Use POST /deliverable/group-and-count for raw fields or
POST /deliverable/groups
for its domain dimensions.
Each of these is a 400 that names the field or resource at fault.