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

Aggregate order properties

POST /v1/order-properties/aggregate

Counts order properties by filter and grouping fields, and calculates the sum, average, minimum, and maximum of numeric fields.

Standard fields

Field Purpose
personTypeId Payer type ID from GET /v1/person-types. For groupBy
type Property type — for groupBy
required Whether the field is required when placing an order — for groupBy
active Active flag — for groupBy
sort Sort order — for sum, avg, min, max
inputFieldLocation Deprecated field. Bitrix24 does not use it — a numeric field
id Property ID from list order properties. A numeric field
propsGroupId Group ID from a property with the same payer type in list order properties. A numeric field

Fields for groupBy are listed in data.aggregatable of GET /v1/order-properties/fields. Numeric functions accept fields of type number from the same schema: id, personTypeId, propsGroupId, sort, inputFieldLocation.

Request body fields

Field Type Required Description
aggregate array no An array of expressions such as { "field": "sort", "function": "sum" }, with 1 to 5 expressions. Functions: count, sum, avg, min, max. For count, the field is "*". When omitted, defaults to [{ "field": "*", "function": "count" }]
filter object no Filter by fields from GET /v1/order-properties/fields.
Filtering syntax. Example: { "id": 125 }
groupBy string | string[] no A grouping field or an array of up to 5 fields. Allowed fields: personTypeId, type, required, active
groupOrderBy array no Sort groups: [{ "field": "count", "direction": "desc" }]. field accepts count, a field from groupBy, or <field>:<function> from aggregate. Directions: asc, desc. If direction is omitted, defaults to desc. Requires groupBy
groupLimit number no Number of returned groups: an integer from 1 to 1000. When omitted, groups are not limited. Requires groupBy

Examples

curl — personal key

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

curl — OAuth application

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

JavaScript — personal key

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

const { data } = await res.json()
console.log('Properties by type and active status:', data.groups)

JavaScript — OAuth application

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

const { data } = await res.json()

Other scenarios

The blocks below are request bodies.

Count properties matching the filter without grouping or numeric functions — records are not downloaded:

JSON
{ "filter": { "id": 125 } }

Sum the sort order with grouping when the filter matches no records:

JSON
{
  "filter": { "id": 125, "code": "ABSENT_DELIVERY_COMMENT" },
  "aggregate": [{ "field": "sort", "function": "sum" }],
  "groupBy": ["type", "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 properties matching the filter
data.aggregates object Numeric results by field and function, such as { "sort": { "sum": 500 } }. Empty for count alone
data.aggregates.<field>.truncated boolean Present as true when numeric results were calculated from an incomplete set of records
data.groups array Present with groupBy. Each group contains grouping field values, count, and aggregates. personTypeId is a number, type is a string, and required and active are boolean
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 Present as true for an incomplete set of records. The group's count and calculations cover the 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 when fewer records were read than the reported total, including due to the 5000-record cap, or when reading stopped on a subpage error. false for a complete response. Always false without grouping or numeric functions
data.meta.recordsShortfall number Number of unread records: totalRecords - recordsProcessed. Present when records are missing, including at the 5000-record cap
data.meta.pageErrorSample object A sample subpage error. Present when reading stopped on an error
data.meta.warnings array Contains a warning with code AGGREGATE_TRUNCATED for an incomplete set of records
data.meta.groupTotal number Present with groupBy: the number of groups before groupLimit is applied
data.meta.groupsTruncated boolean Present with groupBy. true when groupLimit limits the returned groups

Response example

JSON
{
  "success": true,
  "data": {
    "count": 1,
    "aggregates": {
      "sort": {
        "sum": 500
      }
    },
    "groups": [
      {
        "type": "STRING",
        "active": false,
        "count": 1,
        "aggregates": {
          "sort": {
            "sum": 500
          }
        }
      }
    ],
    "meta": {
      "totalRecords": 1,
      "recordsProcessed": 1,
      "truncated": false,
      "groupTotal": 1,
      "groupsTruncated": false
    }
  }
}

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 aggregate is not an array or is empty
400 INVALID_PARAMS aggregate contains more than 5 expressions
400 INVALID_PARAMS The function is unknown or missing
400 INVALID_PARAMS The field for count is not "*"
400 INVALID_PARAMS The field for sum, avg, min, or max is missing or is "*"
400 INVALID_PARAMS A nonnumeric field such as name or defaultValue was passed to a numeric function
400 INVALID_PARAMS The numeric function field was not found. The message lists allowed fields: id, personTypeId, propsGroupId, sort, inputFieldLocation
400 INVALID_PARAMS op, field, or function was passed at the top level without the aggregate array
400 INVALID_PARAMS groupBy is not a string or an array of strings, or the array contains a value of another type
400 INVALID_PARAMS The grouping field is not one of personTypeId, type, required, active
400 INVALID_PARAMS groupBy has more than 5 fields
400 INVALID_PARAMS groupBy contains a reserved name: count, aggregates, meta, groups
400 INVALID_PARAMS groupOrderBy was passed without groupBy
400 INVALID_PARAMS groupLimit was passed without groupBy
400 INVALID_PARAMS groupOrderBy is not an array
400 INVALID_PARAMS A groupOrderBy item is not an object with a nonempty string field
400 INVALID_PARAMS groupOrderBy.direction is neither asc nor desc
400 INVALID_PARAMS The <field>:<function> key in groupOrderBy.field is absent from the numeric aggregate expressions
400 INVALID_PARAMS groupOrderBy.field is not count, a field from groupBy, or a numeric aggregate expression key
400 INVALID_PARAMS groupLimit is not an integer from 1 to 1000
400 UNKNOWN_FILTER_FIELD Unknown field in filter
400 INVALID_FILTER_FIELD A field name in filter starts with the unsupported prefix @ or !@
400 INVALID_FILTER_OPERATOR Unsupported operator, an empty condition object, or $or / $and logical conditions
400 INVALID_FILTER_SHAPE filter is not an object of conditions, for example a string, number, or array
400 INVALID_DUPLICATE_FILTER_FIELD Two filter conditions resolve to the same condition, for example $ne and $nin for one field
422 AGGREGATION_LIMIT_EXCEEDED When the cap is enforced for the portal, more than 5000 records match the filter and the request requires numeric calculations or grouping. Records are not downloaded. Narrow the filter
422 BITRIX_ERROR The key's user does not have permission in Bitrix24. The Bitrix24 code is in error.b24Code: 200040300010
403 BITRIX_ACCESS_DENIED The portal credentials do not have the sale scope (insufficient_scope)
422 BITRIX_ERROR A business error with the Bitrix24 message
503 BITRIX_TIMEOUT Bitrix24 did not respond in time. Retry after the interval in Retry-After
502 BITRIX_UNAVAILABLE Bitrix24 could not be reached
403 SCOPE_DENIED The API key lacks the sale scope
401 MISSING_API_KEY The X-Api-Key header is missing
401 TOKEN_MISSING No tokens are configured for the API key
429 RATE_LIMITED The 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.

See also