ДАРА АНАЛИТИКА
Разделы документации

Документация

API: посетители

Атрибуты посетителей без персональных данных — POST /visitors/attributes, GET /visitors/{visitor_id}, GET /network — и данные о посетителях с сервера POST /users. Примеры на curl, PHP и Python.

Общие правила — ключ, формат, идентификаторы, коды ошибок — и справочник всех методов и схем из описания OpenAPI находятся в разделе API.

Атрибуты посетителей

POST /visitors/attributes возвращает атрибуты посетителей вашего сайта: пол, возрастную группу, географию, детей, компанию, интересы, категории покупок и параметры посетителя. Персональных данных, точного возраста и года рождения в ответе нет.

curl -X POST https://analytics.daratech.ru/api/v1/visitors/attributes \
  -H "Authorization: Bearer $DARA_ANALYTICS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "visitors": [
      {"ref": "u-17", "user_id": "u-17"},
      {"ref": "anon-1", "visitor_id": "0b7e6f8a-3c2d-4e5f-9a1b-2c3d4e5f6a7b"}
    ]
  }'
  • В одном запросе — до 100 посетителей. В каждом элементе нужен хотя бы один идентификатор: user_id, visitor_id или fingerprint_uuid.
  • ref — ваша метка до 64 символов, возвращается как есть. По ней удобно сопоставлять ответы с запросами.
  • fingerprint_uuid учитывается, только если к сайту подключён DARA Fingerprint.
  • Посетитель ищется по порядку: user_idvisitor_idfingerprint_uuid. Используется первый найденный на сайте.
  • Результаты идут в том же порядке, что элементы запроса.
  • Ошибка формы любого элемента — нет идентификатора, ref длиннее 64 символов, user_id длиннее 191, неверный UUID, больше 100 элементов — отклоняет весь запрос ответом 422 с кодом validation_failed; в details — поле вида visitors[3].visitor_id.
  • Метод только читает: он не записывает посетителей и не открывает данных сети.

Ответ 200:

{"results": [{
  "ref": "u-17", "found": true,
  "attributes": {
    "gender":    {"value": "female", "confidence": 0.99, "source": "network"},
    "age_group": {"value": "25_34", "confidence": 0.95, "source": "own"},
    "geo":       {"country": "RU", "region": "Татарстан", "city": "Казань", "method": "ip", "source": "own"},
    "children":  {"value": [{"age_group": "3_6"}], "source": "network"},
    "company":   {"type": "legal", "industry": "Оптовая и розничная торговля", "region": "Москва", "source": "network"},
    "interests": [{"topic_id": 1204, "path": "Семья и дети > Беременность", "share": 0.31, "sensitive": true, "source": "network"}],
    "purchases": [{"category_id": 537, "path": "Детские товары > Подгузники", "segment": "mid", "source": "network"}],
    "params": {"plan": "gold"}
  }}]}
  • source — откуда значение: own — по наблюдениям ваших сайтов, network — из сети ДАРА. Своё значение важнее сетевого: сетевое приходит, только если своего нет.
  • confidence — уверенность от 0 до 1. У age_group уверенность бывает null.
  • geo приходит со всеми ключами: неизвестная часть — null. geo.methodip, если место определено по IP-адресу визитов, и form, если по формам и данным сайтов. Регион и город — названиями, не длиннее 100 символов.
  • company — тип, отрасль (раздел ОКВЭД 2) и регион компании. ИНН и название компании в ответ не входят; у individual отрасли и региона нет.
  • interests — до 20 тем, самые заметные первыми. purchases — категории покупок за 180 дней; segmentnull, если для категории сегмент не считается.
  • sensitive — интерес относится к чувствительной теме.
  • params — параметры посетителя в том виде, в каком их видят отчёты «Параметры посетителя»: вложенные объекты разворачиваются в ключи через точку, значения приходят строками. Например, {"company": {"size": 50}} приходит как {"company.size": "50"}.
  • Неизвестный посетитель{"ref": "anon-1", "found": false}. ref без значения в ответ не попадает.
  • Атрибут без значения в ответ не попадает.

Коды значений

Поле Значения
age_group lt14, 14_17, 18_24, 25_34, 35_44, 45_54, 55_64, 65p
children[].age_group 0_2, 3_6, 7_10, 11_13, 14_17
purchases[].segment low — эконом, mid — средний, high — премиум
company.type legal — юрлицо, individual — ИП или физлицо
gender.value male, female

Когда приходят сетевые значения

  • Сайт — участник сети, и хиты с тегом приходили за последние 7 дней. Иначе в ответе только значения с source: own.
  • Через API без установленного тега данные сети не выдаются.
  • Если посетитель связан с человеком через email или телефон, сетевые значения открываются после окончания визита, в котором ключ ввели, и в пределах суточных лимитов. Посетитель, которому открытие не досталось, приходит без сетевых значений.
  • Интересы и категории покупок берутся списком целиком: есть хотя бы один свой интерес — сетевых интересов в ответе нет.
  • Пользователь сайта, связанный с email через POST /users, получает сетевые значения, только если он связан с посетителем сайта, у которого есть хиты не от робота.

Правила подробно — в разделе Сеть ДАРА.

Кеш и проверка ключа

  • Ответ кешируется на 60 секунд по сайту и идентификатору: частые повторы одного и того же посетителя не дают свежих данных. Кешируются только найденные посетители — found: false при повторе проверяется заново.
  • Кеш сбрасывается сам, когда меняются настройки сети или участие сайта в сети. Проверка ключа и лимит запросов действуют и для ответов из кеша.
  • Чтобы проверить ключ, достаточно запроса со случайным UUID в visitor_id: ответ 200 — ключ действует, 401 — ключ неверен или отозван, 403 — сайт заблокирован.

Один посетитель

GET /visitors/{visitor_id} возвращает то же для одного посетителя и дополнительно поля first_visit_at, last_visit_at и visits — первый и последний визит и число визитов на этот сайт. Посетитель ищется только по visitor_id.

curl https://analytics.daratech.ru/api/v1/visitors/0b7e6f8a-3c2d-4e5f-9a1b-2c3d4e5f6a7b \
  -H "Authorization: Bearer $DARA_ANALYTICS_KEY"

Ответ 200 — без обёртки results и без ref:

{"found": true,
 "attributes": {
   "gender":    {"value": "female", "confidence": 0.99, "source": "network"},
   "age_group": {"value": "25_34", "confidence": 0.95, "source": "own"},
   "geo":       {"country": "RU", "region": "Татарстан", "city": "Казань", "method": "ip", "source": "own"},
   "children":  {"value": [{"age_group": "3_6"}], "source": "network"},
   "company":   {"type": "legal", "industry": "Оптовая и розничная торговля", "region": "Москва", "source": "network"},
   "interests": [{"topic_id": 1204, "path": "Семья и дети > Беременность", "share": 0.31, "sensitive": true, "source": "network"}],
   "purchases": [{"category_id": 537, "path": "Детские товары > Подгузники", "segment": "mid", "source": "network"}],
   "params": {"plan": "gold"}
 },
 "first_visit_at": "2026-03-02T09:14:05.120Z",
 "last_visit_at": "2026-09-14T18:40:11.905Z",
 "visits": 17}
  • Неизвестный посетитель — тоже 200: {"found": false}.
  • visitor_id не UUID — 422 с кодом validation_failed.
  • first_visit_at и last_visit_atnull, если визитов за время хранения данных нет.

Настройки сети

GET /network отдаёт настройки сети, которые нужны потребителям атрибутов:

curl https://analytics.daratech.ru/api/v1/network \
  -H "Authorization: Bearer $DARA_ANALYTICS_KEY"
{"share_sensitive": true, "settings_version": 12}
  • share_sensitive: false — передача чувствительных тем между клиентами выключена: такие темы убираются из сетевых интересов в течение 10 минут. Если вы храните атрибуты у себя, не используйте сетевые интересы с sensitive: true.
  • settings_version растёт при каждом изменении настроек сети. Запрашивайте метод раз в час.

Данные о посетителях

POST /users передаёт то, что ваш сайт знает о посетителях. Поля и правила — в разделе Данные о посетителях.

curl -X POST https://analytics.daratech.ru/api/v1/users \
  -H "Authorization: Bearer $DARA_ANALYTICS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "users": [
      {"user_id": "u-501", "visitor_id": "0b7e6f8a-3c2d-4e5f-9a1b-2c3d4e5f6a7b", "email": "user@example.com", "gender": "female", "birth_year": 1991, "city": "Казань", "children": [{"birth_year": 2019}], "interests": ["Путешествия"], "params": {"plan": "gold"}},
      {"user_id": "u-502", "phone": "+79000000000", "age": 34},
      {"user_id": "u-503", "city": null}
    ]
  }'

Ответ 202 Accepted:

{"results": [{"index": 0, "ok": true}, {"index": 1, "ok": true}, {"index": 2, "ok": true}]}
  • В одном запросе — до 500 записей, в каждой — visitor_id или user_id.
  • Переданные поля заменяются, null очищает поле, непереданные не меняются.
  • Повтор записи безопасен: поля заменяются теми же значениями. Пачку после сетевой ошибки, 429 или 5xx можно отправить ещё раз. interests — сигнал: каждая присланная строка снова усиливает свои темы, поэтому интересы передавайте, когда они изменились.
  • Запись, в params которой есть ключ с персональными данными (email, phone, name, first_name, last_name, middle_name, address, birth_date, passport на любой глубине, без учёта регистра), получает "ok": false и ошибку с кодом pii_not_allowed. Поля email и phone самой записи — не ошибка. Других кодов отказа записи нет.
  • Ошибка формы любой записи отклоняет весь запрос ответом 422 с кодом validation_failed.
  • Если приём временно недоступен, ответ — 503 с кодом unavailable и заголовком Retry-After: ни одна запись не сохранена, пачку нужно отправить ещё раз.
  • null очищает поле: отменяет то, что ваш сайт передавал через POST /users по этому полю. Подробнее — в разделе Данные о посетителях.

Лимиты

Методы Лимит на ключ
/visitors/*, /network 50 запросов в секунду на все три метода вместе
/users 20 запросов в секунду — общий лимит с /conversions и /orders

Сверх лимита — ответ 429 с кодом rate_limited и заголовком Retry-After. Ответ из кеша тоже расходует лимит. Все пределы — в разделе Ошибки и лимиты.

Примеры на PHP

Функция dara_analytics() та же, что в разделе API.

<?php
function dara_analytics(string $method, string $path, ?array $body = null): array
{
    $ch = curl_init('https://analytics.daratech.ru/api/v1' . $path);
    $options = [
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getenv('DARA_ANALYTICS_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => 3,
        CURLOPT_TIMEOUT => 30,
    ];
    if ($body !== null) {
        $options[CURLOPT_POSTFIELDS] = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
    }
    curl_setopt_array($ch, $options);
    $response = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    if ($response === false || $status >= 400) {
        throw new RuntimeException('ДАРА АНАЛИТИКА: HTTP ' . $status . ' ' . ($response ?: curl_error($ch)));
    }
    return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}

$attributes = dara_analytics('POST', '/visitors/attributes', ['visitors' => [
    ['ref' => 'u-17', 'user_id' => 'u-17'],
]]);
foreach ($attributes['results'] as $visitor) {
    if (!$visitor['found']) {
        continue;
    }
    $gender = $visitor['attributes']['gender']['value'] ?? 'не определён';
    $ageGroup = $visitor['attributes']['age_group']['value'] ?? 'не определена';
    echo $visitor['ref'], ': ', $gender, ', ', $ageGroup, "\n";
}

$network = dara_analytics('GET', '/network');
$shareSensitive = $network['share_sensitive'];

dara_analytics('POST', '/users', ['users' => [
    ['user_id' => 'u-501', 'email' => 'user@example.com', 'gender' => 'female', 'birth_year' => 1991],
]]);

Примеры на Python

import os

import httpx

api = httpx.Client(
    base_url="https://analytics.daratech.ru/api/v1",
    headers={"Authorization": f"Bearer {os.environ['DARA_ANALYTICS_KEY']}"},
    timeout=30,
)

response = api.post("/visitors/attributes", json={"visitors": [
    {"ref": "u-17", "user_id": "u-17"},
]})
response.raise_for_status()
for visitor in response.json()["results"]:
    if not visitor["found"]:
        continue
    attributes = visitor["attributes"]
    gender = attributes.get("gender", {}).get("value", "не определён")
    age_group = attributes.get("age_group", {}).get("value", "не определена")
    print(visitor["ref"], gender, age_group)

network = api.get("/network")
network.raise_for_status()
share_sensitive = network.json()["share_sensitive"]

api.post("/users", json={"users": [
    {"user_id": "u-501", "email": "user@example.com", "gender": "female", "birth_year": 1991},
]}).raise_for_status()