Асинхронные операции и ошибки

Долгие и изменяющие запросы External API создают durable operation. Клиент получает 202 Accepted и отслеживает состояние отдельно от исходного HTTP-соединения.

Idempotency

Для каждой логической операции создайте устойчивый Idempotency-Key. Рекомендуемый формат - UUID.

Тот же key с тем же payload и reason возвращает существующую операцию. Тот же key с другими данными возвращает 409 idempotency_key_conflict.

Если HTTP-ответ потерян, повторите исходный запрос без изменений. Не создавайте новый key только из-за timeout.

Polling

Ответ 202 содержит operationId, Location и Retry-After.

curl \
  'https://api.alitos.io/v1/external/operations/${OPERATION_ID}' \
  --header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}"

Статусы операции: queued, running, succeeded, failed.

Соблюдайте Retry-After, добавляйте jitter и не опрашивайте операцию чаще одного раза в две секунды.

Для завершившейся с ошибкой операции status endpoint возвращает HTTP 200 и status: "failed". Поля error.code, error.message и error.retryable описывают результат фоновой работы.

Большие результаты экспорта читаются через GET /operations/{operationId}/result?pageSize=250. Cursor непрозрачен и связан с исходным запросом.

Конкурентные изменения и ETag

Настройки, analytics config и источники проекта защищены ETag.

  1. Выполните безопасный GET.

  2. Прочитайте сильный ETag из заголовка ответа.

  3. Передайте его в If-Match при изменении.

Отсутствующий If-Match возвращает 428. Устаревший ETag возвращает 412. После 412 перечитайте ресурс и сформируйте изменение заново.

Weak ETag с префиксом W/ нельзя использовать для update.

Формат ошибок

Resource endpoints возвращают RFC 7807 Problem Details.

{
  "type": "https://api.alitos.io/problems/idempotency-key-conflict",
  "title": "Idempotency key conflict",
  "status": 409,
  "detail": "The idempotency key was already used with another payload.",
  "code": "idempotency_key_conflict",
  "retryable": false,
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}

Для программной логики используйте code и retryable. Сохраняйте traceId для диагностики, но не записывайте чувствительный payload.

Политика повторов

Ответ

Действие клиента

400

Исправить request, автоматический retry не нужен

401

Получить новый JWT и проверить resource

403

Проверить scope, allowlist и текущие права

409

Проверить code, не менять key автоматически

412

Перечитать ресурс и сформировать update заново

428

Добавить обязательный If-Match

429

Соблюдать Retry-After

503

Повторять только при retryable: true

Для ambiguous_upstream_outcome автоматический retry с новым key запрещен. Сначала проверьте фактическое состояние ресурса в ГЦК.

Лимиты и хранение

Актуальные значения возвращает /capabilities. Базовые значения:

  • 300 GET-запросов в минуту;

  • 60 POST-запросов в минуту;

  • до 5 одновременных операций на ключ;

  • до 1 MiB в request body;

  • 7 дней хранения операций, результатов и idempotency keys.

Deployment может снизить лимиты. Не фиксируйте их в клиентском коде.