# Управление сущностями — общие правила

Management API даёт программный доступ к редактированию сущностей в проекте: персонализации, A/B-тесты, опросы, rule-based действия, моделируемые конверсии, аудиторные сегменты, антиботы, smart-фиды. На этом API можно построить свой интерфейс, синхронизировать сущности с внешней системой, развернуть проект из шаблона, и т.п.

Все эндпоинты единообразны по форме, потому что подчиняются нескольким простым правилам, описанным ниже.

# Пять операций на сущность

На каждую сущность ровно пять операций:

Операция HTTP Тело
Список GET /manage/<entities> — (фильтры через query)
Список (сложный фильтр) POST /manage/<entities>/list JSON-фильтр (для id[], диапазонов дат, длинного поиска)
Получить GET /manage/<entities>/{id}
Создать POST /manage/<entities> полное дерево сущности
Обновить PUT /manage/<entities>/{id} полное дерево сущности
Удалить DELETE /manage/<entities>/{id}

Никаких POST /manage/<entities>/{id}/variants, PUT /manage/<entities>/{id}/options/{oid} и т.п. Любые вложенные коллекции (варианты, шаги опроса, модификации, условия показа) редактируются через родителя, одним телом.

# Тело — полное дерево, заменяет всё

POST и PUT принимают всё дерево сущности целиком: header + дочерние коллекции + внуки + условия показа. Семантика — «полная замена»:

  • Элемент коллекции, присутствующий в теле с прежним id → обновляется.
  • Элемент с id: null или без id → создаётся, сервер сам генерирует UUID и возвращает его в ответе.
  • Элемент, отсутствующий в теле, но существующий в БД → удаляется.
  • Порядок элементов в коллекциях значим (если этой сущности порядок важен — например, шаги опроса).

Для частичного обновления используйте PATCH там, где он поддерживается — иначе вычитайте сущность через GET, поменяйте поле и пошлите назад тем же PUT.

# id принадлежат серверу

  • В POST поле id в теле игнорируется — даже если вы его передадите. Новый id сгенерирует сервер и вернёт в ответе.
  • В PUT id берётся из URL; значение в теле молча перезаписывается.
  • projectId нигде передавать не надо — он выводится из токена; любое значение в теле игнорируется.

Это правило исключает целый класс ошибок «id из тестового проекта попало в продовый».

# Ответ на запись

POST и PUT возвращают 200 OK с компактным телом примерно такой формы:

{
  "personalizationId": "8f3a1e4b-7c4d-4d5e-9aaf-2c1b6d3e5f01",
  "variantIds": ["a1b2…", "c3d4…"],
  "displayConditionId": "e5f6…",
  "createdPersonalization": true,
  "createdVariantIds": ["c3d4…"]
}

Где created* — флаги, что было создано впервые (полезно, если вы синхронизируете внешний источник и хотите отличить «создали» от «обновили»).

DELETE возвращает 204 No Content.

# Списки и пагинация

GET /manage/<entities> принимает:

Query Значение
search Подстрока в названии (без учёта регистра).
state Фильтр по состоянию: Working, Active, Stopped, Paused, Archived.
page Номер страницы, начинается с 1.
pageSize Размер страницы. По умолчанию 50, максимум 200.

Для случаев, когда нужно фильтровать по списку id, диапазону createdOnUtc или другим составным фильтрам — используйте POST /manage/<entities>/list с JSON-телом:

{
  "search": "checkout",
  "state": "Active",
  "ids": ["8f3a1e4b-...", "1c2d3e4f-..."],
  "createdFromUtc": "2026-04-01T00:00:00Z",
  "createdToUtc": "2026-04-30T23:59:59Z",
  "page": 1,
  "pageSize": 50
}

# Идемпотентность и retry

Запросы на чтение (GET) можно ретраить безопасно.

Запись (POST/PUT/DELETE) сейчас не идемпотентна на уровне API. Если у вас сетевой ретрай — повторный POST создаст вторую сущность. Рекомендация: для POST сохраняйте полученный из ответа id и при ретрае переключайтесь на PUT {id}.

# Что НЕ доступно через Public API

Намеренно не вынесены наружу:

  • Запуск/остановка обучения ML-моделей. Управляется автоматически системой.
  • Дебаг-ссылки, превью-токены, инструменты диагностики.
  • Инвалидация кэшей, миграции, бутстрап проекта, инфраструктурные триггеры.
  • Управление аккаунтом и пользователями проекта.

Если вам не хватает какой-то операции — напишите в поддержку. Мы намеренно держим внешний API узким: каждая функция, которую мы выносим наружу, становится контрактом и далее не меняется.

# Связанные страницы