Планирование маршрутов
Требуется разрешение planning:write.
5.1 Запуск
POST /api/public/v1/planning/jobs/
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
order_ids | массив чисел | * | Идентификаторы заказов в системе |
external_ids | массив строк | * | Ваши номера документов |
vehicle_ids | массив чисел | нет | Ограничение по машинам |
warehouse_id | число | нет | Склад отправления |
* Нужно указать хотя бы один из списков order_ids или external_ids.
Удобство для учётных систем: можно ссылаться на свои номера документов, не сохраняя у себя внутренние идентификаторы платформы.
curl -X POST https://api.example.com/api/public/v1/planning/jobs/ \
-H "Authorization: Api-Key ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"external_ids":["РН-000123","РН-000124"],"warehouse_id":3}'
Ответ 202:
{
"job_id": 4471,
"status": "queued",
"input": {"order_ids": [118234, 118235], "vehicle_ids": [], "warehouse_id": 3},
"result": {},
"error": "",
"created_at": "2026-07-30T09:31:07.882014Z",
"updated_at": "2026-07-30T09:31:07.882014Z"
}
Проверка выполняется строго и целиком. Если хотя бы один идентификатор не найден или принадлежит другой компании, задание не создаётся:
| Ситуация | Ответ |
|---|---|
| Заказ не найден | {"detail": "Orders not found for this tenant: [4571]."} |
| Номер документа не найден | {"detail": "Orders not found for external_ids: ['РН-999']."} |
| Пустой отбор | {"detail": "The order selection is empty."} |
| Больше 500 заказов | {"detail": "A planning job may select at most 500 orders (got 640)."} |
| Машина не найдена или отключена | {"detail": "Vehicles not found or inactive for this tenant: [12]."} |
| Склад не найден | {"detail": "Warehouse not found for this tenant: 3."} |
Особенность
vehicle_ids. Если указать ровно одну машину — маршрут строится именно на неё. Если указать две и более — ограничение молча игнорируется, и расчёт идёт по всем свободным машинам. Чтобы закрепить несколько конкретных машин, запускайте отдельные задания.
Планировать можно только заказы в статусе
new. Заказ, уже попавший в маршрут, вызовет ошибку задания. Публичного способа «распланировать заново» нет — освобождение заказа делается диспетчером в интерфейсе.
5.2 Получение результата
GET /api/public/v1/planning/jobs/{job_id}/
Статусы: queued → running → done либо failed.
Списка заданий нет. GET /api/public/v1/planning/jobs/ вернёт 405 — это не
недоработка документации, а отсутствующий метод. Обязательно сохраняйте job_id
у себя сразу после запуска: получить его повторно невозможно.
Успешное завершение:
{
"job_id": 4471,
"status": "done",
"input": {"order_ids": [118234, 118235, 118237], "vehicle_ids": [], "warehouse_id": 3},
"result": {
"route_ids": [9042, 9043],
"summary": {"route_count": 2, "unassigned_count": 1},
"unassigned": [{"order_id": 118237, "reason": "time_window"}]
},
"error": "",
"created_at": "2026-07-30T09:31:07.882014Z",
"updated_at": "2026-07-30T09:33:52.410883Z"
}
Нераспределённые заказы — это штатный результат, а не ошибка. Причины:
| Причина | Смысл |
|---|---|
capacity | не хватает грузоподъёмности или объёма |
time_window | невозможно уложиться в интервал доставки |
max_distance | превышен лимит пробега |
max_duration | превышена длительность смены |
max_orders | превышено число заказов на маршрут |
requirements | нет машины с нужными характеристиками |
no_vehicle | нет свободных машин |
unroutable | до точки нет проезда |
Ошибка задания:
{
"job_id": 4472,
"status": "failed",
"result": {},
"error": "Order 118240 not found or not eligible."
}
Поле error — текст для человека, кодов ошибок здесь нет. Не разбирайте его программно.
Обязательно сверяйте состав. Заказы без координат отбрасываются до расчёта и не попадают ни в маршруты, ни в список нераспределённых — они просто исчезают из результата. Сравнивайте
input.order_idsс объединением размещённых и нераспределённых: разница и есть заказы с неопределённым адресом.