Для разработчиков

Catalog API

HTTP API для полной синхронизации товаров и услуг с каталогом SalesAgent.

Быстрый старт

  1. Создайте API-токенРаздел «Товары и услуги» → «API-токены».
  2. Передайте полный каталогВыполните PUT /v1/catalog с массивом items.
  3. Проверьте операциюЗапрашивайте GET /v1/catalog/operations/{operation_id} до финального статуса.

Авторизация

Передавайте токен в каждом запросе. Токен относится к одному проекту, показывается только при создании и может быть отозван в кабинете. До трёх токенов для синхронизации каталога через API.

HTTP-заголовок
Authorization: Bearer <CATALOG_TOKEN>

Обновление каталога

PUT /v1/catalog всегда передаёт полный актуальный набор позиций. Обработка идёт асинхронно. До статуса active поиск продолжает использовать предыдущую версию. При статусе failed предыдущая версия не изменяется.

API возвращает content_key — ключ идемпотентности содержимого. Повтор того же каталога возвращает существующую операцию. Пока другое обновление выполняется, новый каталог отклоняется с кодом 409 operation_in_progress.

Методы

PUT/v1/catalog

Передать полный каталог

Заменяет каталог проекта после успешной фоновой обработки всех переданных позиций.

Запрос

Авторизация
Bearer-токен
Content-Type
application/json
Тело
Объект с массивом items
Ограничения
1–10 000 позиций; до 50 МиБ; до 100 атрибутов на позицию; строка до 20 000 символов
Пример запроса
curl -sS -X PUT 'https://api.sales-agent.ru/v1/catalog' \
  -H 'Authorization: Bearer <CATALOG_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data '{
  "items": [
    {
      "external_id": "tshirt-black-m",
      "product_id": "tshirt-black",
      "type": "product",
      "name": "Футболка чёрная, размер M",
      "category_path": "Одежда > Футболки",
      "description": "Хлопковая базовая футболка",
      "price": {
        "kind": "exact",
        "amount": 990,
        "currency": "RUB"
      },
      "availability": "available",
      "url": "https://shop.example/products/tshirt-black-m",
      "image_url": "https://shop.example/images/tshirt-black-m.jpg",
      "tags": [
        "чёрная",
        "хлопок"
      ],
      "direction_key": "dir_a1b2c3d4e5f6",
      "cross_sell_product_ids": [
        "cap-black"
      ],
      "upsell_product_ids": [
        "tshirt-premium"
      ],
      "attributes": {
        "Размер": "M",
        "Цвет": "Чёрный",
        "Плотность": 180
      }
    }
  ]
}'

Ответы

202 AcceptedОбработка запущена
Тело ответа
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "queued",
  "item_count": 1,
  "processed_count": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": null,
  "activated_at": null
}

Действие клиентаСохраните operation_id и проверяйте операцию методом GET.

200 OKИдентичный каталог уже активен
Тело ответа
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "active",
  "item_count": 1,
  "processed_count": 1,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": "2026-09-02T10:00:08Z",
  "activated_at": "2026-09-02T10:00:08Z"
}

Действие клиентаДополнительных действий не требуется.

401 Unauthorizedunauthorized
Тело ответа
{
  "error": {
    "code": "unauthorized",
    "message": "Токен отсутствует, неверен или отозван."
  }
}

Действие клиентаСоздайте или укажите действующий токен проекта.

409 Conflictoperation_in_progress
Тело ответа
{
  "error": {
    "code": "operation_in_progress",
    "message": "Дождитесь завершения текущего обновления каталога."
  }
}

Действие клиентаДождитесь финального статуса текущей операции и повторите PUT.

409 Conflictduplicate_external_id
Тело ответа
{
  "error": {
    "code": "duplicate_external_id",
    "message": "external_id должен быть уникальным во всём каталоге."
  }
}

Действие клиентаСделайте external_id уникальными и повторите полный PUT.

413 Content Too Largepayload_too_large
Тело ответа
{
  "error": {
    "code": "payload_too_large",
    "message": "Размер запроса не должен превышать 50 МиБ."
  }
}

Действие клиентаУменьшите размер JSON до 50 МиБ.

413 Content Too Largecatalog_too_large
Тело ответа
{
  "error": {
    "code": "catalog_too_large",
    "message": "В одном каталоге может быть не более 10 000 позиций."
  }
}

Действие клиентаСократите каталог до 10 000 позиций или обратитесь в поддержку для увеличения лимита.

422 Unprocessable Contentcatalog_empty
Тело ответа
{
  "error": {
    "code": "catalog_empty",
    "message": "Передайте хотя бы одну позицию."
  }
}

Действие клиентаДобавьте минимум одну позицию и повторите PUT.

422 Unprocessable Contentvalidation_error
Тело ответа
{
  "error": {
    "code": "validation_error",
    "message": "Поля запроса не прошли проверку.",
    "details": {
      "issues": [
        {
          "type": "value_error",
          "loc": [
            "body",
            "items",
            0,
            "price"
          ],
          "msg": "Value error, numeric price requires amount and uppercase three-letter currency",
          "input": {
            "kind": "exact",
            "amount": 990
          }
        }
      ]
    }
  }
}

Действие клиентаИсправьте поля, перечисленные в error.details.issues, и повторите полный PUT.

GET/v1/catalog/operations/<OPERATION_ID>

Получить состояние операции

Возвращает состояние одной операции, созданной токеном того же проекта.

Запрос

Авторизация
Bearer-токен
Параметр пути
operation_id из ответа PUT
Тело
Отсутствует
Интервал опроса
2–5 секунд
Пример запроса
curl -sS 'https://api.sales-agent.ru/v1/catalog/operations/<OPERATION_ID>' \
  -H 'Authorization: Bearer <CATALOG_TOKEN>'

Ответы

200 OKОперация найдена
Тело ответа
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "validating",
  "item_count": 1,
  "processed_count": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": null,
  "activated_at": null
}

Действие клиентаОбработайте поле status по таблице ниже.

401 Unauthorizedunauthorized
Тело ответа
{
  "error": {
    "code": "unauthorized",
    "message": "Токен отсутствует, неверен или отозван."
  }
}

Действие клиентаСоздайте или укажите действующий токен проекта.

404 Not Foundoperation_not_found
Тело ответа
{
  "error": {
    "code": "operation_not_found",
    "message": "Операция не найдена."
  }
}

Действие клиентаПроверьте operation_id и токен проекта, которым была создана операция.

DELETE/v1/catalog

Очистить каталог

Удаляет активные позиции из поиска. Повторный запрос безопасен.

Запрос

Авторизация
Bearer-токен
Тело
Отсутствует
Пример запроса
curl -sS -X DELETE 'https://api.sales-agent.ru/v1/catalog' \
  -H 'Authorization: Bearer <CATALOG_TOKEN>'

Ответы

204 No ContentКаталог очищен
Тело ответа
HTTP/1.1 204 No Content

Действие клиентаДополнительных действий не требуется.

401 Unauthorizedunauthorized
Тело ответа
{
  "error": {
    "code": "unauthorized",
    "message": "Токен отсутствует, неверен или отозван."
  }
}

Действие клиентаСоздайте или укажите действующий токен проекта.

409 Conflictoperation_in_progress
Тело ответа
{
  "error": {
    "code": "operation_in_progress",
    "message": "Дождитесь завершения текущего обновления каталога."
  }
}

Действие клиентаДождитесь финального статуса текущей операции и повторите DELETE.

Статусы операций

queued, validating и indexing — промежуточные. Остальные статусы финальные.

queuedОперация принята и ожидает обработки.
Ответ со статусом queued
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "queued",
  "item_count": 1,
  "processed_count": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": null,
  "activated_at": null
}

Действие клиентаПродолжайте опрос GET через 2–5 секунд.

validatingСервер проверяет структуру и связи позиций.
Ответ со статусом validating
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "validating",
  "item_count": 1,
  "processed_count": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": null,
  "activated_at": null
}

Действие клиентаПродолжайте опрос GET через 2–5 секунд.

indexingСервер формирует данные полнотекстового и семантического поиска.
Ответ со статусом indexing
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "indexing",
  "item_count": 1,
  "processed_count": 1,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": null,
  "activated_at": null
}

Действие клиентаПродолжайте опрос GET через 2–5 секунд.

activeНовая версия полностью активирована и участвует в поиске.
Ответ со статусом active
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "active",
  "item_count": 1,
  "processed_count": 1,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": "2026-09-02T10:00:08Z",
  "activated_at": "2026-09-02T10:00:08Z"
}

Действие клиентаОстановите опрос. Синхронизация завершена.

replacedЭта версия ранее была активной и заменена более новой.
Ответ со статусом replaced
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "replaced",
  "item_count": 1,
  "processed_count": 1,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": "2026-09-02T10:00:08Z",
  "activated_at": "2026-09-02T10:00:08Z"
}

Действие клиентаОстановите опрос. Проверяйте операцию новой версии, если она вам нужна.

failedОбработка завершилась ошибкой; активная версия не изменена.
Ответ со статусом failed
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "failed",
  "item_count": 1,
  "processed_count": 0,
  "warnings": [],
  "errors": [
    {
      "code": "invalid_direction_key",
      "message": "Направление не найдено в бизнес-профиле.",
      "row": 2,
      "field": "direction_key"
    }
  ],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": "2026-09-02T10:00:02Z",
  "activated_at": null
}

Действие клиентаИсправьте элементы из errors и повторите полный PUT.

clearedЭта версия удалена из активного поиска вызовом DELETE.
Ответ со статусом cleared
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "content_key": "sha256:9b816fd8a7d21d16d17e0e7740c331daf5b3db673fcb3fb0e77ce3b6f44375a2",
  "status": "cleared",
  "item_count": 1,
  "processed_count": 1,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-02T10:00:00Z",
  "finished_at": "2026-09-02T10:00:08Z",
  "activated_at": "2026-09-02T10:00:08Z"
}

Действие клиентаОстановите опрос. Для восстановления передайте полный каталог методом PUT.

Лимиты

ПараметрЛимит
Позиции в каталоге10 000
API-запрос50 МиБ (52 428 800 байт)
Excel-файл50 МиБ; формат .xlsx или .xls; один лист Items
Дополнительные атрибуты позиции100
Теги позиции100
Имя дополнительного атрибута100 символов
Строковое значение атрибута или описание20 000 символов
external_id и product_id200 символов
name500 символов
category_path2 000 символов
url и image_url4 000 символов
API-токены проектадо трёх токенов

Для каталога больше 10 000 позиций обратитесь в поддержку.

Поля позиции

ПолеТипОбязательноеНазначение
external_idstringДаУникальный идентификатор позиции или варианта.
namestringДаПубличное название.
product_idstring | nullНетОбщий идентификатор вариантов. По умолчанию равен external_id.
typeproduct | service | nullНетТип позиции.
category_pathstring | nullНетПуть категории любой глубины через символ >.
descriptionstring | nullНетОписание для поиска и ответа.
priceobject | nullНетЦена вместе с валютой.
availabilityenum | nullНетСтатус наличия.
urlstring | nullНетПубличная HTTP(S)-ссылка на позицию.
image_urlstring | nullНетПубличная HTTP(S)-ссылка на изображение.
tagsstring[]НетТеги для поиска.
direction_keystring | nullНетСвязь с направлением бизнес-профиля и его CTA.
cross_sell_product_idsstring[]Нетproduct_id сопутствующих позиций.
upsell_product_idsstring[]Нетproduct_id расширенных или более дорогих вариантов.
attributesobjectНетДополнительные публичные характеристики.

Цена и наличие

Для price.kind доступны exact, from, free и on_request. Варианты exact и from требуют неотрицательный amount и трёхбуквенный код currency в верхнем регистре. Наличие: available, unavailable, preorder, on_request.

Дополнительные атрибуты

attributes принимает до 100 пар «имя — значение». Имя — до 100 символов; строковое значение — до 20 000 символов. Значения: строка, число, boolean, дата ISO или null.

Поиск и CTA

Поля каталога участвуют в полнотекстовом и семантическом поиске. Цена, наличие, ссылки и характеристики найденной позиции берутся из активного каталога. Материалы сайта и Q&A используются как поясняющий контекст и не заменяют эти значения.

direction_key связывает позицию с направлением бизнес-профиля и доступными CTA. Действие «Предложить сопутствующие позиции» использует только связи cross_sell_product_ids после выбора основной позиции. Отсутствующие связи не создаются автоматически.

OpenAPI

Спецификация содержит публичные методы, схемы запросов и схемы ответов Catalog API.

Скачать catalog-openapi.json