For AI agents: markdown of this page — /docs-content-en/entities/doc-templates/aggregate.md documentation index — /llms.txt
Aggregate document templates
POST /v1/doc-templates/aggregate
Count and numeric aggregations (sum, average, minimum, maximum) over document templates with filtering and grouping.
Standard fields:
sort— sort index, the only numeric field wheresum/avg/min/maxare meaningfulnumeratorId— numerator, a number, works in numeric functions and ingroupByfileId— template file on Drive, a number, works in numeric functions and ingroupByregion— template region, a string, forgroupByonlymoduleId— owner module, a string, forgroupByonlyactive— active flag, a string, forgroupByonly
The sum/avg/min/max functions accept only numeric fields — sort, numeratorId, fileId. A string field in a numeric function returns 400 INVALID_PARAMS. groupBy accepts any field from the list above.
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
aggregate |
array | no | Array of aggregations. Each item: { "field": "sort", "function": "sum" }. Functions: count, sum, avg, min, max. For count the field is "*". Without the array — count only |
filter |
object | no | Filtering by the fields from GET /v1/doc-templates/fields. Filtering syntax |
groupBy |
string | string[] | no | A field or an array of fields to group by (up to 5). Allowed values are from the list above |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/doc-templates/aggregate" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"aggregate": [
{ "field": "sort", "function": "sum" },
{ "field": "sort", "function": "avg" }
],
"groupBy": "region"
}'
curl — OAuth app
curl -X POST "https://vibecode.bitrix24.com/v1/doc-templates/aggregate" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"aggregate": [
{ "field": "sort", "function": "sum" },
{ "field": "sort", "function": "avg" }
],
"groupBy": "region"
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/doc-templates/aggregate', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
aggregate: [
{ field: 'sort', function: 'sum' },
{ field: 'sort', function: 'avg' },
],
groupBy: 'region',
}),
})
const { success, data } = await res.json()
console.log('Total templates:', data.count)
console.log('By region:', data.groups)
JavaScript — OAuth app
const res = await fetch('https://vibecode.bitrix24.com/v1/doc-templates/aggregate', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
aggregate: [
{ field: 'sort', function: 'sum' },
{ field: 'sort', function: 'avg' },
],
groupBy: 'region',
}),
})
const { success, data } = await res.json()
To group by several fields, pass an array:
"groupBy": ["region", "active"](up to 5).
Other scenarios
Record count — count with the field "*", the fastest request without loading templates. Without the aggregate array the result is the same:
{ "aggregate": [{ "field": "*", "function": "count" }] }
Breakdown by two fields at once — how many templates fall into each combination of region and active flag:
{ "groupBy": ["region", "active"] }
Number of templates in a single region — count with a filter, records are not loaded:
{ "filter": { "region": "ru" } }
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.count |
number | Total number of templates matching the filter |
data.aggregates |
object | Numeric aggregation results: { "sort": { "sum": 1650, "avg": 275 } }. An empty object when the aggregate array is not passed |
data.groups |
array | Groups, present only with groupBy. Each item: grouping fields + count + aggregates |
data.meta.totalRecords |
number | Total number of records matching the filter |
data.meta.recordsProcessed |
number | How many records were processed for numeric aggregations. Equals 0 for a request without numeric functions — records are not loaded |
data.meta.truncated |
boolean | true if more than 5000 records matched the filter |
data.meta.groupTotal |
number | Number of groups, present only with groupBy |
data.meta.groupsTruncated |
boolean | true if there were more groups than the output limit. Present only with groupBy |
Response example
Response to the main request (sum and avg over sort with groupBy: "region"):
{
"success": true,
"data": {
"count": 6,
"aggregates": {
"sort": { "sum": 1650, "avg": 275 }
},
"groups": [
{
"region": "ru",
"count": 3,
"aggregates": { "sort": { "sum": 600, "avg": 200 } }
},
{
"region": "by",
"count": 2,
"aggregates": { "sort": { "sum": 900, "avg": 450 } }
},
{
"region": "kz",
"count": 1,
"aggregates": { "sort": { "sum": 150, "avg": 150 } }
}
],
"meta": {
"totalRecords": 6,
"recordsProcessed": 6,
"truncated": false,
"groupTotal": 3,
"groupsTruncated": false
}
}
}
Without groupBy the fields data.groups, data.meta.groupTotal and data.meta.groupsTruncated are absent from the response.
Error response example
400 — a non-existent field. The message lists the available fields:
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "Field 'bogus' not found. Available numeric fields: sort, numeratorId, fileId, region, moduleId, active."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
Invalid function name or a non-existent field — the message lists the available fields |
| 400 | INVALID_PARAMS |
A string field (region, moduleId, active) in sum/avg/min/max — the message names the field type |
| 400 | INVALID_PARAMS |
groupBy by a field outside the list, a reserved word (count, aggregates, meta, groups), or more than 5 fields in groupBy |
| 403 | SCOPE_DENIED |
The API key lacks the documentgenerator scope |
| 401 | TOKEN_MISSING |
The API key has no configured tokens |
For the full list of common API errors, see Errors.
Notes
count vs numeric functions. count is computed with a single call to Bitrix24 for any data volume, without loading records, and meta.recordsProcessed equals 0. The sum/avg/min/max functions load records page by page (up to 5000) and compute on the Vibecode side — if more than 5000 records match the filter, meta.truncated becomes true and the aggregation runs over the first 5000. For exact counts on large selections, use count or narrow the filter.
Numeric aggregation is over a single field. Only sort yields a meaningful sum or average. The numeratorId and fileId fields are numeric too and are accepted in sum/avg/min/max, but they are identifiers — aggregate them for grouping, not for summation. The remaining fields are strings and work only in groupBy.