ДАРА ОТПЕЧАТОКДокументация
Документация
ДАРА ОТПЕЧАТОК — облачный сервис идентификации посетителей. Один тег <script> даёт каждому браузеру на вашем сайте постоянный visitor_uuid, а серверу сайта — профиль посетителя: визиты, устройство, признак нескольких аккаунтов на одном устройстве.
Быстрый старт
-
Получите ключи сайта
Откройте личный кабинет → Настройки → Ключи сайтов и создайте ключи. Кабинет выдаст пару: публичный ключ
pk_…для страниц и секретныйsk_…для сервера. Секретный ключ показывается один раз. -
Добавьте скрипт на сайт
Вставьте перед закрывающим тегом
</head>:<script src="https://fingerprint.daratech.ru/sdk/dara-fingerprint.js"></script> <script> DaraFingerprint.init({ apiUrl: 'https://fingerprint.daratech.ru/api', apiKey: 'pk_ВАШ-ПУБЛИЧНЫЙ-КЛЮЧ' }); </script>SDK запишет посетителю cookie
dara_visitorс егоvisitor_uuid. Пока cookie жива, посетитель узнаётся на любой странице сайта и при смене сети. -
Продлевайте cookie с сервера
Safari удаляет cookie, записанные скриптом, через 7 дней без визита. Чтобы посетитель не терялся, отвечайте с сервера сайта заголовком
Set-Cookieи передайте SDKcookieServerManaged: true— см. Cookie на сервере.
Ключи сайта
| Ключ | Где | Методы |
|---|---|---|
| pk_… | Код страниц. Виден любому, поэтому данных посетителей по нему не отдаётся | /session/init (SDK вызывает его сам). Методы /track/pageview, /track/action и /collect/geolocation оставлены для старых интеграций: SDK 4.x их не вызывает, новым сайтам они не нужны |
| sk_… | Только сервер сайта. Хранится у нас как хеш | /visitor/info, /collect/field, /visitor/delete |
Ключ передаётся заголовком X-API-Key или Authorization: Bearer sk_…. Посетители, сессии и совпадения видны только в пределах сайта: по ключу другого сайта методы отвечают 404.
Серверные методы (/visitor/info, /collect/field, /visitor/delete) по публичному ключу отвечают 401.
Конфигурация SDK
Параметры DaraFingerprint.init(options):
| Параметр | Тип | Описание |
|---|---|---|
| apiUrl | string | Обязателен: https://fingerprint.daratech.ru/api. Без него SDK шлёт запросы на /api вашего же сайта |
| apiKey | string | Публичный ключ сайта pk_… |
| cookieName | string | Имя cookie посетителя. По умолчанию: dara_visitor |
| cookieDays | number | Срок cookie в днях. По умолчанию: 365 |
| cookieServerManaged | boolean | true — cookie продлевает ваш сервер (Cookie на сервере), и SDK не переписывает её скриптом, пока значение не изменилось. По умолчанию: false — SDK продлевает cookie сам на каждой загрузке |
| debug | boolean | Вывод логов в консоль. По умолчанию: false |
Как работает
Посетитель — это cookie dara_visitor на вашем сайте. Отпечаток устройства личностью не считается: у одинаковых устройств он одинаковый. Два человека с iPhone одной модели, версии iOS и языка дают один и тот же отпечаток — и получают разные visitor_uuid.
SDK собирает сигналы браузера, сервер считает из них хеш устройства. Если cookie потерялась, прежний visitor_uuid возвращается (match: "restored") только при выполнении всех условий:
- устройство уникально на сайте: не iOS и не iPadOS, за 30 дней с ним не было трёх и более посетителей, защита браузера от отпечатков не меняет его сигналы;
- за 30 дней с этим устройством был ровно один посетитель;
- он заходил из той же сети (IPv4 /24, IPv6 /48), и в этой сети не больше 20 посетителей сайта;
- он не активен прямо сейчас из другой сети.
Иначе создаётся новый посетитель, а совпадение по устройству записывается как возможное: оно видно в /visitor/info и в кабинете, но профиль не меняет. Разные люди автоматически не склеиваются.
Cookie на сервере
Safari (ITP) ограничивает cookie, записанные из JavaScript, семью днями. Cookie из ответа вашего сервера живёт полный срок. Продлевайте её на каждом ответе страницы, если значение — UUID:
// PHP, до вывода страницы
$uuid = $_COOKIE['dara_visitor'] ?? '';
if (is_string($uuid) && preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $uuid)) {
setcookie('dara_visitor', strtolower($uuid), [
'expires' => time() + 400 * 86400,
'path' => '/',
'secure' => true,
'samesite' => 'Lax',
'httponly' => false, // SDK читает cookie из JavaScript
]);
}
И передайте SDK cookieServerManaged: true. Без этой опции SDK на каждой загрузке переписывает cookie скриптом, и Safari снова ставит ей потолок в 7 дней — продление с сервера тогда ничего не даёт:
DaraFingerprint.init({
apiUrl: 'https://fingerprint.daratech.ru/api',
apiKey: 'pk_ВАШ-ПУБЛИЧНЫЙ-КЛЮЧ',
cookieServerManaged: true
});
Сигналы
В хеш устройства входят сигналы, которые не меняются у одного браузера:
- Canvas — различия отрисовки текста и фигур
- Math — платформенные отличия тригонометрических функций
- GPU: WebGL Renderer и Vendor
- Экран, colorDepth, devicePixelRatio, количество точек касания
- Ядра CPU, объём памяти, платформа
- Часовой пояс (IANA-название) и языки
User-Agent с версией браузера, тип сети, доступная область экрана, Do Not Track и число плагинов сохраняются в сессии, но в хеш не входят: у одного человека они меняются.
POST /session/init
SDK вызывает этот метод автоматически. Ключ — публичный.
POST https://fingerprint.daratech.ru/api/session/init
Content-Type: application/json
X-API-Key: pk_ВАШ-ПУБЛИЧНЫЙ-КЛЮЧ
{
"visitor_uuid": "<UUID из cookie dara_visitor>",
"session_uuid": "<UUID вкладки>",
"fingerprint_data": { "canvasFp": "…", "gpuRenderer": "…", "screen": "1920x1080", … },
"page_url": "https://example.com/",
"user_agent": "Mozilla/5.0...",
"screen_resolution": "1920x1080"
}
{
"success": true,
"visitor_uuid": "0f8c2a4e-…", // запишите в cookie dara_visitor
"session_uuid": "7d1e…", // uuid сессии вкладки: присланный или новый
"session_id": 42,
"match": "cookie", // cookie | restored | new
"confidence": 1.0, // 1.0 cookie, 0.9 restored, 0 new
"is_identified": false, // есть email или телефон
"is_ambiguous": false, // в истории, вероятно, несколько людей
"fp_version": 2,
"merged_from": null, // устарело: "fingerprint" при match = restored
"visit_count": 7,
"first_visit": "2026-04-12 09:23:11",
"recent_visits": [
{ "date": "2026-05-24 14:00:00", "browser": "Chrome", "os": "Windows 10", "device_type": "desktop" }
]
}
visitor_uuid обязательно в формате UUID, иначе ответ 400. Если uuid принадлежит другому сайту, выдаётся новый. session_uuid в ответе отличается от присланного, если сессия с присланным uuid принадлежит другому посетителю или сайту (вкладка пережила смену cookie): тогда сессия заводится под новым uuid, и его нужно передавать дальше. SDK 4.2 делает это сам.
POST /visitor/info
Профиль посетителя для сервера сайта. Ключ — секретный. Посетитель чужого сайта — 404.
{
"success": true,
"visitor": {
"uuid": "…", "is_identified": true, "email": "…", "phone": null, "first_name": "…", "last_name": null,
"total_visits": 7, "total_actions": 12, "created_at": "2026-04-12 09:23:11", "last_visit_at": "…",
"is_bot": false, // все сессии посетителя — роботы
"last_ip_kind": "regular" // regular | mobile | hosting | proxy | null
},
"ambiguous": false,
"device": {
"hash_prefix": "3fa1c9d2",
"is_common": false, // true — по устройству людей не различить
"common_reason": null, // low_entropy_platform | many_visitors | many_networks | unstable_signals
"visitors_on_device_90d": 2
},
"possible_matches": [
{ "visitor_uuid": "…", "confidence": 0.6, "reasons": ["same_device"],
"is_common_device": false, "last_seen_at": "…", "is_identified": true }
],
"multi_account": {
"suspected": true, // на этом устройстве другой аккаунт с другим email
"other_identified": 1,
"same_browser_emails": 0, // другие email из форм этого же браузера
"confidence": 0.6
},
"current_session": null, // как строка sessions, если передан session_uuid
"sessions": [
{ "session_uuid": "…", "created_at": "…", "device_type": "desktop", "browser": "Chrome", "os": "Windows 10",
"ip_address": "203.0.113.7", "landing_page": "https://example.com/", "page_views": 3, "actions_count": 1,
"utm_source": "yandex", "city": "Казань", "country": "Россия", "isp": "…",
"ip_kind": "regular", // hosting и proxy — отметка, а не приговор: через них ходят и люди с VPN
"bot_reason": null } // user_agent | webdriver | null
],
"identification_events": [ { "event_type": "email_match", "confidence": 0.99, "event_data": { … }, "created_at": "…" } ],
"linked_profiles": [ { "link_type": "email", "confidence": 1.0, "visitor_uuid": "…", … } ],
"collected_data": [ { "field_type": "email", "field_name": "registration_email", "parsed_value": "…", "created_at": "…" } ]
}
Все поля — только вашего сайта: сессии, события, данные форм и связанные профили других сайтов не отдаются никогда. Даты — ГГГГ-ММ-ДД ЧЧ:ММ:СС по UTC. Сессий в ответе — 10 последних, событий и данных форм — по 20.
Возможные совпадения: 0,3 — общее устройство, 0,6 — уникальное устройство из разных сетей, 0,8 — уникальное устройство из одной сети. Для общего устройства multi_account.suspected всегда false.
POST /collect/field
Данные из форм: email, телефон, имя. Ключ — секретный. session_uuid необязателен: без него данные привязываются к последней сессии посетителя на сайте. Совпадения email и телефона ищутся только среди посетителей вашего сайта.
{
"visitor_uuid": "0f8c2a4e-…",
"field_type": "email", // email | phone | name | text
"field_name": "registration_email",
"field_value": "user@example.com"
}
Ответ — {"success": true, "data_id": 123, "parsed_value": "user@example.com"}: parsed_value — нормализованное значение (email в нижнем регистре, телефон цифрами) или null, если значение не распознано.
POST /visitor/delete
Удаление данных посетителя по его запросу (152-ФЗ). Ключ — только секретный (sk_…). В теле — ровно одно из полей:
{ "visitor_uuid": "0f8c2a4e-…" } // один профиль: uuid из cookie dara_visitor
{ "email": "user@example.com" } // все профили вашего сайта с этой почтой
{ "phone": "+7 999 123-45-67" } // все профили с этим телефоном (нормализуется как в /collect/field)
Почта и телефон удобны, когда человек пишет «удалите мои данные» и uuid его браузера неизвестен: у одного человека бывает несколько профилей (телефон, ноутбук), и находятся все, в которых почта или телефон есть в профиле или в данных форм вашего сайта.
{
"success": true,
"visitors_found": 2,
"visitors_removed": 2, // удалены целиком; остальные остались другому сайту (см. ниже)
"deleted": { "sessions": 5, "page_views": 31, "actions": 4, "form_data": 3,
"identification_events": 2, "device_links": 1 },
"has_more": false // true — профилей больше 100: повторите тот же запрос
}
Удаляется всё, что собрано на вашем сайте: сессии со страницами и действиями, данные форм, события идентификации, возможные совпадения устройства. Профиль без других данных удаляется целиком. Если этого же посетителя знает другой сайт (до версии 2 cookie могла быть общей), профиль остаётся ему, но почта, телефон, имя и «последние» поля в нём пересчитываются только из его данных, а ваш сайт посетителя больше не видит.
Повтор безопасен: если удалять нечего, ответ — 200 с нулями. Каждый вызов, который что-то удалил, записывается в журнал действий кабинета — без самой почты и телефона. Копии базы хранятся 7 дней: через неделю удалённого нет и в них. Удалить посетителя можно и в кабинете — кнопкой в его карточке.
Если посетитель снова зайдёт на сайт, SDK соберёт данные заново: прекратить сбор — задача сайта (не подключать SDK без согласия).
Ошибки и пределы
Ошибка — ответ с кодом HTTP и телом {"success": false, "error": "текст"}. Текст — для человека и может меняться, решения принимайте по коду:
| Код | Когда |
|---|---|
| 400 | нет visitor_uuid или он не UUID, тело не JSON; в /visitor/delete — не ровно одно из полей или почта, телефон не распознаны |
| 401 | ключа нет, он неверный или отозван; публичный ключ в серверном методе |
| 403 | домен страницы не в списке разрешённых доменов сайта |
| 404 | посетителя нет или он принадлежит другому сайту — по 404 на заведомо несуществующий uuid удобно проверять, что ключ действует |
| 429 | слишком часто с одного IP: методы кода страницы (/session/init и старые методы публичного ключа) — 10 запросов в секунду с запасом 40. Серверные методы с секретным ключом частотой не ограничены |
| 500, 503 | сбой на нашей стороне — повторите позже |
С callback
DaraFingerprint.init({
apiUrl: 'https://fingerprint.daratech.ru/api',
apiKey: 'pk_ВАШ-ПУБЛИЧНЫЙ-КЛЮЧ'
}).onReady(function (result) {
console.log('visitor_uuid:', result.visitor_uuid);
console.log('Как узнан:', result.match); // cookie | restored | new
console.log('Есть контакты:', result.is_identified);
});
// То же событием
window.addEventListener('dara:ready', function (e) {
console.log(e.detail.visitor_uuid, e.detail.match, e.detail.is_ambiguous);
});
PHP
Проверка при регистрации: нет ли на этом устройстве другого аккаунта. Сервер берёт uuid из cookie и вызывает API секретным ключом.
function daraCall(string $path, array $data): array
{
$ch = curl_init('https://fingerprint.daratech.ru/api' . $path);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 3,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . getenv('DARA_SECRET_KEY'), // sk_…
],
CURLOPT_POSTFIELDS => json_encode($data),
]);
$raw = curl_exec($ch);
return $raw !== false ? (json_decode($raw, true) ?? []) : [];
}
$uuid = $_COOKIE['dara_visitor'] ?? '';
if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $uuid)) {
daraCall('/collect/field', [
'visitor_uuid' => $uuid,
'field_type' => 'email',
'field_name' => 'registration_email',
'field_value' => $email,
]);
$info = daraCall('/visitor/info', ['visitor_uuid' => $uuid]);
$possibleMultiAccount = !empty($info['multi_account']['suspected']);
}
Нужны ещё веб-аналитика и рекомендации? Все продукты ДАРА — на daratech.ru.