Асинхронные операции и ошибки
Импорт, экспорт, аналитика источников B4 и поддерживаемые изменения выполняются
как фоновые операции. Ответ 202 Accepted означает, что запрос принят;
завершение отслеживается отдельно от исходного HTTP-соединения.
1. Запустите операцию и сохраните её ID
Перед запуском создайте постоянный Idempotency-Key для одной логической операции
и укажите причину в reason. Ключ содержит 1–128 видимых ASCII-символов;
рекомендуется UUID. Сохраните ключ вместе с запросом для возможных повторов.
Одинаковые ключ, тело и reason возвращают существующую операцию. Если с тем же
ключом передать другие данные, сервер вернёт 409 idempotency_key_conflict.
Ответ 202 содержит operationId, statusUrl, created, а также заголовки
Location и Retry-After. created: false означает, что запрос вернул ранее
созданную операцию. Сохраните operationId в переменную OPERATION_ID.
2. Дождитесь завершения
В примерах используется Bash; ALITOS_EXTERNAL_JWT содержит JWT для исходной
операции. Компактный ответ удобен для повторного опроса:
curl --include \
"https://api.alitos.io/v1/external/operations/${OPERATION_ID}?view=compact" \
--header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}"
| Действие |
|---|---|
| Операция ожидает выполнения; продолжайте опрос |
| Операция выполняется; продолжайте опрос |
| Получите результат |
| Прочитайте |
Соблюдайте Retry-After, добавляйте небольшую случайную задержку и не опрашивайте
чаще раза в две секунды. progress и отдельные показатели прогресса могут
отсутствовать; завершение определяется полем status.
view=compact возвращает состояние, доступные показатели прогресса и ошибку,
без строк результата, reason, idempotencyKey и полей с отсутствующими значениями.
Без этого параметра сохраняется полный ответ v1, включая nullable-поля и итог
успешной операции.
3. Получите итог или строки результата
После succeeded запросите сводный итог один раз:
curl \
"https://api.alitos.io/v1/external/operations/${OPERATION_ID}?view=compact&includeSummary=true" \
--header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}"Итог находится в result; при компактном опросе без includeSummary=true
он не передаётся. Способ чтения подробных данных зависит от операции:
Импорт сделок в Архив: проверьте счётчики в
result; отдельных строк результата нет.B4:
GET /operations/{operationId}/result?view=allвозвращает все сохранённые строки источников одним ответом, без ограничения числа строк и сnextCursor: null. Этот режим доступен только для B4;cursorиpageSizeвместе с ним запрещены.Экспорт сделок:
GET /operations/{operationId}/result?pageSize=250возвращает страницу JSON-строк. Передавайте непустойnextCursorв параметреcursorследующего запроса, пока страницы не закончатся.
Все пути выше относятся к https://api.alitos.io/v1/external. Обычный запрос
/result без view=all сохраняет постраничное чтение. До succeeded этот метод
возвращает 409 operation_not_completed: числовой HTTP-код находится в status,
состояние операции — в operationStatus.
Операцию читает тот же пользователь с JWT из того же ключа и со scope исходной операции. Новый JWT подходит. Текущий доступ проверяется заново при каждом опросе и при чтении результата. Cursor непрозрачен и привязан к операции: не разбирайте его и не переносите в другую выгрузку.
Ошибка запроса и ошибка операции
При сбое фоновой работы запрос состояния возвращает HTTP 200 с status: "failed"
и объектом error. Это результат выполнения операции, а не успешный бизнес-результат.
Ошибки самого HTTP-запроса к API имеют формат RFC 9457 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 без чувствительного тела запроса. Ошибки /oauth/token используют поля
error и error_description — см.
авторизацию.
HTTP-ответ | Действие клиента |
|---|---|
| Исправьте запрос; неизменённый запрос повторять не нужно |
| Проверьте JWT и |
| Проверьте scope, список кабинетов ключа и текущие права пользователя |
| Разберите |
| Перечитайте ресурс и заново подготовьте изменение |
| Передайте обязательный |
| Соблюдайте |
| Повторяйте только при |
Защищённые методы при 401 возвращают WWW-Authenticate: Bearer; неверный
предъявленный токен может добавить error="invalid_token". Поле retryable
есть также в ошибках управления ключами.
Сбои сервиса данных представлены кодами upstream_unavailable (503),
upstream_timeout (504) и upstream_rate_limited (429). Ошибка
upstream_version_unsupported (502) автоматически не повторяется.
Если ответ запуска потерян, повторите тот же запрос с тем же ключом, телом
и reason. Временная HTTP-ошибка не повод менять ключ. Если операция уже имеет
status: "failed", тот же ключ вернёт её снова; он не перезапускает работу.
Разберите ошибку и фактическое состояние ресурса. При ambiguous_upstream_outcome
сначала сверьте результат в ГЦК; автоматический запуск с новым ключом запрещён.
Изменения с защитой версии
Для методов, требующих If-Match, сначала прочитайте ресурс и сохраните сильный
ETag из заголовка ответа. Передайте его без изменения в If-Match при записи.
Отсутствующий заголовок даёт 428; устаревшая версия — 412.
После 412 перечитайте ресурс и заново подготовьте изменение.
Точные правила заголовков и совместимости — в условных запросах. Для изменения источников нужен сильный ETag конкретного проекта — см. чтение и редактирование источников.
Лимиты и срок хранения
Текущие значения возвращает /capabilities. Базовые лимиты на ключ —
60 GET-запросов и 15 POST-запросов в минуту, до двух одновременных операций;
тело запроса — до 1 MiB. Настройки сервиса могут снизить лимиты, поэтому
не фиксируйте их в клиентском коде.
Базовый срок хранения операций, результатов и ключей идемпотентности — семь дней. После его окончания тот же ключ может создать новую работу: старый запрос нельзя считать безопасным повтором без проверки фактического результата.