For AI agents: markdown of this page — /docs-content-en/entities/person-types/aggregate.md documentation index — /llms.txt

Aggregate payer types

POST /v1/person-types/aggregate

Counts payer types with filtering and grouping by activity or code, and calculates the sum, average, minimum, and maximum of numeric fields.

Standard fields

Field Purpose
active Activity flag for groupBy
code Unique code for groupBy
sort Sort order: a numeric field for sum, avg, min, max
id Payer type ID from List payer types. A numeric field for sum, avg, min, max

Fields for groupBy are listed in data.aggregatable of GET /v1/person-types/fields. Numeric functions accept fields with the number type from the same schema: id and sort.

Request body fields

Field Type Required Description
aggregate array no An array of 1 to 5 expressions such as { "field": "sort", "function": "sum" }. Functions: count, sum, avg, min, max. For count, the field is "*". Defaults to [{ "field": "*", "function": "count" }]
filter object no Filter by fields from GET /v1/person-types/fields.
Filtering syntax. Example: { "id": 21 }
groupBy string | string[] no A field or array of up to 5 grouping fields. Allowed fields: active, code
groupOrderBy array no Group sorting: [{ "field": "count", "direction": "desc" }]. The field is count, a field from groupBy, or <field>:<function> from aggregate. Directions: asc, desc. Defaults to desc when direction is omitted. Requires groupBy
groupLimit number no Number of groups to return: an integer from 1 to 1000. If omitted, groups are not truncated. Requires groupBy

Examples

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/person-types/aggregate" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "id": 21 },
    "aggregate": [{ "field": "*", "function": "count" }],
    "groupBy": ["active", "code"],
    "groupOrderBy": [{ "field": "count", "direction": "desc" }],
    "groupLimit": 10
  }'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/person-types/aggregate" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "id": 21 },
    "aggregate": [{ "field": "*", "function": "count" }],
    "groupBy": ["active", "code"],
    "groupOrderBy": [{ "field": "count", "direction": "desc" }],
    "groupLimit": 10
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/person-types/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { id: 21 },
    aggregate: [{ field: '*', function: 'count' }],
    groupBy: ['active', 'code'],
    groupOrderBy: [{ field: 'count', direction: 'desc' }],
    groupLimit: 10,
  }),
})

const { data } = await res.json()
console.log('Payer type counts by activity and code:', data.groups)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/person-types/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { id: 21 },
    aggregate: [{ field: '*', function: 'count' }],
    groupBy: ['active', 'code'],
    groupOrderBy: [{ field: 'count', direction: 'desc' }],
    groupLimit: 10,
  }),
})

const { data } = await res.json()

Other scenarios

The blocks below are request bodies.

Count types matching the filter without grouping or numeric functions. Records are not fetched:

JSON
{ "filter": { "id": 21 } }

Sum, average, minimum, and maximum sort order:

JSON
{
  "filter": { "id": 21 },
  "aggregate": [
    { "field": "*", "function": "count" },
    { "field": "sort", "function": "sum" },
    { "field": "sort", "function": "avg" },
    { "field": "sort", "function": "min" },
    { "field": "sort", "function": "max" }
  ]
}

Sum of sort order grouped by activity when the filter matches no records:

JSON
{
  "filter": { "id": 21, "code": "ABSENT_DOCS_PERSON_397F55D8FB1D" },
  "aggregate": [{ "field": "sort", "function": "sum" }],
  "groupBy": "active"
}

For the last request, data.count and the sum are 0, and data.groups is an empty array.

Response fields

Field Type Description
success boolean Always true on success
data.count number Total number of types matching the filter
data.aggregates object Numeric results by field and function, for example { "sort": { "sum": 900 } }. An empty object when only count is used
data.aggregates.<field>.truncated boolean Included as true when numeric results are calculated from an incomplete set of records
data.groups array Included with groupBy. Each group contains grouping field values, count, and aggregates. The active value is a boolean; the code value is a string or null
data.groups[].count number Number of processed records in the group
data.groups[].aggregates object Numeric results within the group, in the same format as data.aggregates
data.groups[].truncated boolean Included as true for an incomplete set of records. Group counts and calculations apply to processed records
data.meta.totalRecords number Total number of records matching the filter
data.meta.recordsProcessed number Number of processed records, up to 5000. 0 without grouping or numeric functions
data.meta.truncated boolean true if fewer records were read than the total count, including because of the 5000-record ceiling, or a subpage error stopped the read. false for a complete response. Always false without grouping or numeric functions
data.meta.recordsShortfall number Number of unread records: totalRecords - recordsProcessed. Included when there is a shortfall, including one caused by the 5000-record ceiling
data.meta.pageErrorSample object A sample subpage error. Included when an error stopped the read
data.meta.warnings array Contains a warning with the code AGGREGATE_TRUNCATED for an incomplete set of records
data.meta.groupTotal number Included with groupBy: the number of groups before applying groupLimit
data.meta.groupsTruncated boolean Included with groupBy. true if groups were truncated by groupLimit

Response example

JSON
{
  "success": true,
  "data": {
    "count": 1,
    "aggregates": {},
    "groups": [
      {
        "active": false,
        "code": "DOCS_PERSON_397F55D8FB1D",
        "count": 1,
        "aggregates": {}
      }
    ],
    "meta": {
      "totalRecords": 1,
      "recordsProcessed": 1,
      "truncated": false,
      "groupTotal": 1,
      "groupsTruncated": false
    }
  }
}

Without groupBy, the response omits data.groups.

Error response example

400 — the string field name was passed to the numeric function sum:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Field 'name' is not numeric (type: string). Only number fields support sum."
  }
}

Errors

HTTP Code Description
400 INVALID_PARAMS The aggregate is not an array or is an empty array
400 INVALID_PARAMS The aggregate contains more than 5 expressions
400 INVALID_PARAMS The function is unknown or missing
400 INVALID_PARAMS The field for count differs from "*"
400 INVALID_PARAMS The field for sum, avg, min, or max is missing or is "*"
400 INVALID_PARAMS A numeric function received a non-numeric field, such as name
400 INVALID_PARAMS The numeric function field was not found. The message lists the allowed fields: id, sort
400 INVALID_PARAMS The op, field, or function was provided at the root without an aggregate array
400 INVALID_PARAMS The groupBy is neither a string nor an array of strings, or the array contains a value of another type
400 INVALID_PARAMS The grouping field is neither active nor code
400 INVALID_PARAMS The groupBy contains more than 5 fields
400 INVALID_PARAMS The groupBy contains a reserved name: count, aggregates, meta, or groups
400 INVALID_PARAMS The groupOrderBy was provided without groupBy
400 INVALID_PARAMS The groupOrderBy is not an array, an item has no string field, the field is absent from grouping or aggregate expressions, or direction is neither asc nor desc
400 INVALID_PARAMS The groupLimit was provided without groupBy
400 INVALID_PARAMS The groupLimit is not an integer from 1 to 1000
400 UNKNOWN_FILTER_FIELD An unknown field in filter
400 INVALID_FILTER_FIELD A field name in filter starts with the unsupported prefix @ or !@
400 INVALID_FILTER_OPERATOR An unsupported operator, an empty condition object, or logical conditions with $or / $and
400 INVALID_FILTER_SHAPE The filter is not a condition object, such as a string, number, or array
400 INVALID_DUPLICATE_FILTER_FIELD Two filter conditions resolve to the same condition, such as $ne and $nin for one field
422 AGGREGATION_LIMIT_EXCEEDED With the limit enabled for the account, more than 5000 records match the filter and the request requires numeric calculations or grouping. No records are fetched. Narrow the filter
403 SCOPE_DENIED The API key lacks the sale scope
401 MISSING_API_KEY The X-Api-Key header is missing
401 TOKEN_MISSING The API key has no configured tokens
429 RATE_LIMITED Request limit exceeded: 300 per minute per portal, shared by all API keys for the portal. The exact value is in the x-ratelimit-limit header. Retry after the delay in the Retry-After header

For the full list of common API errors, see Error codes.

Known specifics

A request without grouping or numeric functions counts records without fetching them. Numeric calculations and any grouping, including grouping with only count, are subject to a 5000-record limit. If the account is configured to reject requests above this limit and more records match the filter, the request returns 422 AGGREGATION_LIMIT_EXCEEDED without fetching them. Otherwise, records are read page by page, up to 5000. For an exact count over a large set, use a request without grouping or numeric functions. Narrow the filter to calculate over the entire set. See Aggregation POST — the 5000-record ceiling.

See also