AploDelivery Partner API — портал разработчика · v2 (2026-10-16)

Идемпотентность

Работает

В AploDelivery есть два независимых механизма, которые легко перепутать: одноразовость запроса (X-Request-ID) и идемпотентность заказа (externalOrderId). Они решают разные задачи.

X-Request-ID — одноразовость HTTP-запроса

Каждый подписанный запрос должен нести новый X-Request-ID (UUID). Сервер один раз принимает конкретную пару «API-ключ + requestId» и навсегда отклоняет её повторное использование (401 unauthorized) — подробности в Аутентификации. Это защита от replay-атаки на уровне транспорта, а не механизм идемпотентности бизнес-операции: если вы повторяете один и тот же POST /v1/orders из-за таймаута, сгенерируйте новый X-Request-ID для повторной попытки — старый уже использован и будет отклонён.

externalOrderId — идемпотентность создания заказа

POST /v1/orders идемпотентен по ключу (tenantId, source, externalOrderId) плюс SHA-256 нормализованного канонического содержимого заказа (payloadSha256 в ответе). Практическое правило:

Область действия идемпотентности — конкретный credential (tenantId + source, то есть в терминах партнёра — ваш API-ключ). Один и тот же externalOrderId у разных партнёров (разных source) не конфликтует.

Что считается «тем же содержимым»

Сервер сравнивает не байты JSON, а SHA-256 от нормализованного типизированного представления заказа (payloadSha256). Практически: одинаковые значения полей дают одинаковый хэш независимо от порядка ключей или пробелов в вашем JSON — но любое отличие значения (даже отличающийся comment) даёт другой хэш и, соответственно, 409 при повторной отправке под тем же externalOrderId.

Практический паттерн ретрая

1. Сгенерировать externalOrderId один раз, сохранить его у себя ДО отправки.
2. Собрать CanonicalOrder с фиксированным createdAt.
3. POST /v1/orders с новым X-Request-ID.
4. Сетевая ошибка / таймаут / 5xx → повторить шаг 3 с ТЕМ ЖЕ externalOrderId,
   ТЕМ ЖЕ телом, но НОВЫМ X-Request-ID.
5. 200 или 201 — успех, дальше работать с вернувшимся id/state.
6. 409 idempotency_conflict — остановиться, это не сетевая ошибка.

Отмена и другие операции

Связанное