# Получение персонализаций (runtime)
Метод применяется без веб-бандла: мобильное приложение, серверный рендер, бэкенд.
Три продукта в админке — общий runtime-контур
В админке персонализации, A/B-тесты и действия по правилам — разные разделы (обзор).
На backend и в ответе personalizations/apply они обрабатываются единым контуром применения вариантов (те же поля personalizationId / optionId, модификации, subscription params). Отдельный эндпоинт ab-tests/apply — для выборки только A/B без смешивания с персонализациями в одном ответе.
На сайте с бандлом всё это также идёт через onPersonalization.
Sales Ninja по контексту пользователя возвращает, какие варианты (персонализаций, а при общем apply — и других сущностей стека «Сайт») следует применить.
# Описание метода
POST https://api.sales-ninja.me/public/{source}/v1.0/personalizations/apply
Headers:
X-SN-TOKEN: <ваш токен проекта>
Content-Type: application/json
{source} — идентификатор источника вызова (mobile, server, и т.п.). Уточняется в поддержке.
# Тело запроса
{
"context": {
"pageTitle": "<название текущей страницы/экрана>",
"userScreenWidth": 1280,
"userScreenHeight": 720,
"customUserScopeParams": {},
"customPageScopeParams": {},
"clientDevice": "<Desktop|Tablet|Smartphone|Other>",
"deviceModel": "<модель устройства, опционально>",
"deviceBrand": "<производитель устройства, опционально>",
"os": "<Android|Windows|Linux|MacOs|IOs|Other>",
"osVersion": "<версия ОС, опционально>",
"userIp": "<IP клиента, опционально>",
"utmMedium": "<utm_medium, опционально>",
"utmSource": "<utm_source, опционально>",
"utmCampaign": "<utm_campaign, опционально>",
"utmTerm": "<utm_term, опционально>",
"utmContent": "<utm_content, опционально>",
"sessionNumber": 4,
"sessionId": "<id сессии>",
"pagesOpenedSinceFirstEntry": 2,
"pagesOpenedInThisSession": 1,
"firstEntryOnUtc": "2026-04-10T19:27:47Z",
"sessionStartOnUtc": "2026-04-15T18:15:50Z",
"lastReachedGoals": []
},
"customerId": "<id клиента в Sales Ninja>",
"appliedPersonalizationItems": []
}
projectId в теле передавать не нужно — он выводится из токена; любое значение в этом поле игнорируется.
# Пример
{
"context": {
"pageTitle": "Интернет-магазин — Главная",
"userScreenWidth": 1280,
"userScreenHeight": 720,
"customUserScopeParams": {
"revenue": "12350",
"netProfit": "900"
},
"customPageScopeParams": {},
"clientDevice": "Desktop",
"deviceModel": "MacBook Air M1",
"deviceBrand": "Apple",
"os": "MacOs",
"osVersion": "14.0",
"userIp": "192.168.0.1",
"utmMedium": "display",
"utmSource": "billboard",
"utmCampaign": "yellow_dress",
"sessionNumber": 4,
"sessionId": "8bf06a1d-0321-4be2-89b7-314181511c3d",
"pagesOpenedSinceFirstEntry": 2,
"pagesOpenedInThisSession": 1,
"firstEntryOnUtc": "2026-04-10T19:27:47Z",
"sessionStartOnUtc": "2026-04-15T18:15:50Z",
"lastReachedGoals": []
},
"customerId": "ab859455-b459-419b-bba0-d73e911a9dc2",
"appliedPersonalizationItems": [
{
"personalizationId": "50e62336-9b35-4ab6-b77a-a26b99c69883",
"personalizationOptionId": "47b6fd00-29be-4d8c-adc0-0d9fa525745f",
"isControl": false,
"option": { "id": "09c5fd24-adce-46af-8338-c84fbb2af59c", "title": "Как сейчас" },
"title": "Размер шрифтов",
"version": 18,
"validUntilUtc": "2026-04-30T19:27:48Z"
}
]
}
# Поля контекста
# pageTitle
Название страницы/экрана, для которой запрашиваются персонализации.
# userScreenWidth / userScreenHeight
Размеры экрана пользователя в пикселях.
# customUserScopeParams / customPageScopeParams
Пользовательские параметры клиента и страницы в виде ключ-значение. Значения обязательно строками. Используются и для таргетинга персонализаций, и для обогащения статистики (revenue, netProfit и т.п.). Подробнее: user params, page params.
# clientDevice
Тип устройства. Допустимо: Desktop, Tablet, Smartphone, Other.
# deviceModel, deviceBrand
Модель и марка устройства, если их можно определить (для мобильных приложений — обычно да).
# os, osVersion
ОС и её версия. ОС: Android, Windows, Linux, MacOs, IOs, Other.
# userIp
IP клиента. Желательно передавать — нужен для антибота и географии.
# utmMedium, utmSource, utmCampaign, utmTerm, utmContent
Стандартные UTM-метки рекламной кампании, по которой пришёл пользователь.
# sessionNumber
Порядковый номер сессии этого пользователя.
# sessionId
Идентификатор текущей сессии.
# pagesOpenedSinceFirstEntry / pagesOpenedInThisSession
Сколько страниц/экранов пользователь открыл с момента первого визита / в этой сессии.
# firstEntryOnUtc / sessionStartOnUtc
Время первого входа пользователя и время начала текущей сессии в UTC.
# lastReachedGoals
Список последних достигнутых целей. Опционально — используется для обогащения сигналов таргетинга.
# customerId
Идентификатор клиента в Sales Ninja. Если у вас уже есть веб-бандл — берите его через
await ninja('getCustomerIdAsync'). Если интеграция чисто серверная — сохраняйте customerId, который мы
вернули в первом ответе, и используйте дальше.
# appliedPersonalizationItems
Список персонализаций, которые уже применены на этом экране в этой сессии. Передавайте сюда то, что вы получили в предыдущем вызове и реально показали пользователю — это даёт системе понимание непрерывности эксперимента и помогает не «перетыкать» решение в рамках одной сессии.
Поля одного элемента:
personalizationId— id персонализации.personalizationOptionId— id применённого варианта.isControl— был ли это контрольный вариант.option.id,option.title— id и название варианта.title— название самой персонализации.version— версия персонализации, под которой решение было принято.validUntilUtc— до какого UTC-времени применённое решение валидно.
# Ответ
{
"personalizations": [
{
"personalizationId": "50e62336-9b35-4ab6-b77a-a26b99c69883",
"title": "Размер шрифтов",
"version": 19,
"validUntilUtc": "2026-04-30T19:27:48Z",
"isControl": false,
"option": {
"id": "47b6fd00-29be-4d8c-adc0-0d9fa525745f",
"title": "Крупный шрифт"
}
}
],
"customerId": "ab859455-b459-419b-bba0-d73e911a9dc2"
}
В personalizations — список того, что система рекомендует применить прямо сейчас на этом экране. Каждый
элемент — это конкретный вариант (option) персонализации.
Если в запросе не был передан customerId, в ответе вернётся выданный системой свежий customerId —
сохраните его и используйте в следующих запросах.
# Что делать с ответом
- Применить указанные варианты на текущем экране (показать конкретный текст, поменять баннер, и т.п.).
- На следующем экране передать эти же элементы в
appliedPersonalizationItems, чтобы Sales Ninja понимал, что эксперимент идёт. - При достижении бизнес-цели вызвать POST /goals/reach с
customerIdиз ответа — система привяжет конверсию к экспериментам, которые на пользователя действовали.
# Пример (Python)
import os, requests
SN_TOKEN = os.environ["SN_TOKEN"]
SOURCE = "mobile"
def fetch_personalizations(customer_id: str, screen: str, ctx: dict) -> dict:
r = requests.post(
f"https://api.sales-ninja.me/public/{SOURCE}/v1.0/personalizations/apply",
headers={"X-SN-TOKEN": SN_TOKEN},
json={
"context": {
"pageTitle": screen,
**ctx,
},
"customerId": customer_id,
"appliedPersonalizationItems": [],
},
timeout=15,
)
r.raise_for_status()
return r.json()