Как выполнить пакет запросов batch
Выберите инструмент для разработки с AI-агентом:
- используйте Битрикс24 Вайбкод, чтобы создать приложение для Битрикс24 по описанию задачи без знания языков программирования. Агент напишет код и разместит приложение на сервере без ручной настройки хостинга
- используйте MCP-сервер, чтобы разрабатывать интеграцию через REST API в своем проекте. Агент будет обращаться к официальной REST-документации
Scope:
базовыйКто может выполнять метод: любой пользователь
Метод batch выполняет за одно обращение к серверу несколько запросов к REST API — независимых или связанных, когда результат одного запроса передается в следующий.
Когда использовать batch
Метод подходит для двух задач:
- несколько независимых вызовов за один запрос — когда нужно выполнить группу методов, результаты которых не зависят друг от друга. Один пакет вместо нескольких отдельных обращений снижает количество запросов к серверу
- связанные вызовы с передачей данных — когда результат одного метода нужно подставить в параметры следующего. Запросы выполняются последовательно, поэтому данные предыдущего вызова доступны в последующих
Учитывайте ограничения:
- в один пакет входит не более 50 подзапросов
- вложенность запрещена: внутри
batchнельзя вызывать другойbatch
Параметры метода
Обязательные параметры отмечены *
|
Название |
Описание |
|
cmd* |
Массив подзапросов. Ключ элемента — идентификатор подзапроса, значение — вызываемый метод с параметрами в виде строки |
|
halt |
Определяет, прерывать ли последовательность запросов в случае ошибки. Принимает булевы значения |
Данные подзапросов кодируют по-разному в зависимости от способа передачи пакета. В теле POST-запроса в формате JSON, как в примерах ниже, значения cmd передают обычными строками без дополнительного кодирования. Если пакет передают в query-параметрах URL, данные подзапросов url-кодируют, и, поскольку весь пакет сам становится значением параметра, они проходят двойное кодирование.
Примечание
Количество запросов в пакете ограничено 50. При превышении подзапросы сверх лимита завершаются ошибкой ERROR_BATCH_LENGTH_EXCEEDED.
Массив запросов может быть с числовыми ключами или ассоциативным. В параметрах каждого последующего запроса можно использовать данные предыдущих запросов в таком виде:
$result[идентификатор_запроса][поле_ответа]
где идентификатором запроса служит его ключ в массиве запросов.
С версии rest 24.0.0 для метода batch запрещена вложенность: при вызове метода batch нельзя вызывать внутри другой batch. Такой подзапрос завершается ошибкой ERROR_BATCH_METHOD_NOT_ALLOWED.
Примеры кода
Как использовать примеры в документации
Независимые вызовы
Пакет из нескольких разных методов, результаты которых не зависят друг от друга. Каждый подзапрос выполняется отдельно, данные между ними не передаются.
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"halt": 0,
"cmd": {
"get_user": "user.current",
"get_departments": "department.get",
"get_app": "app.info"
}
}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/batch
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"halt": 0,
"cmd": {
"get_user": "user.current",
"get_departments": "department.get",
"get_app": "app.info"
},
"auth":"**put_access_token_here**"
}' \
https://**put_your_bitrix24_address**/rest/batch
// This snippet is an ES module: top-level await requires type="module" or a bundler.
// $b24 is an already-initialized SDK instance (see the SDK "Get started" guide).
import { Text } from '@bitrix24/b24jssdk'
import type { B24Frame } from '@bitrix24/b24jssdk'
declare const $b24: B24Frame
try {
// Named commands: each key becomes the identifier of its subrequest
const response = await $b24.actions.v2.batch.make({
calls: {
get_user: { method: 'user.current', params: {} },
get_departments: { method: 'department.get', params: {} },
get_app: { method: 'app.info', params: {} }
},
options: {
isHaltOnError: false, // analog of halt = 0: run every subrequest
returnAjaxResult: true, // wrap each subrequest result in an AjaxResult
requestId: Text.getUuidRfc4122()
}
})
// isSuccess reflects the batch call as a whole
if (!response.isSuccess) {
console.error(response.getErrorMessages().join('; '))
} else {
// getData() returns an object keyed by the command names above
const result = response.getData()
console.info(result.get_user.getData()?.result)
console.info(result.get_departments.getData()?.result)
console.info(result.get_app.getData()?.result)
}
} catch (error) {
// Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
console.error(error)
}
<!-- Load the SDK (UMD build); it is exposed as the global B24Js -->
<script src="https://unpkg.com/@bitrix24/b24jssdk@1/dist/umd/index.min.js"></script>
<script>
async function runBatch() {
try {
// Initialize the SDK inside a Bitrix24 frame
const $b24 = await B24Js.initializeB24Frame()
// Named commands: each key becomes the identifier of its subrequest
const response = await $b24.actions.v2.batch.make({
calls: {
get_user: { method: 'user.current', params: {} },
get_departments: { method: 'department.get', params: {} },
get_app: { method: 'app.info', params: {} }
},
options: {
isHaltOnError: false, // analog of halt = 0: run every subrequest
returnAjaxResult: true, // wrap each subrequest result in an AjaxResult
requestId: B24Js.Text.getUuidRfc4122()
}
})
// isSuccess reflects the batch call as a whole
if (!response.isSuccess) {
console.error(response.getErrorMessages().join('; '))
return
}
// getData() returns an object keyed by the command names above
const result = response.getData()
console.info(result.get_user.getData()?.result)
console.info(result.get_departments.getData()?.result)
console.info(result.get_app.getData()?.result)
} catch (error) {
// Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
console.error(error)
}
}
document.addEventListener('DOMContentLoaded', runBatch)
</script>
BX24.callBatch({
get_user: ['user.current', {}],
get_departments: ['department.get', {}],
get_app: ['app.info', {}]
}, function(result) {
console.log('get_user result: ', result.get_user.data());
console.log('get_departments result: ', result.get_departments.data());
console.log('get_app result: ', result.get_app.data());
});
Подробнее о callBatch методе в статье BX24.JS SDK.
$result = \CRest::callBatch(
// Commands
[
'get_user' => [
'method' => 'user.current',
'params' => []
],
'get_departments' => [
'method' => 'department.get',
'params' => []
],
'get_app' => [
'method' => 'app.info',
'params' => []
],
],
// Halt
false
);
echo "<pre>";
var_dump($result);
echo "</pre>";
Связанные вызовы
Подзапросы выполняются последовательно, поэтому результат предыдущего запроса можно подставить в параметры следующего через конструкцию $result[идентификатор_запроса][поле_ответа]. В примере ниже метод department.get получает идентификатор подразделения из результата user.current.
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"halt": 0,
"cmd": {
"get_user": "user.current",
"get_department": "department.get?ID=$result[get_user][UF_DEPARTMENT][0]"
}
}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/batch
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"halt": 0,
"cmd": {
"get_user": "user.current",
"get_department": "department.get?ID=$result[get_user][UF_DEPARTMENT][0]"
},
"auth":"**put_access_token_here**"
}' \
https://**put_your_bitrix24_address**/rest/batch
BX24.callBatch({
get_user: ['user.current', {}],
get_department: {
method: 'department.get',
params: {
ID: '$result[get_user][UF_DEPARTMENT][0]'
}
}
}, function(result) {
console.log('Raw result: ', result);
console.log('get_user result: ', result.get_user.data());
console.log('get_department result: ', result.get_department.data());
});
Подробнее о callBatch методе в статье BX24.JS SDK.
$result = \CRest::callBatch(
// Commands
[
'get_user' => [
'method' => 'user.current',
'params' => []
],
'get_department' => [
'method' => 'department.get',
'params' => [
"ID" => '$result[get_user][UF_DEPARTMENT][0]'
]
],
],
// Halt
false
);
echo "<pre>";
var_dump($result);
echo "</pre>";
Примечание
Если промежуточный метод списочный, он возвращает массив записей, поэтому при обращении к результату указывайте индекс нужной записи. Например, в конструкции $result[user_by_name][0][ID] для метода user.search берется идентификатор первого найденного пользователя.
Обработка ответа
HTTP-статус: 200
{
"result": {
"result": {
"get_user": {
"ID": "1",
"ACTIVE": true,
"NAME": "John",
"LAST_NAME": "Doe",
"EMAIL": "my@example.com",
"LAST_LOGIN": "2024-08-29T10:29:54+03:00",
"DATE_REGISTER": "2023-08-24T03:00:00+03:00",
"IS_ONLINE": "Y",
"TIMESTAMP_X": "24.08.2023 13:19:39",
"LAST_ACTIVITY_DATE": "2024-08-29 10:30:11",
"PERSONAL_GENDER": "",
"PERSONAL_BIRTHDAY": "",
"UF_EMPLOYMENT_DATE": "",
"UF_DEPARTMENT": [
1
]
},
"get_department": [
{
"ID": "1",
"NAME": "DEMO",
"SORT": 500
}
]
},
"result_error": [],
"result_total": {
"get_department": 1
},
"result_next": [],
"result_time": {
"get_user": {
"start": 1724916859.46156,
"finish": 1724916859.464775,
"duration": 0.0032150745391845703,
"processing": 0.003075838088989258,
"date_start": "2024-08-29T10:34:19+03:00",
"date_finish": "2024-08-29T10:34:19+03:00"
},
"get_department": {
"start": 1724916859.464944,
"finish": 1724916859.471518,
"duration": 0.006574153900146484,
"processing": 0.005941152572631836,
"date_start": "2024-08-29T10:34:19+03:00",
"date_finish": "2024-08-29T10:34:19+03:00"
}
}
},
"time": {
"start": 1724916859.421475,
"finish": 1724916859.471588,
"duration": 0.05011296272277832,
"processing": 0.010200977325439453,
"date_start": "2024-08-29T10:34:19+03:00",
"date_finish": "2024-08-29T10:34:19+03:00"
}
}
Возвращаемые данные
|
Название |
Описание |
|
result |
Корневой объект ответа с результатами вызова переданных методов (подробное описание) |
|
time |
Информация о времени выполнения запроса в целом |
Объект result
Ключами во всех полях объекта служат идентификаторы подзапросов из массива cmd.
|
Название |
Описание |
|
result |
Результаты успешно выполненных подзапросов. Значение каждого поля содержит данные, которые вернул соответствующий метод |
|
result_error |
Ошибки подзапросов. Значение каждого поля содержит |
|
result_total |
Общее количество записей для списочных методов. Значение каждого поля — число найденных записей соответствующего подзапроса |
|
result_next |
Значение параметра |
|
result_time |
Информация о времени выполнения каждого подзапроса |
Обработка ошибок
Метод batch не возвращает общую ошибку на весь пакет — сам запрос завершается со статусом 200. Результат каждого подзапроса, завершившегося ошибкой, попадает в поле result_error под ключом этого подзапроса. Успешно выполненные подзапросы при этом остаются в поле result.
Поведение при ошибке зависит от параметра halt:
halt = 0— выполняются все подзапросы пакета, ошибки собираются вresult_errorпо каждому проблемному подзапросуhalt = 1— выполнение цепочки прерывается на первом же подзапросе с ошибкой, последующие подзапросы не выполняются
{
"result": {
"result": [],
"result_error": {
"get_user": {
"error": "insufficient_scope",
"error_description": ""
},
"get_department": {
"error": "insufficient_scope",
"error_description": ""
}
},
"result_total": [],
"result_next": [],
"result_time": []
},
"time": {
"start": 1724916638.077564,
"finish": 1724916638.132399,
"duration": 0.05483508110046387,
"processing": 0.0017969608306884766,
"date_start": "2024-08-29T10:30:38+03:00",
"date_finish": "2024-08-29T10:30:38+03:00"
}
}
{
"result": {
"result": [],
"result_error": {
"get_user": {
"error": "insufficient_scope",
"error_description": ""
}
},
"result_total": [],
"result_next": [],
"result_time": []
},
"time": {
"start": 1724916725.460891,
"finish": 1724916725.851307,
"duration": 0.39041590690612793,
"processing": 0.0005991458892822266,
"date_start": "2024-08-29T10:32:05+03:00",
"date_finish": "2024-08-29T10:32:05+03:00"
}
}
Каждый элемент поля result_error содержит информацию об ошибке подзапроса:
|
Название |
Описание |
|
error |
Строковый код ошибки. Может состоять из цифр, латинских букв и знака подчеркивания |
|
error_description |
Текстовое описание ошибки. Описание не предназначено для показа конечному пользователю в необработанном виде |
Возможные коды ошибок
|
Статус |
Код |
Описание |
Значение |
|
|
|
Method is not allowed for batch usage |
Метод нельзя вызывать внутри |
|
|
|
Max batch length exceeded |
В пакет передано больше 50 подзапросов |
При проектировании цепочки команд не пренебрегайте ключом halt — при значении 1 он прервет выполнение цепочки, если один запрос из цепочки вернет ошибку.
Статусы и коды системных ошибок
HTTP-статус: 20x, 40x, 50x
Описанные ниже ошибки могут возникнуть при вызове любого метода
|
Статус |
Код |
Описание |
|
|
|
Возникла внутренняя ошибка сервера, обратитесь к администратору сервера или в техническую поддержку Битрикс24 |
|
|
|
Возникла внутренняя ошибка сервера, обратитесь к администратору сервера или в техническую поддержку Битрикс24 |
|
|
|
Превышен лимит на интенсивность запросов |
|
|
|
Метод заблокирован из-за превышения лимита на ресурсоемкость запросов. Блокировка снимается автоматически через 10 минут |
|
|
|
Текущий метод не разрешен для вызова с помощью batch |
|
|
|
Превышена максимальная длина параметров, переданных в метод batch |
|
|
|
Неверный access-токен или код вебхука |
|
|
|
Для вызовов методов требуется использовать протокол HTTPS |
|
|
|
REST API заблокирован из-за перегрузки. Это ручная индивидуальная блокировка, для снятия необходимо обращаться в техническую поддержку Битрикс24 |
|
|
|
REST API доступен только на коммерческих планах |
|
|
|
У пользователя, с чьим access-токеном или вебхуком был вызван метод, не хватает прав |
|
|
|
Манифест недоступен |
|
|
|
Запрос требует более высоких привилегий, чем предоставляет токен вебхука |
|
|
|
Предоставленный access-токен доступа истек |
|
|
|
Пользователь не имеет доступа к приложению. Это означает, что приложение установлено, но администратор портала разрешил доступ к этому приложению только конкретным пользователям |
|
|
|
Публичная часть сайта закрыта. Чтобы открыть публичную часть сайта на коробочной установке отключите опцию «Временное закрытие публичной части сайта». Путь к настройке: Рабочий стол > Настройки > Настройки продукта > Настройки модулей > Главный модуль > Временное закрытие публичной части сайта |