Для разработчиков

API вебхука

Ваша система передаёт заказ в ADelivo одним POST-запросом, а мы присылаем статусы доставки на ваш адрес: курьер назначен, в пути, доставлен, отменён.

Шаг 1

Подключение

Адрес для заказов и токен выдаёт ADelivo — они видны администратору в кабинете: Компания → магазин → Настроить. Там же указывается ваш адрес для статусов и есть кнопка проверки.

Все запросы — JSON в UTF-8. Все времена — ISO 8601 по Москве, например 2026-10-01T14:15:00+03:00.

ЧтоЗначение
Адрес заказовhttps://adelivo.ru/api/webhooks/custom/{shopId}
АвторизацияAuthorization: Bearer <токен> или X-Api-Key: <токен>
Адрес статусовваш HTTPS-адрес, принимает POST с JSON

Вы → ADelivo

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

POST https://adelivo.ru/api/webhooks/custom/{shopId} Authorization: Bearer <токен> Content-Type: application/json { "orderId": "L-1001", "address": "Одинцово, мкр. Клубничное Поле, 3, кв. 12", "phone": "+79990000000", "slot": "14:00-15:00", "items": "Клубника 1 кг", "comment": "домофон 12" }
ПолеОписание
orderIdобязательноВаш номер заказа. По нему отсекаются дубли и он приходит во всех статусах
addressобязательноАдрес доставки
phoneжелательноТелефон получателя
slot—Интервал "14:00-15:00". Вместо него "asap": true — как можно быстрее. Нет ни того, ни другого — тоже «как можно быстрее»
date—"2026-10-01"; по умолчанию — сегодня
items—Строка или [{ "name": "Клубника", "qty": 2 }]
name, comment—Имя получателя, комментарий курьеру

Ответ — 201

{ "ok": true, "id": "cmu1abc2d0000xyz", "orderId": "L-1001", "status": "new", "onExchange": true, "duplicate": false, "slot": { "asap": false, "date": "2026-10-01", "from": "14:00", "to": "15:00" }, "deliveryPrice": 250, "warnings": ["Адрес не найден на карте — диспетчер уточнит вручную"] }

id — наш номер заказа, orderId — ваш. warnings есть, только если что-то не так, — заказ при этом всё равно создан. Повтор с тем же orderId дубль не создаёт: ответ 200, тот же id, "duplicate": true. Поэтому при любом сбое запрос можно смело повторить.

Ошибки

{ "ok": false, "code": "missing_address", "error": "Не передан адрес доставки" }
HTTPcodeКогда
400bad_bodyПустое тело или не JSON
400missing_order_id, missing_addressНет обязательного поля
400bad_slotСлот не разобрать
401unauthorizedНеверный токен
403integration_disabledПодключение выключено в ADelivo
404shop_not_foundНеверный адрес
500internalСбой у нас — повторите с тем же orderId

Вы → ADelivo

Отмена

Тот же адрес и токен, в теле — номер заказа и действие.

POST https://adelivo.ru/api/webhooks/custom/{shopId} { "orderId": "L-1001", "action": "cancel", "reason": "клиент передумал" } → 200 { "ok": true, "id": "cmu…", "orderId": "L-1001", "status": "cancelled" }

Заказ снимается с биржи; если курьер уже взял его, ему приходит уведомление. Этот ответ и есть подтверждение — хук cancelled на вашу собственную отмену не приходит. Уже доставленный заказ отменить нельзя: 409 already_finished.

ADelivo → вы

Статусы

POST на ваш адрес при каждом шаге доставки. Порядок: assigned → in_delivery → delivered, либо cancelled на любом шаге до доставки.

X-Adelivo-Event: assigned X-Adelivo-Event-Id: cmv1… уникален для события — для защиты от повторов X-Adelivo-Signature: sha256=<hex> HMAC-SHA256 тела на вашем токене

Общие поля всех событий: event, eventId, orderId (ваш), adelivoId (наш), at — когда это произошло.

assigned — курьер взял заказ

{ "event": "assigned", "eventId": "cmv1…", "orderId": "L-1001", "adelivoId": "cmu1…", "at": "2026-10-01T14:02:10+03:00", "courier": { "name": "Иван Петров", "phone": "+79991112233" }, "courierAtStoreAt": "2026-10-01T14:15:00+03:00" }

courierAtStoreAt — когда курьер будет у вас на базе: время, которое он выбрал в приложении (или время выезда от диспетчера). Пока не выбрано — оценка по геопозиции курьера, если нет и её — null. Курьер часто выбирает время уже после того, как взял заказ: тогда придёт ещё один assigned с новым eventId и точным временем — применяйте последний.

in_delivery — курьер забрал заказ

{ "event": "in_delivery", "eventId": "cmw1…", "orderId": "L-1001", "adelivoId": "cmu1…", "at": "2026-10-01T14:16:00+03:00", "courier": { "name": "Иван Петров", "phone": "+79991112233" }, "eta": "2026-10-01T14:21:00+03:00" }

at — когда забрал, eta — когда привезёт: через 5 минут, если адрес в пределах ~500 м от базы, иначе через 10 минут.

delivered — доставлен

{ "event": "delivered", "eventId": "cmx1…", "orderId": "L-1001", "adelivoId": "cmu1…", "at": "2026-10-01T14:23:40+03:00", "courier": { "name": "Иван Петров", "phone": "+79991112233" } }

cancelled — отменён у нас

{ "event": "cancelled", "eventId": "cmy1…", "orderId": "L-1001", "adelivoId": "cmu1…", "at": "2026-10-01T14:05:00+03:00" }

Надёжность

Повторная отправка

Правило
Когда уходитВ течение пары секунд после изменения заказа. Плюс сверка раз в минуту — событие не потеряется.
УспехЛюбой ответ 2xx за 8 секунд. Тело ответа не читаем. Тяжёлую обработку делайте после ответа.
Ошибка4xx, 5xx, таймаут, сеть, редирект 3xx (по редиректам не идём).
Паузы30 с, 1, 2, 5, 10, 15, 30, 30, 60, 60, 120 мин — 12 попыток, ~5,5 часа. Фактически пауза может быть до минуты дольше.
КонецПосле 12 неудач событие больше не шлём. Не доставленное за сутки — тоже.
ДублиПовтор приходит с тем же eventId и тем же телом — отсекайте по eventId.
ПорядокСтрогий внутри заказа: пока assigned не принят, in_delivery ждёт. Если статус перескочил, пропущенные события придут по порядку.

Безопасность

Проверка подписи

X-Adelivo-Signature — HMAC-SHA256 от сырого тела запроса, ключ — ваш токен. Считайте подпись от байтов тела до разбора JSON.

// Node.js / Express import crypto from "crypto"; app.post("/adelivo/status", express.raw({ type: "application/json" }), (req, res) => { const expected = "sha256=" + crypto.createHmac("sha256", process.env.ADELIVO_TOKEN).update(req.body).digest("hex"); if (req.get("X-Adelivo-Signature") !== expected) return res.sendStatus(401); const e = JSON.parse(req.body); if (seen(e.eventId)) return res.sendStatus(200); // повтор — уже обработали if (e.test) return res.sendStatus(200); // проверка из кабинета // e.event: assigned | in_delivery | delivered | cancelled saveStatus(e.orderId, e.event, e); res.sendStatus(200); });
// PHP $body = file_get_contents("php://input"); $expected = "sha256=" . hash_hmac("sha256", $body, getenv("ADELIVO_TOKEN")); if (!hash_equals($expected, $_SERVER["HTTP_X_ADELIVO_SIGNATURE"] ?? "")) { http_response_code(401); exit; } $e = json_decode($body, true);

Перед запуском

Проверка

1. Заказ к нам. Отправьте тестовый заказ — готовый curl с вашим токеном есть в кабинете. Ожидаемый ответ — 201 с "status": "new".

curl -X POST 'https://adelivo.ru/api/webhooks/custom/{shopId}' \ -H 'Authorization: Bearer <токен>' \ -H 'Content-Type: application/json' \ -d '{"orderId":"TEST-1","address":"Одинцово, мкр. Клубничное Поле, 1","phone":"+79990000000","asap":true}'

2. Статусы к вам. В кабинете у поля «Адрес для статусов» есть кнопка «Отправить тест»: на ваш адрес уходит образец выбранного события с "test": trueи "orderId": "TEST-1", подписанный токеном. Ответьте 2xx — в кабинете будет видно код, время ответа и что именно отправили. Настоящие события поля test не содержат.

3. Живой прогон. Создайте заказ, курьер берёт его с биржи и отмечает «На базе в» — по нему придут assigned, in_delivery и delivered.

Запасной путь

Опрос статуса

GET https://adelivo.ru/api/webhooks/custom/{shopId}?orderId=L-1001 Authorization: Bearer <токен> → { "ok": true, "id": "cmu…", "orderId": "L-1001", "status": "in_delivery", "at": "…", "courier": { … }, "eta": "…" }

status: new / assigned / in_delivery / delivered / cancelled — с теми же полями, что в последнем событии. Без orderId запрос просто проверяет токен.

Вопросы по подключению — в Telegram. Другие способы подключения — на странице интеграций.