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

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 всегда передаёт полный актуальный набор позиций. Обработка идёт асинхронно. До статуса succeeded поиск продолжает использовать текущее состояние. При статусе failed предыдущая версия не изменяется.

PUT и DELETE всегда возвращают 202 Accepted сoperation_id. Изменения одного проекта применяются в порядке FIFO; операции разных проектов могут выполняться параллельно. При заполнении очереди API отвечает429 catalog_queue_full, и запрос нужно повторить позже.

Методы

PUT/v1/catalog

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

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

Запрос

Авторизация
Bearer-токен
Content-Type
application/json
Тело
Объект с массивом items
Ограничения
1–30 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": [
    {
      "id": "tshirt-black-m",
      "name": "Футболка чёрная, размер M",
      "description": "Хлопковая базовая футболка",
      "category": "Одежда > Футболки",
      "price": {
        "kind": "exact",
        "amount": 990,
        "currency": "RUB",
        "period": "month"
      },
      "url": "https://shop.example/products/tshirt-black-m",
      "image_url": "https://shop.example/images/tshirt-black-m.jpg",
      "attributes": {
        "Размер": "M",
        "Цвет": "Чёрный",
        "Плотность": 180
      }
    }
  ]
}'

Ответы

202 AcceptedОбработка запущена
Тело ответа
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "operation_type": "full_replace",
  "source": "api",
  "status": "queued",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": null,
  "finished_at": null
}

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

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

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

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

Действие клиентаСделайте 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": "В одном каталоге может быть не более 30 000 позиций."
  }
}

Действие клиентаСократите каталог до 30 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.

429 Too Many Requestscatalog_queue_full
Тело ответа
{
  "error": {
    "code": "catalog_queue_full",
    "message": "Очередь обновлений каталога заполнена. Повторите запрос позже."
  }
}

Действие клиентаПовторите запрос позже с тем же полным актуальным набором.

PUT/v1/catalog/items/<EXTERNAL_ID>

Создать или изменить позицию

Ставит в очередь изменение только указанной позиции; остальные позиции не переиндексируются.

Запрос

Авторизация
Bearer-токен
Параметр пути
Стабильный id позиции
Тело
Поля позиции без id
Пример запроса
curl -sS -X PUT 'https://api.sales-agent.ru/v1/catalog/items/tshirt-black-m' \
  -H 'Authorization: Bearer <CATALOG_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data '{
  "name": "Футболка чёрная, размер M",
  "description": "Хлопковая базовая футболка",
  "category": "Одежда > Футболки",
  "price": {
    "kind": "exact",
    "amount": 1090,
    "currency": "RUB",
    "period": "month"
  },
  "url": "https://shop.example/products/tshirt-black-m",
  "image_url": "https://shop.example/images/tshirt-black-m.jpg",
  "attributes": {
    "Размер": "M",
    "Цвет": "Чёрный",
    "Плотность": 180
  }
}'

Ответы

202 AcceptedИзменение поставлено в очередь
Тело ответа
{
  "operation_id": "2ae33f63-5909-4de8-a09f-bf6d6b1366ce",
  "operation_type": "item_upsert",
  "source": "api",
  "status": "queued",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:01:00Z",
  "started_at": null,
  "finished_at": null
}

Действие клиентаСохраните operation_id и опрашивайте операцию до succeeded или failed.

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

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

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
          }
        }
      ]
    }
  }
}

Действие клиентаИсправьте поля позиции и повторите PUT.

429 Too Many Requestscatalog_queue_full
Тело ответа
{
  "error": {
    "code": "catalog_queue_full",
    "message": "Очередь обновлений каталога заполнена. Повторите запрос позже."
  }
}

Действие клиентаПовторите запрос позже.

DELETE/v1/catalog/items/<EXTERNAL_ID>

Удалить позицию

Ставит в очередь удаление одной позиции. Повторное удаление отсутствующей позиции безопасно.

Запрос

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

Ответы

202 AcceptedУдаление поставлено в очередь
Тело ответа
{
  "operation_id": "7c4e0407-31c3-4f75-916d-b238f8bb507c",
  "operation_type": "item_delete",
  "source": "api",
  "status": "queued",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:02:00Z",
  "started_at": null,
  "finished_at": null
}

Действие клиентаОпрашивайте операцию до succeeded или failed.

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

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

429 Too Many Requestscatalog_queue_full
Тело ответа
{
  "error": {
    "code": "catalog_queue_full",
    "message": "Очередь обновлений каталога заполнена. Повторите запрос позже."
  }
}

Действие клиентаПовторите запрос позже.

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",
  "operation_type": "full_replace",
  "source": "api",
  "status": "validating",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": "2026-09-11T10:00:01Z",
  "finished_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>'

Ответы

202 AcceptedОчистка поставлена в очередь
Тело ответа
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "operation_type": "full_replace",
  "source": "api",
  "status": "queued",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": null,
  "finished_at": null
}

Действие клиентаСохраните operation_id и опрашивайте операцию до succeeded или failed.

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

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

429 Too Many Requestscatalog_queue_full
Тело ответа
{
  "error": {
    "code": "catalog_queue_full",
    "message": "Очередь обновлений каталога заполнена. Повторите запрос позже."
  }
}

Действие клиентаПовторите запрос позже.

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

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

queuedОперация принята и ожидает обработки.
Ответ со статусом queued
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "operation_type": "full_replace",
  "source": "api",
  "status": "queued",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": null,
  "finished_at": null
}

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

validatingСервер проверяет структуру и связи позиций.
Ответ со статусом validating
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "operation_type": "full_replace",
  "source": "api",
  "status": "validating",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": "2026-09-11T10:00:01Z",
  "finished_at": null
}

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

indexingСервер формирует данные полнотекстового и семантического поиска.
Ответ со статусом indexing
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "operation_type": "full_replace",
  "source": "api",
  "status": "indexing",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 1,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": "2026-09-11T10:00:01Z",
  "finished_at": null
}

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

succeededИзменение опубликовано или завершилось идемпотентным no-op.
Ответ со статусом succeeded
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "operation_type": "item_upsert",
  "source": "api",
  "status": "succeeded",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 1,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 1,
  "warnings": [],
  "errors": [],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": "2026-09-11T10:00:01Z",
  "finished_at": "2026-09-11T10:00:08Z"
}

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

failedОбработка завершилась ошибкой; активная версия не изменена.
Ответ со статусом failed
{
  "operation_id": "7a67d3f3-146a-463f-b0ca-438f46074941",
  "operation_type": "full_replace",
  "source": "api",
  "status": "failed",
  "source_filename": null,
  "item_count": 1,
  "added": 0,
  "changed": 0,
  "deleted": 0,
  "unchanged": 0,
  "indexed": 0,
  "warnings": [],
  "errors": [
    {
      "code": "invalid_price",
      "message": "Цена не прошла проверку.",
      "row": 2,
      "field": "price"
    }
  ],
  "created_at": "2026-09-11T10:00:00Z",
  "started_at": "2026-09-11T10:00:01Z",
  "finished_at": "2026-09-11T10:00:02Z"
}

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

Excel

Загрузка существующего шаблона Excel остаётся полной authoritative replacement: колонки, лист Items и правила валидации не меняются. Worker сравнивает файл с текущим каталогом и индексирует только добавленные или семантически изменённые позиции.

Лимиты

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

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

Поля позиции

ПолеТипОбязательноеНазначение
idstringДаУникальный идентификатор позиции или варианта.
namestringДаПубличное название.
descriptionstring | nullНетОписание для поиска и ответа.
categorystring | nullНетBreadcrumb категории любой глубины через символ >.
priceobject | nullНетЦена: kind, amount, currency и необязательный period.
urlstring | nullНетПубличная HTTP(S)-ссылка на позицию.
image_urlstring | nullНетПубличная HTTP(S)-ссылка на изображение позиции. Ассистент показывает картинку только из этого поля.
attributesobjectНетДополнительные публичные характеристики.

Цена

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

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

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

Поиск и рекомендации

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

Поле category участвует в поиске по каждому уровню breadcrumb; дополнительные фильтры строятся по типизированным attributes.

OpenAPI

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

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