For AI agents: markdown of this page — /docs-content-en/entities/recurring-deals/aggregate.md documentation index — /llms.txt
Aggregate
POST /v1/recurring-deals/aggregate
Counts deal recurrence settings and computes numeric aggregates using a filter. Use it to analyse execution counts and repetition limits.
Standard fields
| Field | Purpose |
|---|---|
FieldcounterRepeat |
PurposeExecution count. Meaningful for sum, avg, min, max |
FieldlimitRepeat |
PurposeRepetition count limit. Meaningful for numeric functions |
Fieldid, dealId, basedId, categoryId |
PurposeIdentifiers. Accepted by numeric functions, their sum does not describe execution counts |
Standard fields are unavailable for groupBy: recurring deals can be grouped only by UF fields. A request with a standard field returns INVALID_PARAMS with an empty list of available fields.
Custom fields (UF)
The method accepts UF fields of types integer, double, money for numeric functions, and any UF type for groupBy and filtering. Names use UF_CRM_* or ufCrm_*. For an unknown numeric UF field, INVALID_PARAMS lists available numeric fields. To use a UF field, configure it in your Bitrix24 account.
Request body fields
| Field | Type | Required | Description |
|---|---|---|---|
Fieldaggregate |
Typeobject[] | RequiredNo | DescriptionUp to 5 expressions. Default: count over * |
Fieldaggregate[].field |
Typestring | RequiredYes | DescriptionExpression field: * for count, a numeric field for sum, avg, min, max |
Fieldaggregate[].function |
Typestring | RequiredYes | DescriptionFunction: count, sum, avg, min, max |
Fieldfilter |
Typeobject | RequiredNo | DescriptionConditions using the filter syntax |
FieldgroupBy |
Typestring / string[] | RequiredNo | DescriptionUp to 5 fields. Only UF fields that exist in the Bitrix24 account: standard fields cannot be used for grouping |
FieldgroupOrderBy |
Typeobject[] | RequiredNo | DescriptionGroup sorting. Only with groupBy |
FieldgroupOrderBy[].field |
Typestring | RequiredYes | DescriptionA grouping key, count, or a requested result such as counterRepeat:sum |
FieldgroupOrderBy[].direction |
Typestring | RequiredNo | DescriptionDirection: asc or desc. Default: desc |
FieldgroupLimit |
Typenumber | RequiredNo | DescriptionWith groupBy: an integer from 1 to 1000 |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/recurring-deals/aggregate" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"aggregate":[{"field":"counterRepeat","function":"sum"},{"field":"counterRepeat","function":"avg"}],"filter":{"active":true}}'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/recurring-deals/aggregate" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"aggregate":[{"field":"counterRepeat","function":"sum"},{"field":"counterRepeat","function":"avg"}],"filter":{"active":true}}'
JavaScript — personal key
const response = await fetch('https://vibecode.bitrix24.com/v1/recurring-deals/aggregate', {
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({"aggregate":[{"field":"counterRepeat","function":"sum"},{"field":"counterRepeat","function":"avg"}],"filter":{"active":true}}),
})
const result = await response.json()
if (!result.success) throw new Error(result.error.message)
console.log(result.data)
JavaScript — OAuth application
const response = await fetch('https://vibecode.bitrix24.com/v1/recurring-deals/aggregate', {
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({"aggregate":[{"field":"counterRepeat","function":"sum"},{"field":"counterRepeat","function":"avg"}],"filter":{"active":true}}),
})
const result = await response.json()
if (!result.success) throw new Error(result.error.message)
console.log(result.data)
For a groupBy array, supply up to 5 existing UF field names.
Other scenarios
The blocks below are request bodies.
Count all settings:
{}
Count with a filter:
{
"filter": {
"id": 1
},
"aggregate": [
{
"field": "*",
"function": "count"
}
]
}
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionWhether the request succeeded |
Fielddata |
Typeobject | DescriptionThe aggregation result. Its fields are the data.* rows below |
Fielddata.count |
Typenumber | DescriptionTotal matching records |
Fielddata.aggregates |
Typeobject | DescriptionResults by field and function |
Fielddata.aggregates.<field>.truncated |
Typeboolean | DescriptionIncomplete calculation marker, when set |
Fielddata.groups |
Typeobject[] | DescriptionGroups, only with groupBy |
Fielddata.groups[].count |
Typenumber | DescriptionRead records in a group |
Fielddata.groups[].aggregates |
Typeobject | DescriptionGroup results by field and function |
Fielddata.groups[].truncated |
Typeboolean | DescriptionIncomplete group marker, when set |
Fielddata.meta.totalRecords |
Typenumber | DescriptionTotal matching records |
Fielddata.meta.recordsProcessed |
Typenumber | DescriptionNumber of records read, an optional field |
Fielddata.meta.truncated |
Typeboolean | DescriptionWhether the calculation uses an incomplete selection |
Fielddata.meta.recordsShortfall |
Typenumber | DescriptionMissing records: totalRecords - recordsProcessed. Also returned at the 5000-record cap |
Fielddata.meta.pageErrorSample |
Typeobject | DescriptionSample subpage error when reading is interrupted |
Fielddata.meta.warnings |
Typeobject[] | DescriptionContains AGGREGATE_TRUNCATED for an incomplete selection |
Fielddata.meta.groupTotal |
Typenumber | DescriptionNumber of groups before the groupLimit cap |
Fielddata.meta.groupsTruncated |
Typeboolean | DescriptionWhether the group list was limited by groupLimit |
Response example
{
"success": true,
"data": {
"count": 2,
"aggregates": {
"counterRepeat": {
"sum": 699,
"avg": 349.5
}
},
"meta": {
"totalRecords": 2,
"recordsProcessed": 2,
"truncated": false
}
}
}
Without groupBy, data.groups is absent from the response.
Error response example
400 — unknown numeric aggregation field:
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "Field 'UF_CRM_NOT_REAL' not found. Available numeric fields: id, dealId, basedId, counterRepeat, categoryId, limitRepeat."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_PARAMS |
Descriptionaggregate is not an array or the array is empty |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe aggregate array contains more than 5 expressions |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionAn unknown or missing function. Allowed: count, sum, avg, min, max |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe field for count is not * |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionA numeric function has no field or uses * |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionA standard field does not have type number |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionA UF field has a non-numeric type. The message names the UF type |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe field was not found. The message lists available standard and custom numeric fields |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionSeparate op, field or function values are supplied without an aggregate array |
| HTTP400 | CodeINVALID_PARAMS |
DescriptiongroupBy is not a string or an array of strings |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe groupBy array contains more than 5 fields |
| HTTP400 | CodeINVALID_PARAMS |
DescriptiongroupBy contains a standard field: recurring deals cannot be grouped by standard fields |
| HTTP400 | CodeINVALID_PARAMS |
DescriptiongroupBy uses a reserved name: count, aggregates, meta or groups |
| HTTP400 | CodeINVALID_PARAMS |
DescriptiongroupOrderBy is supplied without groupBy |
| HTTP400 | CodeINVALID_PARAMS |
DescriptiongroupLimit is supplied without groupBy |
| HTTP400 | CodeINVALID_PARAMS |
DescriptiongroupOrderBy is not an array |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionA groupOrderBy entry is not an object with a non-empty field string |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe groupOrderBy direction is neither asc nor desc |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionA sort key in <field>:<function> format is not requested in aggregate |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionA group sort field is not a groupBy key, count or a numeric result key |
| HTTP400 | CodeINVALID_PARAMS |
DescriptiongroupLimit is not an integer from 1 to 1000 |
| HTTP400 | CodeUNKNOWN_FILTER_FIELD |
DescriptionThe filter references an unknown field. See the error message and field definitions |
| HTTP400 | CodeINVALID_FILTER_FIELD |
DescriptionA field name starts with the unsupported prefix @ or !@ |
| HTTP400 | CodeINVALID_FILTER_OPERATOR |
DescriptionAn unknown operator, an empty condition object, or a logical condition using $or or $and |
| HTTP400 | CodeINVALID_DUPLICATE_FILTER_FIELD |
DescriptionTwo conditions map to the same filter condition. Supply only one |
| HTTP400 | CodeINVALID_FILTER_SHAPE |
Descriptionfilter is not an object |
| HTTP422 | CodeAGGREGATION_LIMIT_EXCEEDED |
DescriptionThe numeric or grouped selection exceeds 5000 records and rejection before reading records is enabled |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionNo Bitrix24 access tokens are configured |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe API key lacks the crm scope |
| HTTP403 | CodeBITRIX_ACCESS_DENIED |
DescriptionBitrix24 denied access, including a missing required scope |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionBitrix24 rejected the operation or a plan restriction applies. See error.message |
| HTTP503 | CodeBITRIX_TIMEOUT |
DescriptionBitrix24 did not respond in time. Retry after the interval in Retry-After |
| HTTP502 | CodeBITRIX_UNAVAILABLE |
DescriptionA connection to Bitrix24 could not be established |
| HTTP429 | CodeRATE_LIMITED |
DescriptionThe request rate limit was exceeded. The effective limit is in the x-ratelimit-limit header. Retry after the interval in the Retry-After header |
For the full list of common API errors, see Error codes.
Known specifics
Without groupBy and without numeric functions, the method returns a count without reading records: recordsProcessed: 0, truncated: false. A count request with groupBy requires records to be read. Numeric functions use the records read, up to 5000. Narrow the filter for an exact result.
data.meta.truncated becomes true if fewer records were read than the reported total, or a subpage error interrupted reading. A shortfall can occur below the 5000-record cap. The response always includes recordsShortfall or pageErrorSample in this case, and field and group results are marked as truncated.