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

Terminal
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

Terminal
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

javascript
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

javascript
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:

JSON
{}

Count with a filter:

JSON
{
  "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

JSON
{
  "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:

JSON
{
  "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.

See also