## Per-line aggregates for a period

> ⚠️ **The method ships in update `imopenlines 26.700.0` and is not yet available on all Bitrix24 portals.** If the update has not reached your portal yet, the API returns `422 METHOD_NOT_YET_AVAILABLE` — this means the method has not been released on the portal yet, not that the integration is broken.

`POST /v1/openlines/stats`

Summary metrics of Open Channels for a period — session counters, average times, CSAT, and breakdowns by channel, hour, and operator. The main method for top-level dashboard widgets. Heavy: request it no more than once every 30–60 seconds and cache the result.

## Request fields (body)

| Field | Type | Req. | Description |
|------|-----|:-----:|---------|
| `dateFrom` | string | yes | Period start, ISO 8601. The `dateFrom`..`dateTo` period must not exceed 1 year |
| `dateTo` | string | yes | Period end, ISO 8601 |
| `configId` | number | no | Line identifier. Source: [`GET /v1/openline-configs`](/docs/openlines/config/list) |
| `configIdList` | number[] | no | List of line identifiers |
| `source` | string | no | Channel code (connector id), for example `livechat` |
| `sourceList` | string[] | no | List of channel codes |
| `operatorId` | number | no | Operator identifier. Source: [`GET /v1/users`](/docs/entities/users) |
| `operatorIdList` | number[] | no | List of operator identifiers |

If none of `configId*`/`source*`/`operatorId*` is set, aggregates are computed over all lines available to the current user.

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/openlines/stats" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "dateFrom": "2026-06-01T00:00:00+00:00",
    "dateTo": "2026-06-30T23:59:59+00:00",
    "configId": 3
  }'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/openlines/stats" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "dateFrom": "2026-06-01T00:00:00+00:00",
    "dateTo": "2026-06-30T23:59:59+00:00",
    "configId": 3
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/openlines/stats', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    dateFrom: '2026-06-01T00:00:00+00:00',
    dateTo: '2026-06-30T23:59:59+00:00',
    configId: 3,
  }),
})
const { data } = await res.json()
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/openlines/stats', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    dateFrom: '2026-06-01T00:00:00+00:00',
    dateTo: '2026-06-30T23:59:59+00:00',
    configId: 3,
  }),
})
const { data } = await res.json()
```

## Response fields

The response is `{ "success": true, "data": {...} }`. When there is no data for the period, all numeric metrics are returned as `0` (or `0.0`), never as `null`.

| Key | Description |
|---|---|
| `totalSessions` / `closedSessions` / `spamSessions` | Session counters for the period |
| `avgWaitAnswer` / `avgSessionDuration` | Average figures, seconds |
| `likeCount` / `dislikeCount` / `votedSessions` / `positiveRate` | CSAT: the customer rating is a like/dislike, `positiveRate` is the share of likes |
| `kpiFirstAnswerOk` / `kpiFirstAnswerFail` | Counters for the first-answer SLA |
| `sessionsBySource` | Breakdown by channel, `[{ source, count }]` |
| `sessionsByHour` | Exactly 24 entries (hours 0–23, the portal server time zone) |
| `sessionsByOperator` | Breakdown by operator, `[{ operatorId, count, avgWaitAnswer, positiveRate }]` |

## Response example

```json
{
  "success": true,
  "data": {
    "totalSessions": 340,
    "closedSessions": 318,
    "spamSessions": 4,
    "avgWaitAnswer": 42.7,
    "avgSessionDuration": 612.3,
    "likeCount": 210,
    "dislikeCount": 15,
    "votedSessions": 225,
    "positiveRate": 0.9333,
    "kpiFirstAnswerOk": 300,
    "kpiFirstAnswerFail": 18,
    "sessionsBySource": [
      { "source": "livechat", "count": 200 },
      { "source": "whatsapp", "count": 140 }
    ],
    "sessionsByHour": [0,0,0,0,0,0,2,10,25,40,38,30,28,22,20,25,30,20,15,10,8,5,3,1],
    "sessionsByOperator": [
      { "operatorId": 42, "count": 120, "avgWaitAnswer": 38.1, "positiveRate": 0.95 },
      { "operatorId": 51, "count": 90, "avgWaitAnswer": 51.4, "positiveRate": 0.88 }
    ]
  }
}
```

## Error response example

`400` — the period is missing:

```json
{
  "success": false,
  "error": { "code": "MISSING_PARAMS", "message": "Required: dateFrom, dateTo (ISO 8601 strings)" }
}
```

## Errors

| HTTP | Code | When |
|---|---|---|
| 403 | `B24_TARIFF_RESTRICTION` | The tariff does not include Open Channels statistics (`report_open_lines`) |
| 400 | `MISSING_PARAMS` | `dateFrom` and/or `dateTo` are missing |
| 422 | `BITRIX_ERROR` (`error.b24Code: PERIOD_REQUIRED`) | Bitrix24 did not recognize the period |
| 422 | `BITRIX_ERROR` (`error.b24Code: INVALID_FILTER`) | An invalid filter value or date format |
| 422 | `BITRIX_ERROR` (`error.b24Code: PERIOD_TOO_LARGE`) | The period exceeds 1 year |
| 422 | `METHOD_NOT_YET_AVAILABLE` | The `imopenlines 26.700.0` update has not reached the portal yet |

The full list of system codes — [API errors](/docs/errors).

## See also

- [Operators (real-time)](/docs/openlines/operators)
- [Session list](/docs/openlines/sessions)
- [Open Channels statistics](/docs/openlines)
