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

Aggregate activities

POST /v1/activities/aggregate

Count activities with filtering and grouping.

Standard fields:

  • typeId — activity type (for groupBy)
  • ownerTypeId — parent entity type (for groupBy)
  • responsibleId — responsible person (for groupBy)
  • completed — completion status (for groupBy)

All fields in aggregatable are categorical identifiers, so the main scenario is count with grouping. The numeric functions sum/avg/min/max are rarely used.

Request fields (body)

Parameter Type Required Description
aggregate array no Array of aggregations. Each element: { "field": "*", "function": "count" }. Without the array — count only
filter object no Filter by GET /v1/activities/fields fields. Filter syntax
groupBy string | string[] no Field or array of fields to group by (maximum 5). Allowed values — from the list above

Examples

curl — personal key

Number of activities for a deal (ownerTypeId: 2 — deal), grouped by activity type:

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/activities/aggregate" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "ownerTypeId": 2, "ownerId": 741, "completed": "Y" },
    "groupBy": "typeId"
  }'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/activities/aggregate" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "ownerTypeId": 2, "ownerId": 741, "completed": "Y" },
    "groupBy": "typeId"
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/activities/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { ownerTypeId: 2, ownerId: 741, completed: 'Y' },
    groupBy: 'typeId',
  }),
})

const { success, data } = await res.json()
console.log('Total completed activities for the deal:', data.count)
console.log('Distribution by type:', data.groups)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/activities/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { ownerTypeId: 2, ownerId: 741, completed: 'Y' },
    groupBy: 'typeId',
  }),
})

const { success, data } = await res.json()

To group by several fields, pass an array: "groupBy": ["typeId", "completed"] (maximum 5).

Other scenarios

Total number of activities in the Bitrix24 account — the fastest query, no record retrieval:

JSON
{}

Group activities by contact (ownerTypeId: 3) by completion status:

JSON
{
  "filter": { "ownerTypeId": 3, "ownerId": 485 },
  "groupBy": "completed"
}

Response fields

Field Type Description
success boolean Always true on success
data.count number Total number of records matching the filter
data.aggregates object Aggregation results (usually empty for activities)
data.groups array Groups (only with groupBy). Each element: grouping fields + count
data.meta.totalRecords number Total number of records matching the filter
data.meta.recordsProcessed number How many records were processed (for count0, records are not retrieved)
data.meta.truncated boolean true if more than 5000 records matched the filter

Response example

Response to the main query (groupBy: "typeId"):

JSON
{
  "success": true,
  "data": {
    "count": 2600,
    "aggregates": {},
    "groups": [
      { "typeId": 1, "count": 1200 },
      { "typeId": 2, "count": 800 },
      { "typeId": 6, "count": 600 }
    ],
    "meta": {
      "totalRecords": 2600,
      "recordsProcessed": 2600,
      "truncated": false
    }
  }
}

Without groupBy, the data.groups field is absent from the response.

Error response example

400 — groupBy on a non-aggregatable field or a non-existent field:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "groupBy field 'subject' is not aggregatable on this entity. Available: typeId, ownerTypeId, responsibleId, completed"
  }
}

Errors

HTTP Code Description
400 INVALID_PARAMS groupBy on a non-aggregatable field or more than 5 fields in groupBy
401 TOKEN_MISSING The API key has no configured tokens
403 SCOPE_DENIED The API key lacks the crm scope

Full list of common API errors — Errors.

Known specifics

Universal ownerTypeId. For counters by parent entity, use the ownerTypeId + ownerId pairs: 2 — deal, 3 — contact, 4 — company, 1 — lead. This is the most common scenario for /v1/activities/aggregate.

See also