
## Aggregate Open Channel configurations

`POST /v1/openline-configs/aggregate`

Counts the number of Open Channel configurations with optional grouping by queue type and other schema fields.

**Grouping.** `groupBy` accepts 2 fields: `active`, `queueType` — these are the `aggregatable` fields from [`GET /v1/openline-configs/fields`](/docs/openlines/config/fields). The remaining fields (`id`, `name`, `workTimeFrom`, `workTimeTo`, and other camelCase response fields) are rejected with `400 INVALID_PARAMS` when passed in `groupBy` — details in [Known specifics](#known-specifics).

**Numeric aggregations (`sum`/`avg`/`min`/`max`) do not apply.** Open Channel configuration fields are categorical or identifier fields. Only the `count` function with `field: "*"` is supported.

## Request fields (body)

| Parameter | Type | Required | Description |
|----------|-----|:-----:|---------|
| `aggregate` | array | no | Array of aggregations. Each element: `{ "field": "*", "function": "count" }`. The `count` function requires `field: "*"`. Without the parameter — only `count` |
| `filter` | object | no | Filtering. [Filtering syntax](/docs/filtering). Example: `{"active": false}` |
| `groupBy` | string \| string[] | no | Field or array of fields to group by. Allowed values: `active`, `queueType` — see [Known specifics](#known-specifics) |

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/openline-configs/aggregate" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "groupBy": "queueType"
  }'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/openline-configs/aggregate" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "groupBy": "queueType"
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/openline-configs/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    groupBy: 'queueType',
  }),
})

const { success, data } = await res.json()
console.log('Total configurations:', data.count)
console.log('By queue type:', data.groups)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/openline-configs/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    groupBy: 'queueType',
  }),
})

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

> To group by multiple fields, pass an array: `"groupBy": ["queueType", "active"]`. Combinations of the 2 allowed fields are accepted: `active`, `queueType`.

## Other scenarios

The blocks below are request bodies.

The total number of configurations — the fastest query, without fetching records:

```json
{}
```

Passing `count` explicitly via `aggregate`:

```json
{
  "aggregate": [{ "field": "*", "function": "count" }]
}
```

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data.count` | number | Total number of configurations in the result set (after applying the filter, if it took effect). This is the primary metric for your application |
| `data.aggregates` | object | Numeric-function results grouped by field name. Open Channel configurations have no numeric fields, so the object is always empty |
| `data.groups` | array | Groups (only when `groupBy` is set). Each element: the grouping field + `count` + `aggregates` |
| `data.meta.totalRecords` | number | Total number of configurations — the same number as `data.count` |
| `data.meta.recordsProcessed` | number | How many records were actually processed during grouping. `0` if `groupBy` is not set |
| `data.meta.truncated` | boolean | `true` when the numbers were computed over only some of the records that match the filter: fewer records were read than `data.count` promised — including when more than 5000 matched the filter — or the slice was cut short by a sub-page error. The size of the gap is reported in `data.meta.recordsShortfall`, the interrupted slice in `data.meta.pageErrorSample`. Always present, and `false` on a complete response. If the request has neither `groupBy` nor a numeric function, no records are fetched and the flag is always `false` |
| `data.meta.groupTotal` | number | Number of groups in the result (only when `groupBy` is set) |
| `data.meta.groupsTruncated` | boolean | Whether the group list was truncated (only when `groupBy` is set) |

## Response example

Response to the main query (`groupBy: "queueType"`):

```json
{
  "success": true,
  "data": {
    "count": 10,
    "aggregates": {},
    "groups": [
      { "queueType": "all", "count": 9, "aggregates": {} },
      { "queueType": "evenly", "count": 1, "aggregates": {} }
    ],
    "meta": {
      "totalRecords": 10,
      "recordsProcessed": 10,
      "truncated": false,
      "groupTotal": 2,
      "groupsTruncated": false
    }
  }
}
```

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

## Error response example

400 — the `count` function with an invalid field name:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "count aggregate requires field \"*\""
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | The `count` function was passed with `field` not equal to `"*"`, or `groupBy` referenced a field outside the Vibecode schema |
| 401 | `TOKEN_MISSING` | The API key has no configured tokens |
| 403 | `SCOPE_DENIED` | The API key lacks the `imopenlines` scope |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

**The `filter` parameter is ignored in aggregation.** Passing `{"filter": {"active": false}}` has no effect on the result — the method returns the `count` across all configurations in your Bitrix24 account. To get counts for a subset, use `groupBy` (for example, `groupBy: ["active"]` splits the result by the activity flag) or process the result of [`POST /v1/openline-configs/search`](/docs/openlines/config/search) on the client side.

**The `count` function requires `field: "*"`.** Passing `{"field": "id", "function": "count"}` returns `400 INVALID_PARAMS`. The only correct format: `{"field": "*", "function": "count"}`.

**`groupBy` accepts only 2 fields from the Vibecode schema:** `active`, `queueType`. These are the `aggregatable` fields from the [`GET /v1/openline-configs/fields`](/docs/openlines/config/fields) response. The remaining fields (`id`, `name`, `workTimeFrom`, `workTimeTo`, `queueTime`, `crm`, ...) are rejected with `400 INVALID_PARAMS` when passed in `groupBy`, with the message "groupBy field 'X' is not aggregatable on this entity. Available: active, queueType".

**The truncation marker travels with the number itself.** When a response arrives with `meta.truncated: true`, the marker `truncated: true` sits inside every field object in `data.aggregates` and on every element of `data.groups`, and `data.meta.warnings` gains a warning with the code `AGGREGATE_TRUNCATED`. A client that reads only the number itself therefore sees that it was computed over only some of the records. None of these markers appear on a complete response. Full details — [Aggregation POST — the 5000-record ceiling](/docs/entity-api#aggregation-post-the-5000-record-ceiling).

## See also

- [List configurations](/docs/openlines/config/list)
- [Filtering syntax](/docs/filtering)
- [Limits and optimization](/docs/optimization)
