Как выгрузить список объектов Битрикс24 в 1С

Scope: crm

Кто может выполнять методы: пользователь с правом на чтение объектов CRM

Выберите инструмент для разработки с AI-агентом:

  • используйте Битрикс24 Вайбкод, чтобы создать приложение для Битрикс24 по описанию задачи без знания языков программирования. Агент напишет код и разместит приложение на сервере без ручной настройки хостинга
  • используйте MCP-сервер, чтобы разрабатывать интеграцию через REST API в своем проекте. Агент будет обращаться к официальной REST-документации

Списочные методы REST API возвращают не более 50 элементов за один вызов. Чтобы загрузить в 1С весь справочник компаний или все сделки за период, запросы выполняют постранично.

В туториале разберем три способа и то, когда какой применять:

  1. Обычная навигация через поля next и start — для небольших выборок и разовых операций
  2. Выборка по идентификатору с параметром start = -1 — основной способ для полной выгрузки
  3. Пакетные запросы методом batch — до 50 вызовов в одном HTTP-запросе

Перед началом

Для выполнения примеров нужны:

Как использовать примеры в документации

1. Получаем одну страницу

Вызовем метод crm.company.list и посмотрим, что приходит в ответе.

Параметры = Новый Структура;
Параметры.Вставить("select", СтрРазделить("ID,TITLE,ORIGIN_ID,DATE_MODIFY", ","));
Параметры.Вставить("order", Новый Структура("ID", "ASC"));

Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("crm.company.list", Параметры);

Если НЕ Ответ.Успешно Тогда
	ВызватьИсключение "Не удалось получить список компаний: " + Ответ.ОписаниеОшибки;
КонецЕсли;

Для Каждого Компания Из Ответ.Результат Цикл
	
	// Даты приходят строкой ISO 8601 — приводим к часовому поясу базы
	ДатаИзменения = ИнтеграцияБитрикс24.ДатаИзОтвета(Компания.Получить("DATE_MODIFY"));
	
	Сообщить(СтрШаблон("%1 %2 (изменена %3)",
		Компания.Получить("ID"),
		Компания.Получить("TITLE"),
		Формат(ДатаИзменения, "ДЛФ=DT")));
	
КонецЦикла;

// Полный ответ содержит служебные ключи навигации
Всего = Ответ.Ответ.Получить("total");
Следующая = Ответ.Ответ.Получить("next");

Ответ метода:

{
    "result": [
        {
            "ID": "145",
            "TITLE": "ООО Альфа",
            "ORIGIN_ID": null,
            "DATE_MODIFY": "2026-06-22T16:43:01+03:00"
        }
    ],
    "total": 103,
    "next": 50,
    "time": {
        "start": 1787312593,
        "finish": 1787312593.758879,
        "duration": 0.7588789463043213,
        "processing": 0,
        "date_start": "2026-08-21T14:43:13+03:00",
        "date_finish": "2026-08-21T14:43:13+03:00",
        "operating_reset_at": 1787313091,
        "operating": 0.1701810359954834
    }
}
  • total — общее количество элементов по фильтру
  • next — значение, которое нужно передать в параметре start для следующей страницы. Когда страница последняя, ключа next в ответе нет

Простой цикл по страницам выглядит так:

Начало = 0;

Пока Истина Цикл
	
	Параметры = Новый Структура;
	Параметры.Вставить("select", СтрРазделить("ID,TITLE", ","));
	Параметры.Вставить("order", Новый Структура("ID", "ASC"));
	Параметры.Вставить("start", Начало);
	
	Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("crm.company.list", Параметры);
	
	Если НЕ Ответ.Успешно Тогда
		ВызватьИсключение Ответ.ОписаниеОшибки;
	КонецЕсли;
	
	// Обработайте элементы страницы
	
	Следующая = Ответ.Ответ.Получить("next");
	Если Следующая = Неопределено Тогда
		Прервать;
	КонецЕсли;
	
	Начало = Следующая;
	
КонецЦикла;

Такой цикл подходит для сотен элементов. На больших справочниках он работает медленно: при start >= 0 Битрикс24 на каждой странице пересчитывает общее количество элементов для поля total. Для полной выгрузки используйте способ из следующего раздела.

2. Выгружаем все элементы

Быстрый способ — фильтровать по последнему полученному идентификатору и передавать start = -1. Так Битрикс24 не считает общее количество, а выборка каждый раз начинается с нужного места. Подробное сравнение — на странице Как получить большие объемы данных.

Порядок такой:

  1. отсортировать элементы по идентификатору по возрастанию
  2. добавить в фильтр условие >ID со значением последнего полученного идентификатора
  3. передать start = -1
  4. повторять, пока метод возвращает 50 элементов
&НаСервере
Функция ЗагрузитьКомпании()
	
	Компании = Новый Массив;
	ПоследнийИдентификатор = 0;
	
	Пока Истина Цикл
		
		// Ключ фильтра начинается с символа >, поэтому используем соответствие, а не структуру
		Фильтр = Новый Соответствие;
		Фильтр.Вставить(">ID", ПоследнийИдентификатор);
		
		Параметры = Новый Структура;
		Параметры.Вставить("filter", Фильтр);
		Параметры.Вставить("order", Новый Структура("ID", "ASC"));
		Параметры.Вставить("select", СтрРазделить("ID,TITLE,ORIGIN_ID,DATE_MODIFY", ","));
		Параметры.Вставить("start", -1);
		
		Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("crm.company.list", Параметры);
		
		Если НЕ Ответ.Успешно Тогда
			ВызватьИсключение СтрШаблон("Ошибка выгрузки компаний: %1 %2",
				Ответ.КодОшибки, Ответ.ОписаниеОшибки);
		КонецЕсли;
		
		Страница = Ответ.Результат;
		
		Если Страница.Количество() = 0 Тогда
			Прервать;
		КонецЕсли;
		
		Для Каждого Компания Из Страница Цикл
			Компании.Добавить(Компания);
			ПоследнийИдентификатор = ИнтеграцияБитрикс24.ИдентификаторИзОтвета(Компания.Получить("ID"));
		КонецЦикла;
		
		Если Страница.Количество() < 50 Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Компании;
	
КонецФункции

При start = -1 в ответе приходит "total": 0 и нет ключа next — это ожидаемо, признак конца выборки здесь другой: страница вернула меньше 50 элементов.

Если нужны только изменения с прошлого обмена, добавьте в фильтр дату: >DATE_MODIFY со значением последней успешной синхронизации в формате ISO 8601. Условия в фильтре объединяются по И, поэтому фильтр по идентификатору и по дате работают вместе.

3. Ускоряем выгрузку методом batch

Метод batch выполняет до 50 вызовов за один HTTP-запрос. Для выгрузки это дает до 2500 элементов на запрос вместо 50.

Подзапросы передают в параметре cmd строками вида метод?параметр=значение. Соберем такую строку из параметров 1С — функция обходит структуры, соответствия и массивы и кодирует значения.

// Собирает строку запроса вида filter[>ID]=100&select[0]=ID&select[1]=TITLE
Функция ПараметрыВСтрокуЗапроса(Параметры, Префикс = "") Экспорт
	
	Если ТипЗнч(Параметры) = Тип("Структура") ИЛИ ТипЗнч(Параметры) = Тип("Соответствие") Тогда
		
		Части = Новый Массив;
		Для Каждого КлючИЗначение Из Параметры Цикл
			ИмяПараметра = ?(ПустаяСтрока(Префикс),
				КлючИЗначение.Ключ,
				Префикс + "[" + КлючИЗначение.Ключ + "]");
			Части.Добавить(ПараметрыВСтрокуЗапроса(КлючИЗначение.Значение, ИмяПараметра));
		КонецЦикла;
		Возврат СтрСоединить(Части, "&");
		
	ИначеЕсли ТипЗнч(Параметры) = Тип("Массив") Тогда
		
		Части = Новый Массив;
		Для Индекс = 0 По Параметры.Количество() - 1 Цикл
			ИмяПараметра = Префикс + "[" + Строка(Индекс) + "]";
			Части.Добавить(ПараметрыВСтрокуЗапроса(Параметры[Индекс], ИмяПараметра));
		КонецЦикла;
		Возврат СтрСоединить(Части, "&");
		
	КонецЕсли;
	
	Возврат Префикс + "=" + КодироватьСтроку(ЗначениеВСтрокуЗапроса(Параметры),
		СпособКодированияСтроки.КодировкаURL);
	
КонецФункции

Функция ЗначениеВСтрокуЗапроса(Значение)
	
	Если ТипЗнч(Значение) = Тип("Булево") Тогда
		Возврат ?(Значение, "1", "0");
	ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда
		// ЧРД — точка вместо запятой в дробной части, ЧН — иначе ноль станет пустой строкой
		Возврат Формат(Значение, "ЧГ=0; ЧРД=.; ЧН=0");
	ИначеЕсли ТипЗнч(Значение) = Тип("Дата") Тогда
		Возврат Формат(Значение, "ДФ=yyyy-MM-dd") + "T" + Формат(Значение, "ДФ=HH:mm:ss");
	КонецЕсли;
	
	Возврат Строка(Значение);
	
КонецФункции

Кодируйте значения подзапросов функцией КодироватьСтроку. Символы &, =, %, # внутри значения без кодирования разорвут строку запроса, и подзапрос выполнится с неверными параметрами. Название компании Иванов & партнеры без кодирования превратится в фильтр Иванов и лишний параметр.

Теперь соберем пакет из страниц одного метода. Каждая команда запрашивает свою страницу через start, поэтому команды не зависят друг от друга.

&НаСервере
Функция ЗагрузитьКомпанииПакетом(КоличествоСтраниц = 50)
	
	Команды = Новый Соответствие;
	
	Для Индекс = 0 По КоличествоСтраниц - 1 Цикл
		
		ПараметрыСтраницы = Новый Структура;
		ПараметрыСтраницы.Вставить("order", Новый Структура("ID", "ASC"));
		ПараметрыСтраницы.Вставить("select", СтрРазделить("ID,TITLE,DATE_MODIFY", ","));
		ПараметрыСтраницы.Вставить("start", Индекс * 50);
		
		Команды.Вставить("page" + Строка(Индекс),
			"crm.company.list?" + ПараметрыВСтрокуЗапроса(ПараметрыСтраницы));
		
	КонецЦикла;
	
	Параметры = Новый Структура;
	Параметры.Вставить("halt", 0);
	Параметры.Вставить("cmd", Команды);
	
	Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("batch", Параметры);
	
	Если НЕ Ответ.Успешно Тогда
		ВызватьИсключение Ответ.ОписаниеОшибки;
	КонецЕсли;
	
	Компании = Новый Массив;
	РезультатыКоманд = Ответ.Результат.Получить("result");
	ОшибкиКоманд = Ответ.Результат.Получить("result_error");
	
	Для Индекс = 0 По КоличествоСтраниц - 1 Цикл
		
		ИмяКоманды = "page" + Строка(Индекс);
		
		Если ТипЗнч(ОшибкиКоманд) = Тип("Соответствие") И ОшибкиКоманд.Получить(ИмяКоманды) <> Неопределено Тогда
			Ошибка = ОшибкиКоманд.Получить(ИмяКоманды);
			ЗаписьЖурналаРегистрации("Битрикс24.REST", УровеньЖурналаРегистрации.Ошибка, , ,
				ИмяКоманды + ": " + Строка(Ошибка.Получить("error_description")));
			Продолжить;
		КонецЕсли;
		
		Страница = РезультатыКоманд.Получить(ИмяКоманды);
		
		Если Страница = Неопределено Или Страница.Количество() = 0 Тогда
			Прервать;
		КонецЕсли;
		
		Для Каждого Компания Из Страница Цикл
			Компании.Добавить(Компания);
		КонецЦикла;
		
	КонецЦикла;
	
	Возврат Компании;
	
КонецФункции

Ответ пакета устроен так:

{
    "result": {
        "result": {
            "page0": [ { "ID": "145", "TITLE": "ООО Альфа" } ],
            "page1": [ { "ID": "407", "TITLE": "ООО Бета" } ]
        },
        "result_error": [],
        "result_total": {
            "page0": 103,
            "page1": 103
        },
        "result_next": {
            "page0": 50,
            "page1": 100
        },
        "result_time": {
            "page0": { "start": 1787312593, "duration": 0.75 }
        }
    }
}
  • result — результаты подзапросов по именам команд
  • result_error — ошибки подзапросов. Пакет с halt = 0 выполняет остальные команды, даже если одна вернула ошибку. Пустое значение приходит как массив [], поэтому проверяйте тип перед обращением по ключу
  • result_total и result_next — навигация по каждому подзапросу

В один пакет входит не более 50 подзапросов, вложенные вызовы batch запрещены. Подзапросы выполняются последовательно, поэтому пакет из 50 тяжелых списочных методов может не уложиться в лимит 60 секунд на один запрос. Если пакет завершается по таймауту, уменьшите количество команд.

4. Учитываем лимиты

Битрикс24 ограничивает интенсивность запросов: на большинстве тарифов устойчивая скорость — 2 запроса в секунду, на тарифе Энтерпрайз — 5. При превышении метод возвращает ошибку QUERY_LIMIT_EXCEEDED с кодом состояния 503.

Что это значит для обмена с 1С:

  • Запускайте выгрузку в фоновом или регламентном задании. Пользовательский сеанс не должен ждать, пока отработают сотни запросов
  • Ставьте паузу между запросами. Функция ВыполнитьМетод из общего модуля повторяет запрос при ошибке 503, но лучше не доводить до нее: при массовой выгрузке достаточно паузы в 500 миллисекунд между вызовами
  • Не превышайте 60 секунд на один запрос. Ограничение действует и на batch: время всех подзапросов суммируется
  • Следите за ключом operating в ответе. Он показывает накопленное время выполнения метода. Когда значение превышает лимит, следующий вызов этого метода вернет ошибку OPERATION_TIME_LIMIT с кодом состояния 429
// Пауза между запросами при массовой выгрузке.
// Метод ВызватьПаузу доступен начиная с версии платформы 8.3.25.
ВызватьПаузу(500);

Подробно об ограничениях — на странице Лимиты REST API.

Ошибки и диагностика

Если метод вернул ошибку, проверьте данные запроса.

Ошибка

Причина и решение

QUERY_LIMIT_EXCEEDED со статусом 503

Превышена интенсивность запросов. Уменьшите частоту вызовов и повторяйте запрос с увеличивающейся паузой — так работает функция ВыполнитьМетод из общего модуля

OPERATION_TIME_LIMIT со статусом 429

Накопленное время выполнения метода превысило лимит. Приостановите вызовы этого метода и для первой повторной попытки ориентируйтесь на operating_reset_at из последнего успешного ответа

ERROR_BATCH_LENGTH_EXCEEDED

В пакет передано больше 50 подзапросов. Разбейте выгрузку на порции

ERROR_BATCH_METHOD_NOT_ALLOWED

Внутри batch вызван метод загрузки или скачивания файла либо вложенный batch. Такие вызовы выполняйте отдельными запросами

ERROR_METHOD_NOT_FOUND со статусом 404

Метода не существует или у вебхука нет нужного scope. Проверьте имя метода и права вебхука

В ответе нет ключа next, хотя элементы не кончились

Запрос выполнен с start = -1 — в этом режиме навигации нет. Признак конца выборки здесь другой: страница вернула меньше 50 элементов

Продолжите изучение