## Пакетные операции

`POST /v1/recurring-deals/batch`

Выполняет несколько операций одного типа над настройками регулярных сделок.

## Параметры

Параметров пути нет. Данные пакета передаются в теле запроса.

## Поля запроса (body)

| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| `action` | string | да | Операция для всего пакета: `create`, `update`, `delete`, `list`, `get` или `fields` |
| `items` | object[] | нет | Обязателен для `create` и `update`. Непустой массив объектов с полями [создания](./create.md) или [изменения](./update.md) |
| `items[].id` | number / string | нет | Обязателен для `update`. ID настройки из [списка регулярных сделок](./list.md) |
| `ids` | array | нет | Обязателен для `delete`. Непустой массив ID настроек из [списка регулярных сделок](./list.md) |
| `calls` | object[] | нет | Обязателен для `list`, `get` и `fields`. Непустой массив подзапросов |
| `calls[].params` | object | нет | Параметры подзапроса. Для `list` — [параметры списка](./list.md), для `get` — ID настройки, для `fields` можно передать `{}` |
| `calls[].params.id` | number / string | нет | Обязателен для `get`. ID настройки из [списка регулярных сделок](./list.md) |

Размер пакета ограничен настройками платформы. По умолчанию — до 500 элементов для `create`, `update`, `delete` и до 50 подзапросов для `list`, `get`, `fields`.

В пакетах записи `null` не передаётся для `active`, `startDate`, `categoryId`, `limitRepeat`, `limitDate` и вложенных полей `params`. Для явной передачи `null` используйте [создание одной настройки](./create.md) или [изменение одной настройки](./update.md).

## Примеры

### curl — личный ключ

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/recurring-deals/batch" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"update","items":[{"id":11,"active":false}]}'
```

### curl — OAuth-приложение

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/recurring-deals/batch" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"update","items":[{"id":11,"active":false}]}'
```

### JavaScript — личный ключ

```javascript
const response = await fetch('https://vibecode.bitrix24.tech/v1/recurring-deals/batch', {
  method: 'POST',
  headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({"action":"update","items":[{"id":11,"active":false}]}),
})
const result = await response.json()
if (!result.success) throw new Error(result.error.message)
console.log(result.data)
```

### JavaScript — OAuth-приложение

```javascript
const response = await fetch('https://vibecode.bitrix24.tech/v1/recurring-deals/batch', {
  method: 'POST',
  headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({"action":"update","items":[{"id":11,"active":false}]}),
})
const result = await response.json()
if (!result.success) throw new Error(result.error.message)
console.log(result.data)
```

## Поля ответа

### Создание, изменение и удаление

| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| `success` | boolean | да | `true`, если пакет обработан. Результат каждого элемента проверяйте отдельно |
| `data` | object | да | Результаты пакета |
| `data.results` | object[] | да | Результаты в порядке элементов запроса |
| `data.results[].index` | number | да | Индекс элемента в исходном массиве, начиная с нуля |
| `data.results[].success` | boolean | да | Успешна ли операция над этим элементом |
| `data.results[].id` | number / string | нет | ID созданной настройки или исходный ID при изменении и удалении. Получить настройку: [по ID](./get.md) |
| `data.results[].error` | string | нет | Код отказа элемента. Может быть пустой строкой, поэтому проверяйте `success` |
| `data.results[].message` | string | нет | Сообщение об отказе элемента |
| `data.summary` | object | да | Сводка по пакету |
| `data.summary.total` | number | да | Количество обработанных элементов |
| `data.summary.succeeded` | number | да | Количество успешных операций |
| `data.summary.failed` | number | да | Количество операций с отказом |

Ошибка отдельной операции возвращается в `data.results`, а HTTP-статус пакета остаётся `200`.

### Чтение

| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| `success` | boolean | да | `true`, если пакет обработан |
| `data` | object[] | да | Результаты в порядке подзапросов |
| `data[].data` | object / array / null | нет | Успешный результат: для `list` — массив настроек, для `get` — настройка или `null`, для `fields` — карта метаданных полей. Поля настройки: [Поля регулярной сделки](./fields.md) |
| `data[].total` | number | нет | Общее количество записей для `list` |
| `data[].hasMore` | boolean | нет | Есть ли следующая страница для `list` |
| `data[].meta` | object | нет | Предупреждения списка |
| `data[].error` | object | нет | Отказ отдельного подзапроса вместо `data` |
| `data[].error.code` | string | нет | Код отказа подзапроса |
| `data[].error.message` | string | нет | Сообщение об отказе подзапроса |

Для `fields` ключи карты сохраняют исходные имена полей Битрикс24, например `ID` и `DEAL_ID`. Для `list` и `get` поля настроек имеют имена API Вайбкод.

Отказ одного подзапроса чтения не останавливает остальные. HTTP-статус пакета остаётся `200`.

## Пример ответа

200 — настройка из примера изменена:

```json
{
  "success": true,
  "data": {
    "results": [
      {
        "index": 0,
        "success": true,
        "id": 11
      }
    ],
    "summary": {
      "total": 1,
      "succeeded": 1,
      "failed": 0
    }
  }
}
```

Для чтения структура другая. Тело запроса: `{"action":"list","calls":[{"params":{"filter":{"id":11},"select":["id","active"]}}]}`.

```json
{
  "success": true,
  "data": [
    {
      "data": [
        {
          "id": 11,
          "active": false
        }
      ],
      "total": 1,
      "hasMore": false
    }
  ]
}
```

## Пример ответа при ошибке

400 — передана неизвестная операция:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_BATCH_ACTION",
    "message": "Action must be one of: create, update, delete, list, get, fields"
  }
}
```

## Ошибки

Таблица описывает отказы всего запроса. Отказы отдельных операций находятся в результатах пакета.

Пакет записи выполняется без отката. При общем отказе после отправки команд, например `502 BITRIX_UNAVAILABLE` или `503 BITRIX_TIMEOUT`, часть операций могла уже выполниться, а результат других может быть неизвестен. Накопленные результаты успешных операций в такой ответ не попадают. Перед повтором проверьте состояние записей: повторное создание может привести к дубликатам.

| HTTP | Код | Описание |
|---|---|---|
| 400 | `INVALID_BATCH_ACTION` | Отсутствует `action` или передана неизвестная операция |
| 400 | `BATCH_ITEM_VALIDATION` | Нет непустого массива для выбранной операции, обязательного поля элемента, либо элемент содержит некорректное значение или поле только для чтения |
| 400 | `BATCH_LIMIT_EXCEEDED` | Превышен размер пакета. Текущий предел указан в `error.message` |
| 403 | `MANAGEMENT_KEY_NO_ENTITY_ACCESS` | Ключ управления не имеет доступа к данным сущностей |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ прошёл проверку скоупа, но его режим запрещает `create`, `update` или `delete` |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `TOKEN_MISSING` | Нет настроенных токенов доступа к Битрикс24 |
| 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `crm` |
| 403 | `BITRIX_ACCESS_DENIED` | Битрикс24 отказал в доступе ко всему пакету |
| 422 | `BITRIX_ERROR` | Бизнес-отказ Битрикс24 на уровне всего пакета. Причина — в `error.message` |
| 503 | `BITRIX_TIMEOUT` | Битрикс24 не ответил вовремя |
| 502 | `BITRIX_UNAVAILABLE` | Сетевой сбой или ошибка сервера Битрикс24 с HTTP-статусом 500 и выше |
| 429 | `RATE_LIMITED` | Превышен лимит запросов. Срок ожидания — в заголовке `Retry-After` |

Полный список общих ошибок API — [Коды ошибок](/docs/errors).

## Смотрите также

- [Создать настройку](./create.md)
- [Обновить настройку](./update.md)
- [Удалить настройку](./delete.md)
- [Регулярные сделки](../recurring-deals.md)
- [Batch](/docs/batch)
- [MCP для AI](/docs/mcp)
- [Сделки](../deals.md)
