# Управление опросами

CRUD над опросами + четыре read-only эндпоинта для аналитики ответов.

База: https://api.sales-ninja.me/public/api/v1/manage/surveys

HTTP Что делает
GET / Список опросов.
POST /list Список со сложным фильтром.
GET /{id} Полный опрос с шагами и вариантами ответов.
POST / Создать.
PUT /{id} Обновить (полная замена дерева).
DELETE /{id} Удалить.
GET /{id}/actions/statistics?fromUtc&toUtc Сводка по опросу за период.
GET /{id}/steps/{stepId}/actions/step-overview?fromUtc&toUtc Сводка по конкретному шагу.
GET /{id}/steps/{stepId}/actions/step-responses?fromUtc&toUtc&page=… Постраничный список ответов на шаг (с фильтрами).
GET /steps/{stepId}/actions/semantic-summary Семантическая агрегация ответов (для свободных ответов).

# Тело опроса (POST/PUT)

{
  "title": "NPS после оформления заказа",
  "header": "Оцените, насколько вы готовы порекомендовать нас",
  "slotFrom": 0,
  "slotTo": 100,
  "displayStrategy": "OncePerSession",
  "state": "Working",
  "useGlobalSettings": true,
  "accentColor": "#1F8AFF",
  "baseButtonColor": "#1F8AFF",
  "baseButtonTextColor": "#FFFFFF",
  "positioning": "BottomRight",
  "enableSmartPositioning": true,
  "displayCondition": {
    "fieldCode": "page_url",
    "operation": "Contains",
    "value": "/thank-you"
  },
  "steps": [
    {
      "type": "Rating10",
      "state": "Active",
      "title": "Готовность рекомендовать",
      "description": "От 0 (точно нет) до 10 (точно да).",
      "containerJson": "{\"min\":0,\"max\":10}",
      "allowComment": true,
      "options": []
    },
    {
      "type": "SingleChoice",
      "state": "Active",
      "title": "Почему такая оценка?",
      "description": "",
      "containerJson": "{}",
      "allowComment": false,
      "options": [
        { "state": "Active", "name": "Удобство оформления" },
        { "state": "Active", "name": "Цены" },
        { "state": "Active", "name": "Скорость доставки" },
        { "state": "Active", "name": "Другое" }
      ]
    }
  ]
}

# Поля

Поле Описание
title Внутреннее название опроса.
header Заголовок, который видит респондент.
displayStrategy Когда показывать (OncePerSession, Always, …). Точный список — в админке.
state Working / Active / Stopped / Paused / Archived.
useGlobalSettings Использовать глобальные цвета/позиционирование проекта. Если false — заполнить accentColor и т.д.
accentColor HEX-цвет акцента.
baseButtonColor HEX-цвет кнопок.
baseButtonTextColor HEX-цвет текста на кнопках.
positioning Позиция на экране: BottomRight / BottomLeft / Center / …
enableSmartPositioning Авто-перепозиционирование при коллизии с другими виджетами.
slotFrom / slotTo Слоты трафика (0-100), на которых работает опрос.
displayCondition Условие показа V2. Target: Default. Создаётся однократно на опрос: после первой записи структура условия фиксируется и обновлять её через PUT нельзя.

# steps[]

Шаг — это один вопрос или экран опроса.

Поле Описание
id UUID существующего шага; для нового — null.
type Rating10, SingleChoice, MultipleChoice, FreeText, … (полный список см. в админке).
state Active / Archived.
title Текст вопроса.
description Подсказка / уточнение.
containerJson JSON-строка с типо-специфичными параметрами шага (диапазон оценки, плейсхолдер и т.п.).
allowComment Разрешить респонденту свободный комментарий.
options[] Варианты ответа (для типов с выбором).

# steps[].options[]

Поле Описание
id UUID существующего варианта; null — будет создан.
state Active / Archived.
name Текст варианта.

# Аналитика по опросу

Все четыре analytics-эндпоинта read-only, не требуют тела.

# GET /{id}/actions/statistics

Сводка ответов за период: количество просмотров, ответов, средние оценки, доли вариантов.

curl "https://api.sales-ninja.me/public/api/v1/manage/surveys/$ID/actions/statistics?fromUtc=2026-04-01T00:00:00Z&toUtc=2026-04-30T23:59:59Z" \
  -H "X-SN-TOKEN: $SN_TOKEN"

# GET /{id}/steps/{stepId}/actions/step-overview

То же, но для одного шага.

# GET /{id}/steps/{stepId}/actions/step-responses

Постраничный список ответов на конкретный шаг. Параметры:

Query Значение
fromUtc/toUtc Период.
page С 1.
pageSize Максимум 50.
tagId Фильтр по тегу ответа.
responseType Тип ответа (зависит от типа шага).
sentiment Тональность (для свободных ответов).
urgency Срочность (для свободных ответов).
isAnnotated Только размеченные / только неразмеченные.

# GET /steps/{stepId}/actions/semantic-summary

Семантическая сводка свободных ответов (кластеризация по теме, выделение основных кластеров). Запрос без периода — система возвращает актуальную сводку.

# Ответ при сохранении

{
  "surveyId": "9a82c331-…",
  "stepIds": ["…", "…"],
  "createdSurvey": true,
  "createdStepIds": ["…"]
}