#Пакетные вызовы
Один HTTP-запрос объединяет до 50 операций над разными сущностями. Каждый вызов идентифицируется собственным id и обрабатывается независимо: ошибка одного вызова не отменяет остальные.
POST /v1/batch
Скоуп: проверяется индивидуально по сущности (crm, task, im, disk и др.) | Базовый URL: https://vibecode.bitrix24.tech/v1 | Авторизация: X-Api-Key (APP-ключ)
#Поля запроса (body)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
calls |
array | ★ | Массив вызовов (от 1 до 50). Каждый элемент — объект, формат описан в таблице ниже. |
#Поля одного вызова
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
id |
string | нет | Идентификатор вызова в ответе. Если не передан — присваивается порядковый индекс ("0", "1", ...). Длина до 64 символов. |
entity |
string | ★ | Имя сущности во множественном числе: deals, contacts, companies, tasks, users, files, folders и другие. Полный список сущностей, доступных вашему ключу, возвращает GET /v1/me — см. Ключи и авторизация. |
action |
string | ★ | Операция: list, get, create, update, delete, fields, search. |
entityId |
number / string | для get / update / delete |
Идентификатор записи. |
params |
object | нет | Параметры операции в едином entity-формате (имена полей в camelCase, фильтры в синтаксисе фильтрации). |
Параметры внутри params совпадают с параметрами одиночного эндпоинта Entity API:
listиsearch—filter,select,order,limitget— полеinclude, если сущность его поддерживаетcreateиupdate— поля сущности (имена вcamelCase)deleteиfields— параметры не нужны- смарт-процессы (
entity: "items") — внутриparamsобязательноentityTypeId
#Примеры
#curl — личный ключ
curl -X POST https://vibecode.bitrix24.tech/v1/batch \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"calls": [
{
"id": "deals",
"entity": "deals",
"action": "list",
"params": {
"filter": { "stageId": "NEW" },
"select": ["id", "title", "amount"],
"limit": 50
}
},
{
"id": "contacts",
"entity": "contacts",
"action": "list",
"params": {
"select": ["id", "name", "lastName"],
"limit": 20
}
},
{
"id": "user1",
"entity": "users",
"action": "get",
"entityId": 1
}
]
}'
#curl — OAuth-приложение
curl -X POST https://vibecode.bitrix24.tech/v1/batch \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"calls": [
{
"id": "deals",
"entity": "deals",
"action": "list",
"params": {
"filter": { "stageId": "NEW" },
"select": ["id", "title", "amount"],
"limit": 50
}
},
{
"id": "contacts",
"entity": "contacts",
"action": "list",
"params": {
"select": ["id", "name", "lastName"],
"limit": 20
}
},
{
"id": "user1",
"entity": "users",
"action": "get",
"entityId": 1
}
]
}'
#JavaScript — личный ключ
const res = await fetch('https://vibecode.bitrix24.tech/v1/batch', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
calls: [
{ id: 'deals', entity: 'deals', action: 'list', params: { filter: { stageId: 'NEW' }, select: ['id', 'title', 'amount'], limit: 50 } },
{ id: 'contacts', entity: 'contacts', action: 'list', params: { select: ['id', 'name', 'lastName'], limit: 20 } },
{ id: 'user1', entity: 'users', action: 'get', entityId: 1 }
]
})
})
const { data } = await res.json()
console.log('Сделки:', data.results.deals)
console.log('Контакты:', data.results.contacts)
console.log('Сводка:', data.summary)
#JavaScript — OAuth-приложение
const res = await fetch('https://vibecode.bitrix24.tech/v1/batch', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
calls: [
{ id: 'deals', entity: 'deals', action: 'list', params: { filter: { stageId: 'NEW' }, select: ['id', 'title', 'amount'], limit: 50 } },
{ id: 'contacts', entity: 'contacts', action: 'list', params: { select: ['id', 'name', 'lastName'], limit: 20 } },
{ id: 'user1', entity: 'users', action: 'get', entityId: 1 }
]
})
})
const { data } = await res.json()
console.log('Сделки:', data.results.deals)
#Поля ответа
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | true, если запрос принят. Частичные ошибки внутри data.errors не переводят его в false. |
data.results |
object | Результаты по id каждого вызова. Значение — то, что вернул бы соответствующий эндпоинт Entity API: массив записей для list / search, объект для get / create, схема полей для fields. |
data.totals |
object | Общее количество записей под фильтр для list / search-вызовов. Ключи — id соответствующих вызовов. |
data.errors |
object | Ошибки по id неудачных вызовов. Каждое значение — { "code": "...", "message": "..." }. |
data.summary.total |
number | Общее количество вызовов в запросе. |
data.summary.succeeded |
number | Количество успешных вызовов. |
data.summary.failed |
number | Количество вызовов с ошибкой. |
data.meta |
object | Дополнительные сведения по id вызовов с action: "list" или action: "search": total, returned, hasMore, truncated. |
#Пример ответа
{
"success": true,
"data": {
"results": {
"deals": [
{ "id": 575, "title": "Тест валюты", "amount": 0 },
{ "id": 741, "title": "Поставка оборудования", "amount": 250000 }
],
"contacts": [
{ "id": 1, "name": "Иван", "lastName": "Петров" }
],
"user1": [
{ "ID": "1", "NAME": "Летта", "ACTIVE": true }
]
},
"totals": {
"deals": 1798,
"contacts": 305
},
"errors": {},
"summary": {
"total": 3,
"succeeded": 3,
"failed": 0
},
"meta": {
"deals": { "total": 1798, "returned": 2, "hasMore": true, "truncated": false },
"contacts": { "total": 305, "returned": 1, "hasMore": true, "truncated": false }
}
}
}
#Частичные ошибки
Если часть вызовов не прошла проверку или вернула ошибку на стороне Битрикс24, успешные результаты остаются в data.results, неудачные — в data.errors под тем же id:
{
"success": true,
"data": {
"results": {
"deals": [
{ "id": 575, "title": "Тест валюты" }
]
},
"totals": {
"deals": 1798
},
"errors": {
"unknown": {
"code": "UNKNOWN_ENTITY",
"message": "Unknown entity \"foobar\". Check GET /v1/guide for available entities."
}
},
"summary": {
"total": 2,
"succeeded": 1,
"failed": 1
},
"meta": {
"deals": { "total": 1798, "returned": 1, "hasMore": true, "truncated": false }
}
}
}
#Пример ответа при ошибке
Если все вызовы не прошли валидацию, возвращается 400 INVALID_REQUEST с разбивкой по id в data.errors:
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "All calls in the batch failed validation"
},
"data": {
"errors": {
"x": {
"code": "MISSING_ENTITY_ID",
"message": "Action \"get\" requires entityId."
}
}
}
}
#Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_REQUEST |
Тело запроса не соответствует схеме или все вызовы провалили валидацию. |
| 400 | UNKNOWN_ENTITY |
В одном из вызовов передано неизвестное имя сущности. |
| 400 | ACTION_NOT_SUPPORTED |
Сущность не поддерживает указанное действие (например, delete для справочной сущности без удаления). |
| 400 | MISSING_ENTITY_ID |
Действия get, update, delete требуют entityId. |
| 400 | MISSING_DYNAMIC_PARAM |
Для смарт-процессов (entity: "items") не передан entityTypeId внутри params. |
| 400 | INVALID_DYNAMIC_PARAM |
entityTypeId для смарт-процессов задан некорректно (не положительное целое). |
| 400 | USE_DEDICATED_ENTITY |
Для переданного entityTypeId существует выделенная сущность — использовать её, а не items. |
| 400 | ENTITY_CUSTOM_ROUTES |
Сущность работает только через специализированные маршруты (например, task-comments — через /v1/tasks/:taskId/comments). |
| 400 | INVALID_CALL |
Объект вызова не содержит обязательных полей entity и action. |
| 401 | TOKEN_MISSING |
У ключа нет настроенных OAuth-токенов или для OAuth-приложения не передан Authorization: Bearer .... |
| 401 | TOKEN_REFRESH_FAILED |
Не удалось обновить OAuth-токен портала. |
| 403 | MANAGEMENT_KEY_NO_ENTITY_ACCESS |
Запрос пришёл с management-ключа — пакетные вызовы доступны только APP-ключам. |
| 403 | SCOPE_NOT_ALLOWED |
Все вызовы запросили скоупы, которых нет у ключа. Если хотя бы один вызов проходит — этот код возвращается внутри data.errors для конкретных вызовов, а сам запрос успешен. |
| 422 | BITRIX_ERROR |
Битрикс24 отклонил вызов. Тело ответа содержит bitrixError.error и bitrixError.error_description. |
| 502 | BITRIX_UNAVAILABLE |
Битрикс24 ответил с ошибкой 5xx. |
| 503 | QUEUE_OVERFLOW |
На портале накопилось слишком много одновременных вызовов Битрикс24 (по умолчанию более 100 в ожидании). Ответ возвращается мгновенно с HTTP-заголовком Retry-After: N (секунды) — клиент должен дождаться его и повторить с экспоненциальным backoff + jitter. Тело: error.code = QUEUE_OVERFLOW, error.retryAfter дублирует заголовок. |
| 504 | QUEUE_TIMEOUT |
Запрос ожидал в очереди портала более 30 секунд. Ответ содержит userMessage и hint. |
| 500 | INTERNAL_ERROR |
Внутренняя ошибка прокси. |
Полный список общих ошибок API — Коды ошибок.
#Известные особенности
search и list с limit > 50 обходят нативный пакетный вызов Битрикс24. Эти вызовы выполняются как отдельные последовательные запросы со страничной выборкой до 5000 записей — каждый потребляет свою квоту rate-limit Битрикс24 независимо. Остальные вызовы — list с limit ≤ 50, get, create, update, delete, fields — объединяются в один пакетный вызов на стороне Битрикс24 и стоят одну единицу rate-limit суммарно.
Стоимость list в единицах rate-limit Битрикс24. Каждые 50 записей = 1 единица. При limit > 50 авто-пагинатор делает несколько вызовов:
limit |
Единиц Битрикс24 |
|---|---|
| 1–50 | 1 (нативный batch) |
| 51–2 550 | 2 |
| 2 551–5 000 | 3 |
Если действие в одном вызове провалилось, остальные продолжают выполняться. Ошибки попадают в data.errors под тем же id, успешные результаты — в data.results. Поле success остаётся true, проверять нужно data.summary.failed или присутствие нужного id в data.results.
users.get возвращает массив, а не объект. Это особенность Entity API: ответ get для пользователей — [ { ID, NAME, ... } ]. Первый элемент — искомая запись.
Пакетные изменения для одной сущности. Если нужно создать, обновить или удалить много записей одной сущности (до 500 штук), используется специализированный эндпоинт POST /v1/{entity}/batch с телом { "action": "create" | "update" | "delete", "items" | "ids": [...] }. Он выполняет операции внутренними пакетами по 50 записей и возвращает массив результатов с пометкой success для каждого элемента.
#Смотрите также
- Лимиты и оптимизация — авто-пагинация, пакетные вызовы, агрегация
- Синтаксис фильтрации — как описывать
params.filter - Entity API — справочник сущностей и одиночных эндпоинтов
- Ключи и авторизация — типы ключей, скоупы, самоописание через
GET /v1/me - Коды ошибок — общий справочник