API доставки отзывов

PUT /shopping/reviews принимает новые и изменённые отзывы о товарах, включая скрытие и удаление. Используйте его для обновлений между полными выгрузками по CSV-контракту. Названия полей и допустимые значения совпадают с форматом файла.

Сейчас API сохраняет отзывы. Shopping Assistant пока не использует их в ответах, а автоматический импорт CSV ещё не реализован. Успешная доставка не означает, что саммари по отзывам уже доступно покупателю.

Подключение и доступ

Отправляйте запросы из серверной системы, в которой хранятся отзывы. Перед подключением получите у специалиста Gravity Field идентификатор раздела (tenant_id) и согласуйте исходящие IP-адреса серверов.

В теле запроса передавайте идентификатор раздела в поле sec. Доступ проверяется по списку разрешённых IP-адресов и подсетей, если он настроен для раздела. Запрос с другого IP получает 403 IP_NOT_ALLOWED. Если список не настроен или пуст, ограничение по IP не применяется. Отдельный заголовок авторизации для этой ручки не предусмотрен.

PUT https://shopping-assistant-api.gravityfield.ai/shopping/reviews
Content-Type: application/json

Запрос

Поле Обязательное Описание
sec Да Непустая строка: идентификатор раздела Shopping Assistant (tenant_id).
data Да Массив от 1 до 1000 отзывов. Каждый элемент содержит полное актуальное состояние отзыва.

Пример доставки

Замените YOUR_TENANT_ID на идентификатор своего раздела, а sku — на точный SKU из товарного фида.

curl --request PUT \
  --url 'https://shopping-assistant-api.gravityfield.ai/shopping/reviews' \
  --header 'Content-Type: application/json' \
  --data '{
    "sec": "YOUR_TENANT_ID",
    "data": [
      {
        "reviewId": "rv-123",
        "sku": "sku-456",
        "rating": 5,
        "title": "Отличный крем",
        "text": "Быстро впитывается, хорошо увлажняет",
        "pros": "Текстура",
        "cons": "Сильный запах",
        "status": "published",
        "helpfulCount": 12,
        "locale": "ru-RU",
        "createdAt": "2026-08-20T09:00:00Z",
        "updatedAt": "2026-08-31T10:00:00Z"
      }
    ]
  }'

Поля отзыва

Поле Обязательное Формат и ограничения
reviewId Да Непустая строка до 256 символов. Стабильный ID отзыва, уникальный в пределах раздела. В одном запросе каждый reviewId встречается только один раз.
sku Да Непустая строка до 256 символов. Должна точно совпадать с sku в товарном фиде, включая регистр и разделители.
rating Да Целое число от 1 до 5.
title Нет Заголовок: строка до 50 000 символов или null.
text Нет Основной текст: строка до 50 000 символов или null.
pros Нет Достоинства: строка до 50 000 символов или null.
cons Нет Недостатки: строка до 50 000 символов или null.
status Да published, hidden или deleted.
helpfulCount Нет Целое число от 0 до 2147483647 или null. Количество отметок о полезности.
locale Нет Строка до 35 символов, например ru-RU, en или en-US, либо null. Язык — 2–3 латинские буквы; следующие части через дефис — по 2–8 латинских букв или цифр.
createdAt Да Дата создания в формате RFC 3339 с часовым поясом, например 2026-08-20T09:00:00Z.
updatedAt Да Дата последнего изменения в том же формате, например 2026-08-31T13:00:00+03:00.

Передавайте числа как JSON-числа, без кавычек. У reviewId, sku и sec удаляются пробелы по краям. Необязательные текстовые поля, переданные пустой строкой или строкой из пробелов, сохраняются как null.

Необязательное поле, отсутствующее в отзыве, также сохраняется как null: прежнее значение не сохраняется. Поэтому при обновлении отправляйте полное состояние отзыва, а не только изменённые поля. Отзывы только с оценкой допустимы.

Неизвестные поля внутри отзыва отклоняются с 400. Используйте точные имена в camelCase: например, reviewId, а не review_id. Не добавляйте имя, email, телефон и другие персональные данные автора.

Обновление, скрытие и удаление

Отзыв определяется сочетанием раздела sec и reviewId. Для всех обновлений одного отзыва сохраняйте тот же reviewId и передавайте время изменения в updatedAt.

  • Новый отзыв сохраняется.
  • Обновление с updatedAt новее сохранённого заменяет состояние отзыва.
  • Обновление с равным updatedAt тоже применяется. Для разных версий используйте разные даты изменения, чтобы порядок доставки не определял итоговое состояние.
  • Обновление со старым updatedAt игнорируется и учитывается в stale.
  • Повторная доставка того же состояния безопасна и может снова учитываться в applied.

Для скрытия отправьте полное состояние со статусом hidden, для удаления — со статусом deleted и новым updatedAt. Обязательные поля нужны и для этих статусов. Например, тело запроса на удаление:

{
  "sec": "YOUR_TENANT_ID",
  "data": [
    {
      "reviewId": "rv-123",
      "sku": "sku-456",
      "rating": 5,
      "status": "deleted",
      "createdAt": "2026-08-20T09:00:00Z",
      "updatedAt": "2026-09-01T10:00:00Z"
    }
  ]
}

Запись со статусом deleted сохраняется, чтобы запоздавшее старое обновление не восстановило отзыв. Отсутствие отзыва в очередном запросе не удаляет его. Для будущей саммаризации предусмотрены только отзывы со статусом published; hidden и deleted исключаются.

Если хотя бы один элемент не проходит валидацию или reviewId повторяется внутри массива, весь запрос отклоняется без сохранения отзывов. В корректном запросе устаревшие элементы игнорируются, а остальные сохраняются.

Успешный ответ

API возвращает 200 OK:

{
  "received": 1,
  "applied": 1,
  "stale": 0
}
Поле Описание
received Количество отзывов в запросе.
applied Количество сохранённых новых или обновлённых отзывов, включая повтор с равным updatedAt.
stale Количество проигнорированных отзывов с более старым updatedAt. Равно received - applied.

Ответ подтверждает сохранение данных, а не построение саммари.

Ошибки и повторная доставка

HTTP error / code Что делать
400 Invalid JSON body Исправьте синтаксис JSON.
400 Invalid request body Исправьте поля по массиву details. Возвращается до 50 ошибок с путём path и описанием message. Индексы в data начинаются с нуля.
400 Invalid request body / DUPLICATE_REVIEW_ID Уберите повторяющиеся reviewId из одного запроса.
403 Forbidden / IP_NOT_ALLOWED Проверьте исходящий IP сервера и согласованный список разрешённых адресов.
404 Unknown tenant / TENANT_NOT_FOUND Проверьте sec и подключение раздела к Shopping Assistant.
503 Reviews storage is unavailable / REVIEWS_STORAGE_UNAVAILABLE Повторите доставку позже. Если ошибка сохраняется, обратитесь в поддержку Gravity Field.
500 Failed to save reviews Повторите доставку позже; при повторяющейся ошибке обратитесь в поддержку.

При 400, 403 или 404 исправьте причину перед повтором. После сетевого сбоя, 500 или 503 повторяйте тот же пакет с задержкой и постепенным увеличением интервала. Сохраняйте исходный updatedAt: время повтора не является временем изменения отзыва.

Для объёма больше 1000 отзывов разделите обновления на несколько запросов. Ограничение на один файл для полной CSV-выгрузки сохраняется.

Проверка интеграции

  • sec содержит идентификатор нужного раздела.
  • Исходящие IP серверов согласованы для раздела.
  • Один запрос содержит от 1 до 1000 отзывов без повторяющихся reviewId.
  • sku совпадает с товарным фидом.
  • Обновления содержат полное состояние, а updatedAt отражает время изменения в исходной системе.
  • Скрытие и удаление передаются явно через status.
  • Обрабатываются applied, stale и ошибки; повтор сохраняет исходные данные и даты.

Файл с отзывами
/shopping_assistant/reviews_file/