Перейти к основному содержимому

Заказы

4.1 Создание одного заказа

POST /api/public/v1/orders/

Обязательным является только поле address. Все остальные поля имеют значения по умолчанию.

ПолеТипОбяз.По умолчаниюОписание
addressстрока (до 512)даАдрес доставки
external_idстрока (до 128)нетnullВаш номер документа
nameстрока (до 255)нет""Наименование заказа
recipientстрока (до 255)нет""ФИО получателя
phoneстрока (до 30)нет""Телефон получателя
latчислонетnullШирота
lonчислонетnullДолгота
time_window_startЧЧ:ММ:ССнетnullНачало интервала доставки
time_window_endЧЧ:ММ:ССнетnullКонец интервала
weightчислонет0Вес, кг
volumeчислонет0Объём, м³
service_timeцелоенет10Время на точке, мин (от 0 до 240)
notesстроканет""Комментарий курьеру
order_typeone_time / recurringнетone_timeТип заказа
delivery_dateГГГГ-ММ-ДДнетсегодняДата доставки

Правила проверки:

  • time_window_end должно быть строго больше time_window_start.
  • lat и lon передаются только вместе. Одна координата без второй — ошибка.
  • Координаты 0, 0 считаются пустыми и заменяются на null — это защита от случайной отправки нулей.

Пример:

curl -X POST https://api.example.com/api/public/v1/orders/ \
-H "Authorization: Api-Key ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"external_id": "РН-000123",
"name": "Кофемашина DeLonghi",
"recipient": "Волкова Ирина Сергеевна",
"phone": "+375291234567",
"address": "г. Минск, пр. Независимости, 154",
"time_window_start": "10:00:00",
"time_window_end": "14:00:00",
"weight": "8.400",
"volume": "0.075",
"service_time": 15,
"notes": "Домофон 154, код 1207",
"delivery_date": "2026-07-31"
}'

Ответ 201:

{
"id": 118234,
"external_id": "РН-000123",
"name": "Кофемашина DeLonghi",
"recipient": "Волкова Ирина Сергеевна",
"phone": "+375291234567",
"address": "г. Минск, пр. Независимости, 154",
"lat": null,
"lon": null,
"time_window_start": "10:00:00",
"time_window_end": "14:00:00",
"weight": "8.400",
"volume": "0.075",
"service_time": 15,
"notes": "Домофон 154, код 1207",
"order_type": "one_time",
"status": "new",
"delivery_date": "2026-07-31",
"created_at": "2026-07-30T09:22:41.117482Z",
"updated_at": "2026-07-30T09:22:41.117482Z"
}

Координаты пустые — это нормально. Геокодирование выполняется асинхронно уже после ответа. Подробнее — раздел 10.

Повторная отправка того же external_id

Если заказ с таким номером документа уже существует, ответ будет 200 (а не 201), и вернётся существующий заказ.

Присланные данные при этом молча отбрасываются — заказ не обновляется. То есть повторная отправка накладной с исправленным адресом или весом ничего не изменит, хотя ответ будет успешным.

Различайте коды ответа:

КодСмысл
201заказ создан
200заказ с таким external_id уже был, вернулся он же, данные не обновлены

Чтобы изменить существующий заказ, используйте PATCH (см. 4.4).

Эта защита от дублей не является строгой гарантией — см. раздел 9. Запросы с одинаковым external_id, пришедшие одновременно, теперь выстраиваются в очередь и второй из них вернёт заказ, созданный первым, — но external_id по-прежнему не уникален в базе, и дубликаты, созданные другими способами (импорт из файла, веб-интерфейс), остаются возможны.

Числа приходят строками. Поля weight, volume, lat, lon сериализуются как строки ("8.400"), а не как числа. Это особенность точных десятичных типов. Учитывайте при разборе ответа.

4.2 Массовая загрузка

POST /api/public/v1/orders/bulk/

Основной способ выгрузки из учётной системы. Тело запроса — массив объектов той же структуры, что и при создании одного заказа. Обёртка не нужна, передаётся именно массив.

Ограничение: до 500 заказов в одном запросе.

Одна ошибочная строка не отменяет весь пакет. Каждый заказ обрабатывается независимо, ответ всегда 200, а результат по каждой позиции возвращается отдельно.

curl -X POST https://api.example.com/api/public/v1/orders/bulk/ \
-H "Authorization: Api-Key ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '[
{"external_id":"РН-000124","address":"г. Минск, ул. Притыцкого, 29","weight":"3.200"},
{"external_id":"РН-000125","address":""},
{"external_id":"РН-000126","address":"г. Борисов, ул. Гагарина, 61","service_time":400}
]'

Ответ:

{
"results": [
{"index": 0, "external_id": "РН-000124", "status": "created", "id": 118235, "errors": null},
{"index": 1, "external_id": "РН-000125", "status": "error", "id": null,
"errors": {"address": ["This field may not be blank."]}},
{"index": 2, "external_id": "РН-000126", "status": "error", "id": null,
"errors": {"service_time": ["Ensure this value is less than or equal to 240."]}}
],
"summary": {"created": 1, "existing": 0, "failed": 2}
}

Поле index — позиция заказа в вашем массиве, по нему сопоставляйте результат с исходными документами.

Значения status:

ЗначениеСмысл
createdзаказ создан
existsнайден существующий заказ с таким external_id, новый не создавался
errorзаказ не создан, причина в errors

Ошибка всего запроса возможна только в двух случаях:

{"detail": "Request body must be a non-empty list of orders."}
{"detail": "A bulk request may contain at most 500 orders."}

4.3 Получение списка

GET /api/public/v1/orders/?status=new&page=1&page_size=200

Фильтры: status и external_id (точное совпадение). Сортировка фиксированная — сначала новые. Постраничная навигация: по умолчанию 50 записей, максимум 200.

Возможные значения status: new, in_route, visited, confirmed, rejected, skipped, archived.

{
"count": 214,
"next": "https://api.example.com/api/public/v1/orders/?page=2&status=new",
"previous": null,
"results": [ ... ]
}

4.4 Изменение заказа

PATCH /api/public/v1/orders/{id}/

Изменять можно: name, recipient, phone, address, lat, lon, time_window_start, time_window_end, weight, volume, service_time, notes, delivery_date, order_type.

Нельзя изменить, запрос вернёт 400: id, external_id, status, created_at, updated_at.

{"external_id": ["This field is read-only."]}

delivery_date и order_type теперь изменяются. Раньше эти поля молча игнорировались — запрос возвращал 200, а значение оставалось прежним. Теперь они применяются как обычные изменяемые поля, и перенести заказ на другую дату можно одним запросом, без отмены и повторного создания:

curl -X PATCH https://api.example.com/api/public/v1/orders/118234/ \
-H "Authorization: Api-Key ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"delivery_date": "2026-08-01"}'

Ни одно переданное поле больше не отбрасывается молча. Если вы пришлёте поле, которого нет в контракте (опечатка в названии, поле из вашей учётной системы), запрос вернёт 400 с указанием этого поля, а не 200. Успешный ответ теперь действительно означает, что применено всё, что вы отправили:

{"prioritet": ["Unknown field."]}

Пустое тело запроса вернёт 400:

{"detail": "No mutable fields were supplied."}

Очистка координат. lat и lon проверяются в паре с уже сохранёнными значениями, поэтому обнулить только одну координату нельзя — вернётся 400. Чтобы сбросить неверно определённые координаты, передайте null в обе сразу, затем отдельным запросом исправьте адрес.

Методы PUT и DELETE для заказов не поддерживаются — вернётся 405.

Важное ограничение: редактировать можно только заказ в статусе new, который ещё не попал в маршрут. После планирования вернётся 409:

{"detail": "Order can no longer be updated because it has been dispatched."}

Отсюда практическое правило: исправляйте данные до запуска планирования.

4.5 Отмена заказа

POST /api/public/v1/orders/{id}/cancel/

Тело запроса не требуется. Условие то же, что и для изменения — заказ ещё не в маршруте, иначе 409.

После отмены заказ переходит в статус archived. Отдельного статуса «отменён» нет, и отменить отмену невозможно — это конечное состояние.