Перейти к содержанию

Асинхронная очередь API 2.0

API 2.0 выполняет чтение и запись объектов в фоновой очереди. Обычный клиент 1С/ERP работает с методами:

POST /api/tasks/queue
GET  /api/tasks/queue?id={taskId}

/api/iris/queue — алиас тех же методов. В новых интеграциях используйте /api/tasks/queue.

Warning

/api/integrations/Tasks/Queue относится к отдельному партнёрскому API с другой авторизацией. Не используйте его вместо /api/tasks/queue.

1. Подготовка

Администратор организации должен создать настройку внешней системы и привязать к ней отдельного пользователя:

GET  /api/SyncSystems/Get
POST /api/SyncSystems/Apply
POST /api/SyncSystems/Delete

Основные поля SyncSystemModel:

Поле Значение
id 0 для новой настройки, ID для изменения
userId Пользователь, от имени которого работает интеграция
behavior 0 — очистка при чтении; 1 — очистка только после ReadConfirmation
trackingType 0 — не отслеживать; 1 — все изменения; 2 — изменения экспедиции
callback.target HTTPS URL для уведомления о завершении задания
callback.secret Секрет HMAC-SHA256; не передавайте его в журналах

Для надёжной синхронизации используйте behavior = 1 и trackingType = 1.

2. Постановка задания

POST /api/tasks/queue
Authorization: Bearer <accessToken>
Idempotency-Key: sync-bids-20261012-1200
Content-Type: application/json
{
  "commands": [
    {
      "action": 1,
      "objects": [
        {
          "type": 1,
          "modelType": 0
        }
      ]
    }
  ]
}

Пример ставит в очередь чтение накопленных изменений заявок. Idempotency-Key необязателен, имеет длину не более 100 символов и в течение 24 часов возвращает те же задания для повторного запроса.

Сервер возвращает HTTP 202 Accepted:

{
  "latencyMsec": 25,
  "enqueuedInMsec": 3,
  "commands": [
    {
      "id": 731245,
      "action": 1,
      "status": 0,
      "readyInMsec": 25,
      "message": null
    }
  ]
}

Каждая команда ставится в очередь независимо. Проверяйте commands[].status: 0 — успех, 1 — команда не попала в очередь. commands[].id — ID задания, а не ID заявки.

3. Действия

Код Имя Назначение
0 Write Создание или полное обновление
1 Read Чтение объектов или накопленных изменений
2 ReadConfirmation Подтверждение обработанной версии
3 ReadQuery Чтение по OData-запросу
4 Delete Удаление по ID CARGO.RUN

Типы объектов: 1 — Bid, 2 — DistributionBid, 3 — Car, 4 — Trailer, 5 — Driver, 6 — Counterparty.

Основные поля objects[]:

Поле Правило
id Внутренний ID CARGO.RUN; null/0 при Write создаёт объект
key Внешний корреляционный ключ до 64 символов; не уникален и не заменяет id
version UUID версии; передача при Write включает проверку конкурентного изменения
modelType 0 — основная модель; другие значения используйте только в описанном сценарии
body Полная модель для Write
query OData-запрос для ReadQuery; в этом объекте id, version и key должны быть пустыми

externalId заявки и objects[].key не уникальны. Обновление, чтение, подтверждение и удаление выполняйте по objects[].id CARGO.RUN.

4. Получение результата

GET /api/tasks/queue?id=731245
Authorization: Bearer <accessToken>

Статусы задания: 0 — Awaiting, 1 — InProgress, 2 — Completed, 3 — Error.

  • При InProgress сервер передаёт Retry-After в секундах.
  • При Awaiting ориентируйтесь на nextRetryAt.
  • Completed не означает успех всех объектов. Проверьте каждый objects[].status.
  • Неизвестное или недоступное задание может вернуть HTTP 200 с null.

Статусы объекта: 0 — Created, 1 — Success, 2 — Error, 3 — VersionMismatch. При VersionMismatch в ответе передаётся текущая версия: перечитайте объект и не подтверждайте устаревшую версию.

Обработка задания выполняется до трёх раз. После ошибок используются задержки 5 и 10 секунд. Завершённые задания хранятся примерно три дня; забирайте результат без отлагательств.

5. Надёжное чтение с подтверждением

Для behavior = 1:

  1. поставьте Read для типа Bid;
  2. дождитесь Completed;
  3. надёжно сохраните каждый успешный объект вместе с id и version;
  4. только после успешной локальной транзакции отправьте ReadConfirmation:
{
  "commands": [
    {
      "action": 2,
      "objects": [
        {
          "type": 1,
          "modelType": 0,
          "id": 123456,
          "version": "2f1ac0f8-1da7-4e74-b69d-1a94de150803"
        }
      ]
    }
  ]
}

Изменения, сделанные тем же пользователем синхронизации, не возвращаются ему как входящие изменения. Это предотвращает эхо синхронизации.

6. Callback

Если в SyncSystemModel задан callback.target, CARGO.RUN отправляет POST после завершения задания. Проверяйте:

HMAC_SHA256(callback.secret, "<timestamp>.<raw-json-body>")

Заголовки: X-Cargorun-Task-Id, X-Cargorun-Webhook-Event, X-Cargorun-Webhook-Timestamp, X-Cargorun-Webhook-Signature: sha256=<hex>.

Callback выполняется до пяти раз с задержками 10, 20, 40 и 80 секунд. Повтор выполняется при сетевой ошибке, HTTP 408, 429 или 5xx.

callbackStatus и счётчики callback возвращаются в GET /api/tasks/queue.

7. Границы гарантий

  • В выборку Read попадают накопленные изменения не старше одного часа. Это намеренное ограничение. Вызывайте синхронизацию чаще одного раза в час.
  • Несколько изменений одного объекта могут объединяться: клиент получит последнюю версию, а не журнал каждого промежуточного события.
  • API 2.0 пока не гарантирует доставку всех смен статуса и удалений. Для них используйте контрольную синхронизацию через GET /api/bids/GetListForExternal.

Полный алгоритм: Синхронизация заявок API 2.0.