Документация
Всё, чтобы запустить A/B-тест на своём сайте: от одной строки кода до чтения итогов и работы через API.
Быстрый старт
- Добавьте сайт в кабинете — получите скрипт сайта.
- Подключите скрипт сайта: строкой в <head> с CDN Сплита, файлом на своём хостинге или в сборку приложения.
- Создайте тест: варианты, доли трафика и цель, которая должна стать чаще.
- Покажите вариант: в коде сайта — или без кода, правками страницы или другим адресом. Цели тоже можно засчитывать без кода: по странице, клику или форме. Готовый код для вашего теста будет на его странице.
- Проверьте по чек-листу и запустите. Дальше Сплит сам скажет, когда можно делать выводы.
Скрипт сайта
После каждой правки тестов Сплит собирает для сайта один минифицированный скрипт — около 3 КБ сжатым. В нём правила всех тестов сайта: кто попадает в тест, какие варианты, правки страницы, цели без кода. Вариант посетителя скрипт считает сам, прямо в браузере, — запросов «какой вариант?» к Сплиту нет, к нам уходят только показы и цели, пачками и в фоне. Если Сплит недоступен, сайт работает как обычно.
Три способа подключить
- С CDN Сплита — рекомендуем
- Строка в <head>. Скрипт обновляется сам: правки тестов доходят до посетителей в течение 5 минут, в остальное время браузер берёт его из кэша.
- На своём хостинге
- Скачайте скрипт на странице сайта в кабинете или забирайте его в деплое и отдавайте со своего сервера или CDN — загрузка сайта не зависит от Сплита совсем. После правок тестов файл нужно обновить. Подробнее — в разделе «Скрипт на своём сайте».
- В сборку приложения
- Импортируйте файл первой строкой — вариант известен сразу при старте, без загрузки и ожидания. Обновляется вместе с выкладкой приложения.
Обычный способ — async
Страница не ждёт загрузку файла: если он недоступен, посетители видят сайт как обычно. Подходит для вариантов, которые меняет код.
<script async src="https://ab.pixeltools.ru/s/ключ.js"></script>Без мигания — синхронно и до стилей
Если вариант меняет вёрстку через CSS и важно, чтобы посетитель не увидел смену, поставьте строку без async самой первой в <head>. Плата за это — страница ждёт скрипт (он маленький и почти всегда берётся из кэша).
<head>
<script src="https://ab.pixeltools.ru/s/ключ.js"></script>
<link rel="stylesheet" href="/styles.css">
</head>Без мигания для правок страницы и редиректа
Если тест меняет страницу без кода или отправляет на другой адрес, поставьте выше кода Сплита строку, которая ненадолго прячет страницу. Сплит снимет скрытие сам, как только применит вариант, а если что-то пойдёт не так — через секунду.
<head>
<!-- 1. Прячет страницу, пока не встанут правки варианта, — не дольше секунды -->
<style>html.ptsab-hide{opacity:0!important}</style>
<script>document.documentElement.classList.add('ptsab-hide');setTimeout(function(){document.documentElement.classList.remove('ptsab-hide')},1000)</script>
<!-- 2. Код Сплита: сам снимет скрытие, как только применит вариант -->
<script async src="https://ab.pixeltools.ru/s/ключ.js"></script>
</head>Согласие на куки
Если на сайте баннер согласия, включите в настройках сайта «Ждать согласия на куки». До согласия скрипт не ставит куку и не шлёт события, а посетитель видит сайт как есть. Согласие передаёт ваш баннер одной строкой:
// Баннер согласия на куки: посетитель нажал «Принимаю»
window.ptsAb?.consent()
// Скрипт сайта вшит в сборку — согласие можно передать заранее
window.ptsAbOptions = {consent: true}Несколько поддоменов
Посетитель определяется по куке на домене сайта. Чтобы на example.ru, app.example.ru и id.example.ru он был одним человеком и видел один вариант, укажите в настройках сайта домен куки .example.ru.
Если на сайте есть Content-Security-Policy
Content-Security-Policy:
script-src 'self' https://ab.pixeltools.ru;
connect-src 'self' https://ab.pixeltools.ru;Конструкторы: Тильда, WordPress и другие
Строка — в поле «Код в <head>», варианты — CSS-правилами там же.
<!-- Тильда, WordPress и другие конструкторы: в «Код в <head>» -->
<script src="https://ab.pixeltools.ru/s/ключ.js"></script>
<!-- Без async и до стилей: вариант встанет до отрисовки, ничего не мигнёт -->
<style>
html[data-ab-hero="b"] .t-btn { background: #0fa9bd; }
</style>Скрипт на своём сайте
Скрипт сайта — обычный JS-файл, брать его с CDN Сплита не обязательно. Положите его к себе — и при загрузке страниц сайт вообще не обращается к Сплиту: правила тестов уже внутри файла, вариант считается в браузере. К нам уходят только показы и цели.
- Скачайте скрипт — кнопка «Скачать скрипт» на странице сайта в кабинете или постоянный адрес
https://ab.pixeltools.ru/s/ключ.js. - Положите файл на свой сервер или CDN, например в
public/split-ключ.js. - Подключите его строкой в <head> — или импортом первой строкой в сборку приложения.
- Обновляйте после правок тестов: создали, запустили или остановили тест — возьмите файл заново. Удобнее всего — в каждом деплое.
Забирать в деплое
# В скрипте деплоя сайта — свежий скрипт Сплита рядом со статикой
curl -fsS -o public/split-ключ.js https://ab.pixeltools.ru/s/ключ.jsПодключить в <head>
<script async src="/split-ключ.js"></script>
<!-- или через библиотеку: init('ключ-сайта', {src: '/split-ключ.js'}) -->Или вшить в сборку приложения
Вариант известен сразу при старте приложения — без загрузки и ожидания.
// main.js — первой строкой
import './split-ключ.js'
if (ptsAb.variant('home-cta') === 'b') {
// новый вариант
}
// Вход на сайте: до этого импорта, например в index.html
// <script>window.ptsAbOptions = {user: 'ID пользователя'}</script>Пока файл не обновлён, посетители видят старые правила: новый тест на сайте не начнётся, а остановленный продолжит показываться (в статистику такие показы уже не попадут). Нужно, чтобы остановка срабатывала сама и быстро, — подключайте скрипт с CDN Сплита.
Библиотека split.js
Для сайтов со сборкой (React, Vue, Vite, webpack) — маленькая библиотека без зависимостей. Строка в <head> не нужна: init() подгрузит готовый файл с правилами тестов сайта — статику с CDN, которую браузер потом берёт из кэша. Вариант считается прямо в браузере, к серверу Сплита за ним никто не ходит. variant() ждёт только загрузку этого файла (на первой странице — десятки миллисекунд, дальше мгновенно из кэша, но не дольше полутора секунд), goal() отметит цель, даже если файл ещё грузится. Не хотите ждать и на первой странице — положите файл к себе (раздел «Скрипт на своём сайте») или считайте вариант на сервере через Split.php.
import {init, variant, value, goal} from './lib/split.js'
// Один раз при старте: подключит скрипт сайта с CDN Сплита.
// Свой хостинг — {src: '/split-ключ.js'}; вход на сайте — {userId: user.id}
init('ключ-сайта')
// Вариант посетителя; null — показывайте как сейчас
if (await variant('home-cta') === 'b') {
showNewButton()
}
const title = await value('home-cta', 'title', 'Как сейчас')
// Цель — после того, как действие случилось
goal('signup') Рядом с каждым файлом — типы TypeScript (.d.ts): автодополнение и проверка работают без настройки. Архив «Всё для фронтенда» содержит библиотеку, обёртки и типы.
Если файл с правилами не загрузился (блокировщик, сеть), variant() вернёт null — показывайте сайт как сейчас. Посетитель останется на контроле и в статистику не попадёт.
Сервер и свои SDK
Сервер: вариант до рендера
Split.php — PHP 8.1+, без зависимостей. Считает вариант тем же способом и по той же куке, что скрипт сайта в браузере: бэк и фронт видят посетителя в одном варианте. Правила берёт из готового файла сайта и кэширует — если Сплит недоступен, работает на последних. Куку посетителя ставит ответом сервера, поэтому Safari её не урезает, а показы и цели отправляет одним запросом уже после того, как посетитель получил страницу.
Архив — готовый Composer-пакет. Распакуйте его в packages/split/, подключите как локальный репозиторий и выполните composer update pixeltools/split — автозагрузка и провайдер Laravel подключатся сами:
{
"repositories": [
{"type": "path", "url": "packages/split"}
],
"require": {
"pixeltools/split": "*"
}
}<?php
use PixelTools\Split\Split;
// Кука посетителя, предпросмотр по ссылке и отправка событий после ответа — сами
$split = Split::fromGlobals('ключ-сайта', userId: $user?->id);
// Вариант до рендера: без мигания и без JS. null — показывайте как сейчас
$hero = $split->variant('home-cta') === 'b' ? 'hero-new' : 'hero';
$title = $split->value('home-cta', 'title', 'Как сейчас');
// Цель, которую знает только сервер: оплата, регистрация через OAuth
$split->goal('purchase', 4990);Laravel
Провайдер делает всё сам: один Split на запрос через DI, пользователь из auth, правила в кэше приложения (Cache::flexible — устаревшие отдаются, пока в фоне не придут свежие), кука без шифрования и отправка событий после ответа. В шаблонах — директивы @variant и @splitValue.
// config/services.php
'split' => [
'key' => env('SPLIT_KEY'),
],
// Провайдер подключается сам (package discovery) — в bootstrap/providers.php ничего добавлять не нужноNode.js, Python и Go
Те же SDK на других языках — по одному файлу без зависимостей. Вариант считается тем же способом, что в браузере и Split.php: это проверяется тестом на сотнях посетителей во всех четырёх языках. Файлы — в карточках выше.
import {Split} from './split-node.mjs'
// Express, Fastify, Next.js — любой обработчик запроса
const split = await Split.fromRequest('ключ-сайта', req, {userId: user?.id})
res.setHeader('Set-Cookie', split.setCookies())
if (split.variant('home-cta') === 'b') {
// новый вариант; null — показывайте как сейчас
}
const title = split.value('home-cta', 'title', 'Как сейчас')
split.goal('signup')
// Показы и цели — после ответа
res.on('finish', () => split.flush())Правила для других языков
Те же правила в JSON — для своего SDK на Go, Python, Node. Расчёт варианта простой, его можно повторить на любом языке:
GET https://ab.pixeltools.ru/s/ключ.json
{
"key": "ключ",
"cookieDomain": ".example.ru",
"endpoint": "https://ab.pixeltools.ru/api/v1/collect",
"experiments": [
{"key": "home-cta", "salt": "x9k2ab1c", "traffic": 100,
"variants": [["a", 50], ["b", 50, {"p": {"title": "Попробовать"}}]]}
],
"goals": [{"n": "thanks", "on": "url", "m": "/thanks"}]
}
// Вариант: FNV-1a 32 бита + fmix32 (как в Split.php)
// в тесте, если hash(salt + ':t:' + visitorId) % 100 < traffic
// вариант — hash(salt + ':v:' + visitorId) % сумма_весов, по весам по порядкуСоздание теста
Мастер в кабинете проводит по четырём шагам. Что значит каждое поле:
- Название и гипотеза
- Для вас: что меняем и что должно вырасти. «Если поднять кнопку выше первого экрана, регистраций станет больше».
- Ключ теста
- Латиница, цифры, - и _. По нему код сайта узнаёт вариант:
ptsAb.variant('home-cta'). После запуска не меняется. - Как показываем
- Кодом на сайте — разработчик показывает вариант в коде. Правками страницы — без кода: новый текст, стиль, скрытие элемента. Разными страницами — у варианта свой адрес. Подробнее — в разделе «Без программиста».
- Варианты
- Первый — контроль, сайт как есть. У каждого — ключ (a, b, c…) и доля. Доли относительные: 50 и 50 — пополам, 1 и 3 — четверть и три четверти.
- Трафик
- Какая часть посетителей попадает в тест. Остальные видят сайт как есть и в статистику не попадают.
- Цели
- Действия, которые должны стать чаще. Основная решает, кто победил; остальные видны рядом — чтобы заметить, если рост одного сломал другое.
- Страницы
- Для тестов на CSS: посетитель засчитывается, когда открыл страницу с этой частью адреса. Для правок страницы — где их применять (пусто — везде). Для разных страниц — исходная страница, с которой посетителей вариантов отправит на их адреса.
Вариант закрепляется за посетителем: он увидит его и при следующих визитах. Поэтому после запуска ключ, варианты и доли не меняются — иначе люди переедут между вариантами и итоги смешаются.
Варианты на сайте
ptsAb.variant('ключ') возвращает вариант посетителя и засчитывает показ. Вызывайте его там, где посетитель увидит отличие: если вызвать на каждой странице, в тест попадут и те, кто до изменённой страницы не дошёл.
import {init, variant} from './split.js'
init('ключ-сайта') // один раз при старте
const v = await variant('home-cta') // null — показывайте как сейчас
if (v === 'b') {
// Кнопка выше
}Пока файл с правилами не загрузился, вариант неизвестен — показывайте сайт как сейчас. Если он так и не загрузился (блокировщик, сеть), посетитель останется на контроле и в статистику не попадёт.
Без программиста
Правки страницы
В мастере выберите «Правками страницы», откройте свой сайт кнопкой «Выбрать на сайте», наведите на элемент и кликните — селектор подставится сам. Что можно сделать с элементом:
- Заменить текст — новый текст вместо старого
- Заменить HTML — новая разметка внутри элемента
- Скрыть — элемент пропадает
- Атрибут — например href=/new-page или src картинки
- Свой CSS — любые стили, без выбора элемента
Правки встают сами, в том числе на элементах, которые сайт дорисовал позже. Посетитель попадает в тест, когда на странице есть элемент, который меняет тест, — так же засчитывается и контроль, поэтому сравнение честное.
Разные страницы
У каждого нового варианта свой адрес — например, новый лендинг. На исходной странице Сплит засчитывает показ и сразу отправляет посетителя варианта на его адрес, сохраняя метки и параметры. Контроль остаётся на месте.
Значения вариантов
В тесте «кодом на сайте» можно задать поля — тексты, цены, флаги — со своим значением у каждого варианта. Код сайта читает их один раз, а менять значения можно в кабинете без выкладки сайта.
// В кабинете у теста hero заданы поля title и price для каждого варианта
const title = ptsAb.value('hero', 'title', 'Как сейчас') // третий аргумент — если посетитель не в тесте
const price = ptsAb.value('hero', 'price', '990')
// split.js / React / Vue
const title = await value('hero', 'title', 'Как сейчас')
const title = useValue('hero', 'title', 'Как сейчас')Цели
ptsAb.goal('ключ') отмечает, что посетитель дошёл до цели. Засчитывается одна конверсия на человека и только после того, как он увидел вариант. Ставьте вызов туда, где действие уже точно случилось.
// После успешной отправки формы (а не по клику на кнопку — форма может не пройти проверку)
form.addEventListener('submit', async (e) => {
e.preventDefault()
const response = await fetch('/lead', {method: 'POST', body: new FormData(form)})
if (response.ok) window.ptsAb?.goal('lead')
})Цели без кода
В мастере у цели выберите, как её засчитать: «Открыл страницу» — по части адреса, например /thanks; «Кликнул по элементу» и «Отправил форму» — по селектору, который можно выбрать прямо на сайте. Сплит поймает это сам. Отправку формы надёжнее засчитывать страницей «спасибо»: событие отправки срабатывает и тогда, когда сервер форму не принял.
Цели Яндекс Метрики и Google Analytics
Если цели уже настроены в Метрике или GA, заново размечать сайт не нужно: выберите тип «Цель Яндекс Метрики» или «Событие Google Analytics» и укажите идентификатор. Сплит поймает вызовы ym(…, 'reachGoal', 'order') и gtag('event', 'purchase'), которые сайт уже делает. А в настройках сайта можно указать счётчик Метрики — тогда варианты уйдут туда параметрами визита.
Выручка
Цель можно считать как выручку: в мастере у цели выберите «Выручка» и передавайте сумму вторым аргументом. Сплит сравнит выручку на посетителя — это главная метрика для магазинов: вариант может давать меньше заказов, но больше денег.
// Цель-выручка: второй аргумент — сумма заказа
ptsAb.goal('purchase', 4990)
// Split.php — то же на сервере, например после оплаты
$split->goal('purchase', $order->total);Просмотры страниц, время на видимой вкладке и клики Сплит считает сам — отдельных вызовов не нужно.
Новые и вернувшиеся
По умолчанию «новый» — тот, у кого не было куки Сплита, когда он попал в тест. Если сайт знает лучше (например, человек зарегистрирован давно, но зашёл с нового устройства), передайте сегмент атрибутом:
{{-- Вошедший давно — «вернувшийся», только что зарегистрировался — «новый» --}}
<script async
src="https://ab.pixeltools.ru/s/ключ.js"
@auth data-segment="{{ auth()->user()->created_at->lt(now()->subDay()) ? 'returning' : 'new' }}" @endauth
></script>Посетители и устройства
Посетитель для Сплита — это браузер на устройстве. При первом визите он получает случайный ID в куке _ptsab на 400 дней, а вариант считается из этого ID. Тот же ID — тот же вариант при каждом визите, без запросов к нам. Поэтому после запуска нельзя менять варианты и доли: иначе люди переедут между вариантами.
Вошедшие пользователи
Если на сайте есть вход, передайте ID пользователя. На новом устройстве такого человека Сплит выведет ID посетителя из ID пользователя — вариант будет тем же, что на других его устройствах, а в статистике он будет одним человеком. Устройство, где человек уже был до входа, остаётся собой: иначе показ до входа и покупка после разъехались бы по двум людям.
<!-- Вошедший пользователь: на всех его устройствах один вариант и один человек в статистике.
К Сплиту уходит только хеш ID вместе с ключом сайта, сам ID — нет -->
<script async src="https://ab.pixeltools.ru/s/ключ.js"
@auth data-user="{{ auth()->id() }}" @endauth></script>
// split.js
init('ключ-сайта', {userId: currentUser?.id})
// Split.php — а в Laravel провайдер возьмёт пользователя из auth сам
Split::fromGlobals('ключ-сайта', userId: $user?->id);Safari и кука с сервера
Safari живут куки, поставленные из JavaScript, только 7 дней, а после перехода по ссылке с рекламными метками — сутки. Кто вернулся позже, получит новый ID и может попасть в другой вариант. Лечится одной строкой на сервере сайта: переставить ту же куку ответом сервера — такие Safari не урезает. Split.php делает это сам.
# В http { }: переставить куку Сплита с сервера, если она пришла от браузера
map $cookie__ptsab $ptsab_cookie {
"~^[\w-]{8,64}$" "_ptsab=$cookie__ptsab; Path=/; Max-Age=34560000; SameSite=Lax";
default "";
}
# В server { }: пустое значение nginx не отправляет
add_header Set-Cookie $ptsab_cookie;Почему не отпечаток браузера
Отпечаток (fingerprint) узнаёт человека по модели устройства, шрифтам и экрану без его ведома. Это персональные данные, для которых нужно согласие; у тысяч людей с одинаковыми телефонами отпечаток совпадает и склеивает их в одного; Safari, Firefox и Brave специально его искажают, и посетитель начинает прыгать между вариантами. Кука плюс ID пользователя надёжнее и честнее.
Инкогнито и очистку кук не обходит никто. Такие посетители засоряют все варианты одинаково, поэтому вывод теста не перекашивается — просто нужно чуть больше трафика.
Аудитория и группы
Кому показывать тест
В мастере, на шаге «Варианты», задайте условия: устройство, источник и кампания (utm или сайт, откуда пришли), новый или вернувшийся, вошёл ли на сайт, язык, параметр адреса или свой атрибут. Все условия должны выполниться. Проверяет их сам скрипт сайта — без запросов. Источник запоминается с первого захода: пришёл из Директа — останется «yandex» и на следующих страницах.
<!-- Свои атрибуты для таргетинга: тариф, город, сегмент CRM — до скрипта сайта -->
<script>window.ptsAbOptions = {attrs: {plan: 'pro', city: 'msk'}}</script>
<!-- В тесте: условие «Свой атрибут сайта» plan равно pro -->Группы взаимоисключения
Тесты на одном месте страницы или на одну цель мешают друг другу. Дайте им одну группу — посетитель попадёт максимум в один из них. Доля трафика теста становится его долей внутри группы; если места в группе не осталось, Сплит не даст запустить тест.
Бандит
Режим «Бандит — заработать больше»: раз в час Сплит отдаёт больше трафика лидеру (не меньше 5% каждому варианту). Уже распределённые посетители остаются в своих вариантах. Бандит экономит деньги на слабом варианте, но вывод о причине у него менее строгий — для проверки гипотезы берите обычный режим.
Контрольная группа сайта
В настройках сайта можно отложить, например, 5% посетителей: они не видят ни одного теста и выкаченного варианта. Сравнение с ними показывает общий эффект всех изменений за месяцы работы — то, что отдельные тесты не покажут.
Выкатка и автостоп
Выкатить победителя без программиста
«Выкатить на всех» на странице теста: тест заканчивается, а выбранный вариант скрипт сайта показывает каждому посетителю. Можно сразу пользоваться выигрышем, а разработчик перенесёт изменение в код, когда будет время. После этого — «Вернуть как было».
Защитные цели
Отметьте у цели «защитная» — например, «Оплатил» в тесте на регистрацию. Если новый вариант значимо её просадит, Сплит сам остановит тест и напишет на почту: регистраций может стать больше, но не ценой денег.
Срок и письма
Можно задать дату остановки — Сплит остановит тест сам. Без даты он напишет, когда появится вывод, когда тест сломается (неверное деление трафика) или замолчит (за сутки ни одного показа). Письма получают владелец сайта и редакторы.
Команда и отчёты
- Команда. На странице сайта пригласите коллег по почте: редактор меняет и запускает тесты, наблюдатель только смотрит отчёты.
- История изменений — внизу отчёта: кто и когда менял, запускал, останавливал и выкатывал тест.
- Ссылка на отчёт — «Поделиться отчётом»: итоги открываются без входа, только чтение. Ссылку можно закрыть в любой момент.
- PDF — «Скачать PDF»: отчёт без кнопок и настроек, готовый для письма или презентации.
Проверка и запуск
На странице теста есть чек-лист: он сам видит, стоит ли скрипт сайта, попадают ли посетители в тест и приходят ли цели.
- Посмотрите варианты до запуска. Откройте сайт с
?ab_ключ=bв адресе — увидите вариант b. Работает и для черновика, в статистику не попадает. - Пройдите путь сами до цели и проверьте, что в чек-листе появилась цель.
- Запустите тест. В течение 5 минут скрипт сайта обновится у посетителей и начнёт делить их на варианты.
// В консоли браузера на своём сайте
ptsAb.visitorId // ваш идентификатор посетителя
ptsAb.variants // {"home-cta": "b"} — какие варианты вам выпали
// Посмотреть конкретный вариант, не попадая в статистику:
// https://example.ru/?ab_home-cta=bКак читать итоги
Сверху отчёта — вердикт одной фразой. Возможные варианты:
- Ждём первых посетителей
- В тест никто не попал. Проверьте скрипт сайта, запуск и вызов ptsAb.variant().
- Собираем данные
- Меньше 100 посетителей в варианте или меньше 10 достижений цели — выводов нет.
- Пока не ясно
- Разница есть, но может быть случайной (p ≥ 0,05). Сплит покажет, сколько ещё ждать.
- Есть победитель
- Вариант лучше контроля и это не случайность (p < 0,05). Можно оставлять его для всех.
- Новый вариант хуже
- Все новые варианты значимо хуже контроля — оставьте как было.
- Разницы нет
- Интервал эффекта уже уместился в ±10%: заметной разницы нет. Выбирайте вариант, который проще поддерживать.
- Сломано деление трафика
- Посетители разошлись по вариантам не так, как заданы доли (проверка SRM). Тест сломан — итогам верить нельзя.
Что значат цифры
- Конверсия — доля посетителей варианта, которые дошли до цели после показа. Для целей-выручки — выручка на посетителя.
- Интервал (усы на полосах) — где на самом деле может быть конверсия. Сильно перекрываются — разница может быть случайной.
- Эффект «от и до» — в каких пределах на самом деле лежит разница с контролем. Честнее одной цифры.
- p — насколько разница может быть случайной. Меньше 0,05 — разнице можно верить.
- Сколько ждать — посетителей на вариант, чтобы текущая разница стала надёжной, и сколько это дней при вашем трафике.
Как считает Сплит
- Можно смотреть каждый день. Обычный тест «врёт», если проверять его по ходу: случайная «победа» рано или поздно мелькнёт. Сплит считает последовательным тестом (mSPRT, как Optimizely): вывод верен в любой момент, сколько бы раз вы ни открывали отчёт.
- Несколько вариантов — поправка Холма: чем больше вариантов, тем строже порог, иначе какой-нибудь «выиграет» случайно.
- Меньше шума — быстрее вывод (CUPED). Сплит учитывает, как посетитель вёл себя за 14 дней до теста, и убирает эту часть разброса. Тот же вывод — на меньшем трафике.
- Проверка деления трафика (SRM). Если посетители разошлись не так, как заданы доли, тест сломан — Сплит скажет об этом вместо вывода. Обычно виноват редирект, ошибка в варианте или боты.
- Боты не считаются. Поисковые роботы, мониторинги и автоматизация видят сайт, но в статистику не попадают.
- Итоги пересчитываются раз в 5 минут.
Дождитесь вердикта и по возможности недели: так тест захватит и будни, и выходные — поведение в них разное.
API
Через API можно забирать итоги в свои отчёты, создавать, запускать и останавливать тесты. Видны только ваши сайты и тесты. Ключ выпускается в настройках кабинета и передаётся в заголовке. Это серверный ключ: на сайт и во фронтенд его не ставьте.
- Адрес
https://ab.pixeltools.ru/api/v1- Ключ
Authorization: Bearer ab_…- Формат
- JSON. Ответ — в поле
data, ошибки проверки — 422 с полемerrors. - Ошибки
- 401 — нет ключа или он отозван, 404 — нет такого сайта или теста у вас, 429 — больше 120 запросов в минуту.
/sitesВаши сайты: адрес скрипта сайта, его правила в JSON и когда сайт последний раз присылал события.
curl https://ab.pixeltools.ru/api/v1/sites \
-H "Authorization: Bearer $AB_KEY"{
"data": [
{
"id": 1,
"name": "example.ru",
"snippet_url": "https://ab.pixeltools.ru/s/k3y.js",
"rules_url": "https://ab.pixeltools.ru/s/k3y.json",
"cookie_domain": ".example.ru",
"last_event_at": "2026-10-26 14:51:09"
}
]
}/sites/{site}/experimentsТесты сайта со статусом, вариантами, целями и числом посетителей.
curl https://ab.pixeltools.ru/api/v1/sites/1/experiments \
-H "Authorization: Bearer $AB_KEY"{
"data": [
{
"id": 7,
"key": "home-cta",
"name": "Кнопка на главной",
"status": "running",
"traffic": 100,
"variants": [{"key": "a", "name": "Как сейчас", "weight": 50}, {"key": "b", "name": "Выше", "weight": 50}],
"goals": [{"key": "signup", "label": "Зарегистрировался"}],
"primary_goal": "signup",
"visitors": 2400,
"started_at": "2026-10-12T10:00:00+03:00",
"stopped_at": null
}
]
}/sites/{site}/experimentsСоздать тест. Создаётся черновиком — запустите отдельным запросом. Поля те же, что в мастере кабинета.
curl -X POST https://ab.pixeltools.ru/api/v1/sites/1/experiments \
-H "Authorization: Bearer $AB_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Кнопка на главной",
"key": "home-cta",
"traffic": 100,
"variants": [{"key": "a", "name": "Как сейчас", "weight": 50}, {"key": "b", "name": "Выше", "weight": 50}],
"goals": [
{"key": "signup", "label": "Зарегистрировался"},
{"key": "purchase", "label": "Оплатил", "metric": "revenue", "on": "ym", "match": "order"}
],
"primary_goal": "signup",
"guardrails": ["purchase"],
"audience": [{"field": "device", "op": "is", "value": "mobile"}],
"layer": "hero",
"allocation": "fixed",
"ends_at": "2026-12-01T12:00:00+03:00"
}'{"data": {"id": 8, "key": "home-cta", "status": "draft", "...": "..."}}/experiments/{id}Один тест.
curl https://ab.pixeltools.ru/api/v1/experiments/7 \
-H "Authorization: Bearer $AB_KEY"{"data": {"id": 7, "key": "home-cta", "status": "running", "...": "..."}}/experiments/{id}/resultsИтоги: вердикт, конверсии с интервалами, p-value, вовлечённость и данные по дням. Параметр segment — all, new или returning.
curl "https://ab.pixeltools.ru/api/v1/experiments/7/results?segment=new" \
-H "Authorization: Bearer $AB_KEY"{
"data": {
"experiment": "home-cta",
"segment": "new",
"primary_goal": "signup",
"verdict": {
"state": "winner",
"variant": "b",
"uplift": 0.214,
"p_value": 0.004,
"required": 3900,
"progress": 1,
"days_left": 0
},
"variants": [
{
"key": "a",
"visitors": 4710,
"pageviews": 2.1,
"time": 96,
"clicks": 5.4,
"goals": {"signup": {"converted": 184, "rate": 0.039, "ci": [0.0338, 0.0449], "uplift": null, "p_value": null}}
},
{"key": "b", "visitors": 4690, "...": "..."}
],
"days": [{"day": "2026-10-12", "variants": {"a": {"visitors": 310, "converted": 11}, "b": {"...": "..."}}}]
}
}/experiments/{id}/startЗапустить тест (или запустить снова после остановки). В течение 5 минут скрипт сайта обновится у посетителей и начнёт делить их на варианты.
curl -X POST https://ab.pixeltools.ru/api/v1/experiments/7/start \
-H "Authorization: Bearer $AB_KEY"{"data": {"id": 7, "status": "running", "...": "..."}}/experiments/{id}/stopОстановить тест: все снова видят сайт как есть, итоги сохраняются.
curl -X POST https://ab.pixeltools.ru/api/v1/experiments/7/stop \
-H "Authorization: Bearer $AB_KEY"{"data": {"id": 7, "status": "stopped", "...": "..."}}/experiments/{id}/shipВыкатить вариант на всех без кода: тест заканчивается, скрипт сайта показывает этот вариант каждому посетителю.
curl -X POST https://ab.pixeltools.ru/api/v1/experiments/7/ship \
-H "Authorization: Bearer $AB_KEY" \
-H "Content-Type: application/json" \
-d '{"variant": "b"}'{"data": {"id": 7, "status": "shipped", "shipped_variant": "b", "...": "..."}}/experiments/{id}Убрать тест в корзину: он останавливается и через 90 дней удаляется навсегда. Вернуть можно в кабинете.
curl -X DELETE https://ab.pixeltools.ru/api/v1/experiments/7 \
-H "Authorization: Bearer $AB_KEY"{"data": {"id": 7, "status": "trashed", "purge_at": "2027-01-24T12:00:00+03:00"}}Частые вопросы
- Сайт мигает при загрузке — видно старый вариант, потом новый
- Вариант применяется после загрузки скрипта. Для правок страницы и редиректа поставьте строку против мигания (раздел «Установка»), для CSS-вариантов — скрипт сайта без async первым в <head>. Для вариантов в коде — показывайте нейтральное состояние, пока вариант не известен, или считайте вариант на сервере через Split.php.
- Посетитель увидит оба варианта?
- Нет: вариант закреплён за ID в куке и не меняется. Вошедшим передайте
data-user— тогда вариант один и на всех их устройствах. Для Safari переставляйте куку с сервера (раздел «Посетители и устройства»). - Сплит замедлит сайт?
- Нет. Скрипт сайта весит около 4 КБ сжатым и лежит на CDN, браузер берёт его из кэша. Вариант он считает за доли миллисекунды, без запросов к нам. События уходят пачками в фоне через sendBeacon — страница их не ждёт. С async скрипт вообще не блокирует загрузку, а если Сплит недоступен, сайт работает как обычно.
- Чем ограничен бесплатный тариф?
- Один сайт, два теста одновременно и 20 000 посетителей в тестах за месяц. Расход видно в настройках. Когда лимит исчерпан, скрипт продолжает работать, идущие тесты собирают данные — нельзя только запустить новый.
- Сайт ходит к Сплиту за каждым вариантом?
- Нет. Правила лежат готовым файлом, вариант считается в браузере или в Split.php. К Сплиту уходят только показы и цели — пачками и в фоне. Сплит недоступен — сайт работает как обычно, посетители видят контроль.
- Можно ли вести несколько тестов на одной странице?
- Да, если они меняют разные вещи и не влияют на одну и ту же цель. Иначе результаты будут мешать друг другу — лучше по очереди.
- Блокировщики рекламы ломают тест?
- Если скрипт заблокирован, посетитель видит контроль и в статистику не попадает. На выводы это не влияет, только чуть уменьшает трафик теста.
- Что если поменять тест после запуска?
- Название, гипотезу и цели — можно. Ключ, варианты и доли — нет: создайте новый тест.
- Сплит мешает Яндекс Метрике?
- Нет, это независимые скрипты. Вариант посетителя можно передать в Метрику параметром визита:
ym(id, 'params', ptsAb.variants). - Как удалить тест и что будет с данными?
- На странице теста или в списке — «В корзину». Тест останавливается и хранится в корзине 90 дней вместе со всеми данными: оттуда его можно вернуть. Через 90 дней он удаляется навсегда. Удалить сразу — кнопка «Удалить навсегда» в корзине.