KillBot API для выявления ботов на сайте

KillBot предоставляет два API, которые можно использовать:

  • АПИ с оплатой за клиента. Это могут делать партнеры-провайдеры. Партнёру-провайдеру предоставляется менеджерский аккаунт в Килбот где он может управлять своими клиентами (создавать аккаунты, назначать подписки и т.п.). Стоимость подписки в этом случае составит 50% от публичных тарифов. Можно интегрировать KillBot в свой сервис с входом по кнопке в личный персонализированный кабинет килбота. Для получения доступа в аккаунт менеджера обратитесь в поддержку.
  • АПИ с оплатой за запросы (тарифицируются только запросы которые классифицированы как пользователи. Стоимость смотрите на странице подписок: https://killbot.ru/subscriptions). Это JS API для программного получения информации, кому принадлежит визит - пользователю или боту. Можете встраивать в своё антифрод или любое другое решение.

API с оплатой за запросы для коммерческого использования (тариф API)

Если вы хотите интегрировать алгоритмы выявления ботов в своё решение, используйте API ниже.

Пример данных которые можно получить по АПИ тут: https://killbot.ru/snpsht.html - это живое JS демо, можно открыть исходный код и скопировать себе.

Идея

Подключение антифрода KillBot по API осуществляется размещением JS-кода на сайте. Код собирает браузерные данные и отправляет их на сервер KillBot. Результат проверки можно получить двумя способами:

  • рекомендуется: событие kbDataReceived — результат приходит автоматически после обработки данных;
  • альтернатива: GET-запрос на /r/get.php с номером сессии.

Для сбора данных подключается скрипт /js/cn.js с одного из серверов KillBot. Скрипт отправляет данные несколькими запросами, общий объём — 5–15 KB.

Скрипт KillBot не собирает персональные данные, не собирает данные ввода форм, не запрашивает доступ к микрофону, геолокации, видеокамере и другим де-идентифицирующим объектам.

Важно: для стабильной работы страница со скриптом Килбота должна открываться по HTTPS.

Самый минимальный вариант: только отправка браузерных данных на сервер Килбота (без ожидания) подключение cn.js . Результат можно запросить в ТЕЧЕНИЕ 5 минут.

Если вам не нужно сразу получать результат в JS — достаточно подключить cn.js. Он сам соберёт и отправит данные на сервер KillBot. Результат проверки можно запросить позже через get.php, когда это понадобится.

Результат проверки на бота нужно запросить в течение 300 секунд после отправки запроса, по истечению этого времени килбот результат проверки НЕ отдаст.

const kbKey = 'YOUR_KEY'; /* ключ из личного кабинета KillBot */

const kbUserID = Math.floor(Math.random() * 900000000);
const kbSessionID = (Date.now() * 10000) + (Math.floor(Math.random() * (99999 - 10000)) + 10000);

const s = document.createElement('script');
s.async = true;
s.src = 'https://data.killbot.ru/js/cn.js?hash_str=' + encodeURIComponent(kbKey)
    + '&r=' + btoa(document.referrer || '')
    + '&url=' + btoa(location.href)
    + '&c=' + kbSessionID
    + '&kbUserID=' + kbUserID
    + '&v=0&rmd' + Math.random();
document.head.appendChild(s);

// kbSessionID и kbUserID сохраните (cookie / localStorage / сервер) —
// по kbSessionID позже можно запросить результат через get.php

Когда нужно проверить результат — сделайте GET-запрос (с JS или с бэкенда):

// kbSessionID — тот же, что передавали в cn.js как параметр c=
fetch('https://data.killbot.ru/r/get.php?waf=1&c=' + kbSessionID)
    .then(function(r) { return r.json(); })
    .then(function(data) {
        if (data.error) {
            console.log('ошибка:', data.m);
            return;
        }
        if (data.l === false) {
            console.log('данные ещё не готовы, повторите запрос через 1–2 сек');
            return;
        }
        console.log('bot:', data.bot, 'snsht:', data.snsht, data);
    });

Если l === false или ответ пустой — данные ещё обрабатываются, повторите запрос через 1–2 секунды (обычно хватает 2–5 попыток).

Когда использовать какой вариант:

  • только cn.js + get.php — минимум кода, результат можно получить с задержкойне более 5 минут;
  • cn.js + kbDataReceived — результат нужен сразу после проверки на стороне JS;
  • fetch + выбор сервера + kbDataReceived — production-интеграция с fallback при блокировках (см. пример выше).

Полный пример: выбор самого быстрого и рабочего сервера + kbDataReceived

Рекомендуемый способ интеграции:

  1. выбрать самый быстрый доступный сервер из списка (запрос /ping);
  2. загрузить cn.js через fetch и выполнить как inline-скрипт (не через <script src> — так надёжнее при блокировках);
  3. при ошибке загрузки переключиться на следующий сервер из списка;
  4. получить результат в обработчике события kbDataReceived.
const kbKey = 'YOUR_KEY'; /* ключ из личного кабинета KillBot — параметра kbKey в JS коде килбота (интеграция как JS)*/

const kbServers = [
    'https://10052024.ru',
    'https://r1.kill-bot.ru',
    'https://data.killbot.ru',
    'https://r3.nl.kill-bot.ru',
    'https://r4.us.kill-bot.ru',
    'https://r6.sg.kill-bot.net'
];

const kbSliderTimeout = 5000;
let kbServerURL = '';
let kbRes = null;

async function kbGetFastestServer(servers) {
    return new Promise(function(resolve) {
        let resolved = false;
        const fallback = 'https://data.killbot.ru';
        let pending = servers.length;

        servers.forEach(function(url) {
            const ctrl = new AbortController();
            const t = setTimeout(function() { ctrl.abort(); }, 6000);

            fetch(url + '/ping', { cache: 'no-store', mode: 'cors', signal: ctrl.signal })
                .then(function(r) {
                    if (!resolved && r.status === 200) {
                        resolved = true;
                        resolve(url);
                    }
                })
                .catch(function() {})
                .finally(function() {
                    clearTimeout(t);
                    pending--;
                    if (!resolved && pending <= 0) resolve(fallback);
                });
        });

        setTimeout(function() {
            if (!resolved) resolve(fallback);
        }, 6050);
    });
}

function kbFireTimeout() {
    setTimeout(function() {
        if (kbRes != null) return;
        document.dispatchEvent(new CustomEvent('kbDataReceived', {
            detail: JSON.stringify({ error: true, m: 'timeout' })
        }));
    }, 2 * kbSliderTimeout + 5000);
}

document.addEventListener('kbDataReceived', function(event) {
    if (kbRes != null) return;
    try {
        if (event.detail) kbRes = JSON.parse(event.detail);
    } catch (e) {
        kbRes = null;
    }
    // Обрабатываем kbRes: bot, fraud, snsht, waf и т.д.
    console.log('KillBot result:', kbRes);
});

(async function kbStart() {
    kbServerURL = await kbGetFastestServer(kbServers);

    const kbUserID = Math.floor(Math.random() * 900000000);
    const kbSessionID = (Date.now() * 10000) + (Math.floor(Math.random() * (99999 - 10000)) + 10000);

    kbFireTimeout();

    const uri = '/js/cn.js?hash_str=' + encodeURIComponent(kbKey)
        + '&p=' + btoa('')
        + '&r=' + btoa(document.referrer || '')
        + '&url=' + btoa(location.href)
        + '&c=' + kbSessionID
        + '&kbUserID=' + kbUserID
        + '&v=0&rmd' + Math.random();

    fetch(kbServerURL + uri)
        .then(function(r) { return r.text(); })
        .then(function(text) {
            const s = document.createElement('script');
            s.text = text;
            s.id = 'kb-c';
            document.head.appendChild(s);
        })
        .catch(function(e) {
            document.dispatchEvent(new CustomEvent('kbDataReceived', {
                detail: JSON.stringify({ error: true, m: e.message || 'cn.js load failed' })
            }));
        });
})();

Живая демо-страница с полной версией (fallback по серверам, pretty-print JSON, описание полей): https://killbot.ru/snpsht.html — можно открыть исходный код и скопировать себе.

 

Альтернатива: получение результата через get.php

Для надёжности финальный ответ лучше проверять и на бэкенде, в теории бот может подменить ответ JS-запроса - но на практике поведенческие боты так не делают - не встречал таких случаев на практике.

Результат можно опрашивать GET-запросом:
https://data.killbot.ru/r/get.php?c={{kbSessionID}}

Ниже пример GET запроса для получения результата средствами JS.

const kbTimeout = 2000;
const kbMaxRequests = 10;
let response = null;
let requestCount = 0;

function makeRequest() {
    if (requestCount >= kbMaxRequests) {
        response ? complete(response) : fail();
        return;
    }

    requestCount++;
    const xhr = new XMLHttpRequest();
    xhr.open('GET', kbServerURL + '/r/get.php?c=' + kbSessionID, true);
    xhr.timeout = 15000;

    xhr.onreadystatechange = function() {
        if (xhr.readyState !== 4) return;
        if (xhr.status === 200) {
            try {
                response = JSON.parse(xhr.responseText);
                if (!response || response.error === true || response.l === false) {
                    setTimeout(makeRequest, kbTimeout);
                } else {
                    complete(response);
                }
            } catch (e) {
                setTimeout(makeRequest, kbTimeout);
            }
        } else {
            setTimeout(makeRequest, kbTimeout);
        }
    };

    xhr.send();
}

function complete(response) {
    // успех
}

function fail() {
    // ошибка / таймаут
}

 

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

{
    "bot": false,          // итог проверки: true — бот / подозрительный визит
    "fraud": false,        // то же, что bot
    "l": true,             // скрипт полностью загружен и все слепки собраны
    "bl": false,           // слепок в чёрном списке (известные боты)
    "wl": true,            // слепок в белом списке (известные браузеры)
    "d": false,            // deny: true — запретить доступ на сайт
    "capt": 0,             // капча: 0 — нет; 1 — капча; 2 — слайдер; 3/31 — alert; 4 — hang; 6 — deny
    "snsht": 2969538378,   // основной слепок браузера (999999 — сгруппированный бот)    
    "net_id": 2696850341,  // идентификатор сети
    "net_t": "home",       // тип сети: home, mob, corp, vpn
    "os": "Windows",       // ОС посетителя
    "sess": "45786830545786830",   // ID сессии (kbSessionID)
    "UserID": "468073784468073784", // ID пользователя (kbUserID)
    "ip": "51.158.237.65", // IP визита
    "t": true,             // показывать метрику: false — не грузить код метрики
    "act": "1",            // подписка активена
    "cv": "abc123...",     // checksum для серверной проверки ответа
    "metr": "44537875",    // ID счётчика Яндекс.Метрики (если настроен)
    "utm": "is_bot",       // имя HTTP-параметра для передачи результата проверки в URL (из настроек)
    "url": "",             // URL редиректа (если задан WAF правилом)
    "waf": { /* см. ниже */ }
}

 

WAF-данные

С их помощью можно создавать правила фильтрации:

killbot:
  UserID: 429434077125846125      // уникальный ID пользователя
  UserID2: 429434077125846125     // альтернативный ID (cross-check)
  bot: false                       // визит от бота?
  capt: 0                          // тип капчи для визита (см. capt выше)
  metr: true                       // показывать метрику
  deny: false                      // блокировка доступа
  man_act: true                    // для слепка задано ручное действие
  solved_early: false              // ранее решал капчу на этом сайте
  solved_early_killbot: false      // ранее решал капчу в экосистеме KillBot
  vpn: false                       // VPN / proxy
  snsht: 65519223                  // слепок браузера
  snsht_org: 695851122             // исходный snsht до группировки ботов
  net_id: 3957945795               // идентификатор сети
  net_t: home                      // home — домашняя; mob — мобильная; corp — корпоративная
  bl: false                        // слепок в blacklist
  wl: true                         // слепок в whitelist
  ffp: 3329686866                  // fingerprint шрифтов
  host: data.killbot.ru            // сервер, обработавший запрос
  adt: false                       // признаки anti-detect / spoofing
  not_solved: false                // часто видит капчу, но не решает
  shows_count: 8                   // сколько раз показывалась капча UserID
  solved_count: 0                  // сколько раз UserID решал капчу
  new_user_killbot: true           // новый UserID в KillBot
  new_user_website: true           // новый UserID на этом сайте
  tm: 0                            // время обработки (сек)
user:
  timezone: Asia/Novosibirsk        // часовой пояс браузера
  locale: ru                        // локаль браузера
net:
  ip: 94.237.108.10                // IP пользователя
  host: 94-237-108-10.example.host // reverse DNS
  asn: 202053                      // ASN
  country: FI                      // страна по IP
  ports: []                        // открытые порты (WebRTC scan)
  ping: true                       // IP пингуется
  ttlOS: Linux                     // ОС по TTL
  ttl: 54
  ttl_b: 52
  rtt: 93.25                       // round-trip time (мс)
request:
  user-agent: Mozilla/5.0 ...
  accept-language: ru-RU,ru;q=0.9
  url: https://example.com/page    // URL, с которого вызван KillBot
  referer:                         // referer
browser:
  name: Chrome
  language: ru-RU
  webdriver: false                  // true — automation (бот)
  innerheight: 919
  innerwidth: 1920
  outerheight: 1040
  outerwidth: 1920
device:
  width: 1920
  height: 1080
  os: Windows
  gc: ANGLE (NVIDIA, ...)           // GPU / WebGL renderer
  fps: 63                          // FPS (requestAnimationFrame)

 

Ошибочный ответ

{
    "error": true,
    "error_code": 100,   // 100 — сессия не найдена; 200 — другая ошибка
    "m": "KillBot session does not exist kbSessionID=255483105"
}