Когда выгрузка не помещается в один синхронный ответ — сотни тысяч товаров или тяжёлый отчёт остатков — МойСклад предлагает асинхронный режим. Запрос с параметром async=true ставит задачу в очередь, возвращает ссылку на её статус, а готовый результат вы скачиваете отдельным запросом, не держа соединение открытым.
Зачем нужен асинхронный режим
Синхронный запрос ограничен по объёму и времени: большие выборки упираются в лимиты и таймауты, а сервер тратит ресурсы на удержание соединения. Асинхронный режим решает это, разделяя работу на три фазы: постановка задачи, ожидание и скачивание результата.
Когда стоит использовать async:
- полная выгрузка каталога на десятки и сотни тысяч позиций;
- тяжёлые отчёты — остатки по всем складам, обороты, прибыльность;
- регулярная ночная синхронизация большого объёма данных;
- любая выборка, где синхронный ответ рискует не уложиться в лимиты.
https://api.moysklad.ru/api/remap/1.2. Асинхронный режим включается добавлением параметра ?async=true к обычному GET-запросу сущности или отчёта.Шаг 1. Ставим задачу
Добавьте async=true к запросу выгрузки:
GET /api/remap/1.2/entity/product?async=true&limit=1000
Сервис не возвращает данные сразу. Вместо этого приходит ответ со статусом 202 Accepted и двумя важными заголовками:
| Заголовок | Что содержит |
|---|---|
Location | URL для проверки статуса задачи |
Content-Location | URL, по которому будет доступен результат |
Сохраните оба адреса. По Location вы опрашиваете готовность, по Content-Location — забираете результат, когда он готов.
Шаг 2. Опрашиваем статус
Обращайтесь к сохранённому Location обычным GET:
GET /api/remap/1.2/async/{taskId}
Ответ содержит поле state со статусом задачи:
PENDING— задача в очереди;PROCESSING— выполняется;DONE— готова, результат можно скачивать;ERROR— завершилась с ошибкой;CANCEL— отменена.
Опрашивайте статус с разумным интервалом (например, раз в несколько секунд), а не в плотном цикле — иначе вы зря расходуете лимит запросов. Когда state станет DONE, переходите к скачиванию.
Шаг 3. Скачиваем результат
Когда задача в статусе DONE, забирайте результат по сохранённому Content-Location:
GET /api/remap/1.2/async/{taskId}/download
Обратите внимание на поведение ответа: сервис отдаёт результат через редирект (303 See Other) на файл с данными. Ваш HTTP-клиент должен следовать за редиректом, чтобы получить тело:
- GET по
Content-Location; - клиент получает
303с заголовкомLocationна файл; - переход по нему возвращает готовый JSON-результат выгрузки.
Результат доступен для скачивания ограниченное время, поэтому забирайте его сразу после перехода задачи в DONE, а не спустя часы.
Лимиты асинхронных задач
Асинхронный режим тоже имеет ограничения, которые важно учитывать в интеграции:
| Ограничение | Смысл |
|---|---|
| Число одновременных задач | Аккаунт может держать ограниченное количество async-задач в очереди |
| Время жизни результата | Готовый файл доступен для скачивания ограниченный срок |
| Максимальный объём | Очень большие выборки лучше дробить по фильтрам, а не тянуть одним запросом |
Если лимит одновременных задач исчерпан, постановка новой вернёт ошибку — обрабатывайте это и ставьте задачи последовательно. Для регулярных выгрузок стройте очередь на своей стороне, чтобы не превышать ограничения сервиса.
Практический сценарий выгрузки
Надёжный конвейер большой выгрузки выглядит так:
- поставить задачу
GET /entity/product?async=true, сохранитьLocationиContent-Location; - опрашивать
Locationс нарастающей паузой до статусаDONE; - при
ERROR— прочитать причину и повторить постановку задачи; - при
DONE— скачать результат, следуя за редиректом; - обработать данные и, при необходимости, поставить следующую задачу.
Для очень больших каталогов комбинируйте async с фильтрацией: например, выгружать товары порциями по группам или по дате изменения. Так каждая задача остаётся управляемой, а сбой одной порции не рушит всю выгрузку.
Итог
Асинхронный режим JSON API 1.2 — это три фазы: постановка задачи через ?async=true с ответом 202, опрос статуса по Location до DONE и скачивание результата по Content-Location с переходом по редиректу. Учитывайте лимиты на число задач и время жизни результата, опрашивайте статус с паузами и дробите гигантские выборки по фильтрам.
Когда большие ночные выгрузки из МойСклад нужно завести в каталог на 1С-Битрикс без просадки сайта — с очередями, отказоустойчивостью и контролем лимитов, — мы проектируем такие highload-интеграции и модули обмена. Построим конвейер, который стабильно тянет сотни тысяч позиций.
Частые вопросы
Как включить асинхронный режим запроса?
Добавьте параметр async=true к обычному GET-запросу сущности или отчёта. Сервис поставит задачу в очередь вместо мгновенного ответа.
Что возвращается сразу после постановки async-задачи?
Ответ со статусом 202 Accepted и двумя заголовками: Location для проверки статуса и Content-Location для скачивания готового результата.
Как узнать, что задача готова?
Опрашивайте адрес из Location. В ответе поле state показывает статус: PENDING, PROCESSING, DONE, ERROR или CANCEL. Скачивать можно при DONE.
Как правильно скачать результат?
Обратитесь к Content-Location. Сервис отдаёт результат через редирект 303 на файл, поэтому HTTP-клиент должен следовать за редиректом, чтобы получить тело.
Как часто опрашивать статус задачи?
С разумными паузами, лучше с нарастающей задержкой. Частый поллинг расходует лимит запросов так же, как любые другие вызовы API.
Сколько async-задач можно держать одновременно?
Число одновременных задач на аккаунт ограничено. Если лимит исчерпан, постановка новой вернёт ошибку — ставьте задачи последовательно через свою очередь.
Долго ли доступен готовый результат?
Ограниченное время. Забирайте результат сразу после перехода задачи в DONE, а не спустя часы, иначе файл может стать недоступен.
Когда выбирать async, а когда обычную пагинацию?
До нескольких тысяч записей достаточно синхронной пагинации. Десятки и сотни тысяч записей или тяжёлые отчёты — это задача для асинхронного режима.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.