К содержимому

Чтение и экспорт сделок

Для просмотра сделок используйте поиск; для выгрузки запустите фоновый экспорт. Экспорт возвращает страницы JSON-строк. Готовый CSV-файл или ссылка для скачивания в ответ не входят.

Подготовьте доступ

Примеры используют Bash и curl. ALITOS_EXTERNAL_JWT — JWT из авторизации, CABINET_ID — точный строковый cabinetId, выбранный при поиске кабинетов. Даты в примерах замените нужным периодом.

Для поиска нужен cabinet:deals:read, для экспорта — cabinet:exports:run. Поиск перед экспортом необязателен. Для предварительного выбора кабинета через API нужен cabinet:read. Пользователь должен иметь текущие права на чтение чувствительных данных или экспорт соответственно. Не сохраняйте телефоны, комментарии и тела ответов в технические логи.

Просмотрите сделки

curl --request POST \
  "https://api.alitos.io/v1/external/cabinets/${CABINET_ID}/deals/search" \
  --header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}" \
  --header 'Content-Type: application/json' \
  --data '{
    "dateFrom": "2026-09-01",
    "dateTo": "2026-09-30"
  }'

Ответ содержит items, totalCalls, notFound и при необходимости nextCursor. Для следующей страницы передайте непустой nextCursor без изменений в поле cursor тела запроса, сохранив остальные фильтры. Поиск не принимает page, offset или limit.

Для ограничения выборки можно передать projectIds, query, dealStatusId, dealStatusIds или summaryGroupIds. Используйте реальные ID и группы выбранного кабинета; не угадывайте смысл статуса по его номеру. Точные поля — в OpenAPI.

1. Создайте ключ экспорта

Для новой выгрузки сформируйте и сохраните Idempotency-Key. Следующая команда генерации UUID требует Node.js; если ключ создаёт ваша интеграция, используйте его:

IDEMPOTENCY_KEY="$(node -p 'crypto.randomUUID()')"

Повтор той же выгрузки использует тот же ключ, тело и reason. Не выполняйте генерацию UUID заново при потере ответа.

2. Запустите экспорт

curl --include --request POST \
  "https://api.alitos.io/v1/external/cabinets/${CABINET_ID}/deals/export-jobs" \
  --header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}" \
  --header 'Content-Type: application/json' \
  --header "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
  --data '{
    "reason": "Сверка сделок за сентябрь",
    "dateFrom": "2026-09-01",
    "dateTo": "2026-09-30"
  }'

Экспорт принимает перечисленные выше фильтры поиска, но не его cursor. Даты можно передать как ISO-8601 дату или RFC3339 timestamp; сервер приводит их к дате UTC.

Ответ 202 Accepted содержит operationId, statusUrl, created, а также заголовки Location и Retry-After. Сохраните свой operationId в OPERATION_ID. created: false означает возврат существующей операции при точном повторе.

3. Дождитесь завершения

curl --include \
  "https://api.alitos.io/v1/external/operations/${OPERATION_ID}?view=compact" \
  --header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}"

При queued или running продолжайте опрос с учётом Retry-After, не чаще раза в две секунды и с небольшой случайной задержкой. При failed прочитайте error. HTTP 200 запроса состояния сам по себе не означает успешный экспорт.

4. Прочитайте все страницы

После succeeded получите первую страницу:

curl --get \
  "https://api.alitos.io/v1/external/operations/${OPERATION_ID}/result" \
  --header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}" \
  --data-urlencode 'pageSize=250'

Данные находятся в rows. Если nextCursor непустой, сохраните его в NEXT_CURSOR и запросите следующую страницу:

curl --get \
  "https://api.alitos.io/v1/external/operations/${OPERATION_ID}/result" \
  --header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}" \
  --data-urlencode 'pageSize=250' \
  --data-urlencode "cursor=${NEXT_CURSOR}"

После каждой страницы обновляйте NEXT_CURSOR из нового ответа. Завершите чтение, когда cursor отсутствует или равен null. Не разбирайте его и не переносите в другой экспорт. pageSize принимает от 1 до 1000; значение по умолчанию — 250. Параметр view=all предназначен для B4 и для экспорта сделок не подходит.

В строках есть dealId и dealStatusId; дополнительные данные, например phone, dealStatusLabel, projectId и comment, могут отсутствовать или быть null. Сохраняйте ID сделок и проектов строками; dealStatusId — число.

Для сверки итога один раз прочитайте сводку:

curl \
  "https://api.alitos.io/v1/external/operations/${OPERATION_ID}?view=compact&includeSummary=true" \
  --header "Authorization: Bearer ${ALITOS_EXTERNAL_JWT}"

Объект result содержит rowCount, totalCalls, notFound и truncated. Число выгруженных строк проверяйте по rowCount после чтения всех страниц, а не по размеру одной страницы.

Ошибки и смежные сценарии

Если ответ запуска потерян, повторите тот же POST с тем же ключом. Завершившаяся failed-операция от такого повтора не перезапускается. Правила HTTP-повторов, неоднозначного результата и срока хранения — в операциях и ошибках.

Импорт сделок в Архив создаёт новые сделки. Изменение статусов существующих сделок не входит в REST v1. Для него в Alitos MCP есть отдельный профиль deals и инструменты работы со статусами; REST JWT нельзя использовать для MCP.