Skip to main content
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.