Data API (раніше описаний тут як Server API) дозволяє вашому бекенду читати дані ідентифікації, які TRACIO вже зібрав для вашого workspace: історію відвідувача, окремі сесії та лічильники активності за коротке вікно. Кілька маршрутів також записують — записи акаунтів, користувацькі поля та елементи списків, — щоб ваш бекенд міг доповнювати те, що відомо TRACIO.
Він доповнює Webhooks, а не замінює їх:
| Webhooks | Data API | |
|---|---|---|
| Напрямок | TRACIO надсилає на вашу кінцеву точку | Ваш бекенд запитує сам, коли потрібно |
| Момент | У момент кожної ідентифікації | Будь-коли, у межах вашого вікна зберігання |
| Краще для | Реакції на подію | Пошуку даних у момент рішення, дозавантажень, розбору інцидентів |
Обидві поверхні доступні з тарифу Pro і вище.
https://api.tracio.ai/v2Це окремий хост — не той, що у браузерної кінцевої точки (edge.tracio.ai), і не
той, що у дашборда (app.tracio.ai). Усі три різні: браузер спілкується з edge вашим
публічним ключем, ваш бекенд спілкується з Data API вашим секретним ключем.
Маршрути /v1 видалено. Використовуйте /v2: маршрути ті самі, а кожен ключ JSON і
кожен параметр запиту записано в snake_case (visitor_id, risk_score,
min_risk_score). Ключі всередині ваших власних словників fields і labels — це ваші
дані, і вони зберігають початкове написання. JavaScript SDK зберігає свій інтерфейс у
camelCase.
Кожен запит несе ваш секретний ключ як bearer-токен:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"Data API працює лише в режимі server-to-server. Заголовки CORS навмисно не повертаються, тож браузер не може його викликати — саме це утримує ваш секретний ключ поза клієнтським кодом. Ніколи не віддавайте секретний ключ у браузер.
Створіть його в дашборді, у розділі API Keys, обравши тип secret.
tracio_sk_ плюс 43 символи, разом 53. Дашборд показує
його за першими кількома символами, щоб ви могли відрізняти ключі один від одного.404, так само як для даних, яких не існує.Ротація випускає новий ключ і залишає старий робочим ще 7 днів, тож ви можете викотити заміну без простою. Задеплойте новий ключ, переконайтеся, що трафік перейшов на нього, і дайте старому спливти. Публічні ключі не ротуються — вони не є секретами й за задумом видимі у вихідному коді вашої сторінки.
| Метод | Шлях | Повертає |
|---|---|---|
GET | /v2/visitors/{visitor_id} | Агреговану історію одного відвідувача плюс його останню сесію |
GET | /v2/visitors/{visitor_id}/sessions | Посторінковий список сесій цього відвідувача |
GET | /v2/visitors/{visitor_id}/sessions/latest | Одну найсвіжішу сесію |
GET | /v2/visitors/{visitor_id}/velocity | Лічильники активності за коротке вікно |
GET | /v2/sessions/{request_id} | Одну сесію за ідентифікатором її запиту |
POST | /v2/accounts/metadata | Прив'язує відображувані імена та email до ваших ідентифікаторів акаунтів |
POST | /v2/events/fields | Прикріплює користувацькі поля до візиту після завантаження сторінки |
POST | /v2/events/fields/delete | Стирає користувацькі поля візиту — сам візит не зачіпається |
GET | /v2/lists | Списки вашого workspace: id, назва, тип (дія), режим, кількість елементів |
POST | /v2/lists/{list_id}/entries | Додає значення до списку, за бажання з TTL |
POST | /v2/lists/{list_id}/entries/delete | Видаляє значення зі списку |
GET | /.well-known/webhook-keys | Публічні ключі для підпису платформи у вебхуків (без автентифікації) |
Той самий ключ і той самий хост обслуговують і API рішень, повністю в snake_case:
| Метод | Шлях | Призначення |
|---|---|---|
POST | /v2/transactions | Синхронне рішення APPROVE / REVIEW / DECLINE щодо бізнес-події — Business і вище, крім партнерської конверсії (account_register або deposit з affiliate_id), доступної на будь-якому тарифі з доступом до API |
GET | /v2/transactions/{transaction_id} | Повторно прочитати рішення разом із його міткою та чинним станом — Business і вище, крім транзакції, атрибутованої партнеру |
PUT, DELETE | /v2/transaction-labels | Встановити або зняти мітку результату для транзакцій, до 50 за раз — Business і вище |
GET | /v2/transaction-labels/value-set | Допустимі значення міток з їхньою полярністю — Business і вище |
POST | /v2/logins/assess | Оцінити вхід: allow / challenge / review / deny з причинами |
POST, GET | /v2/accounts/{user_id}/trusted-devices | Зробити пристрій візиту довіреним для акаунта після вашої додаткової перевірки або отримати список довірених пристроїв акаунта |
DELETE | /v2/accounts/{user_id}/trusted-devices/{device_ref} | Відкликати довіру до пристрою |
GET | /v2/affiliates/{affiliate_id} | Звіт про якість партнера за 90 днів з рекомендацією hold / review |
POST, GET | /v2/self-exclusions | Встановити або продовжити самовиключення для акаунта чи отримати їх список |
DELETE | /v2/self-exclusions/{user_id} | Достроково зняти самовиключення |
Їхні результати надходять до вас і як події вебхуків:
transaction_state_changed, login_risk, trusted_device_enrolled,
trusted_device_revoked і affiliate_threshold_crossed.
Завершальна скісна риска приймається й ігнорується. Невідомий шлях або хибний метод повертають той самий JSON-конверт помилки, що й усе інше, — ніколи не HTML- і не текстову сторінку.
Будь-яке читання обмежене часовим вікном, яким керують два необов’язкові параметри запиту:
| Параметр | Приймає |
|---|---|
from | YYYY-MM-DD або повний таймстамп RFC 3339 |
to | YYYY-MM-DD або повний таймстамп RFC 3339 |
to включає весь цей день цілком.400 invalid_request і повідомленням
time must be YYYY-MM-DD or RFC3339.meta, тож
перевіряйте meta.from і meta.to, а не вважайте, що ваш запит виконано дослівно.curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"Відповідь несе агреговану історію і містить у собі останню сесію, тож у типовому випадку вистачає одного запиту, а не двох:
{ "visitor_id": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "first_seen_at": "2026-05-02T10:11:12Z", "last_seen_at": "2026-07-25T08:00:00Z", "visits": 42, "incognito_visits": 3, "unique_ips": 5, "unique_countries": 2, "browsers": ["Chrome"], "os": ["macOS"], "devices": ["desktop"], "risk": { "max_risk_score": 63, "avg_bot_score": 12.5, "bot_sessions": 7, "last_decision": "real" }, "network": { "vpn_seen": false, "proxy_seen": false, "tor_seen": false, "datacenter_seen": true, "proxy_detected_seen": true, "last_isp": "Deutsche Telekom", "last_real_ip": { "address": "203.0.113.7", "country": "NL", "isp": "KPN" } }, "last_session": { "request_id": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitor_id": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "account_id": "user_8842", "account": { "id": "user_8842", "email": "ann@example.com", "display_name": "Ann Lee" }, "timestamp": "2026-07-25T08:00:00Z", "tag": "checkout", "fields": { "order_ref": "A-1029" }, "url": "https://shop.example.com/checkout", "ip": "203.0.113.42", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "browser": { "name": "Chrome", "version": "126.0" }, "os": { "name": "macOS", "version": "14.5" }, "device": "desktop", "gpu": "Apple M2", "geo": { "country": "DE", "city": "Berlin", "timezone": "Europe/Berlin", "isp": "Deutsche Telekom" }, "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "connection_type": "residential", "proxy_detected": true, "real_ip": { "address": "203.0.113.7", "country": "NL", "isp": "KPN" }, "asn": 3320 }, "screen": { "width": 2560, "height": 1600, "color_depth": 30, "pixel_ratio": 2 }, "locale": { "languages": ["en-US", "de"], "timezone": "Europe/Berlin" }, "client_hints": { "architecture": "arm", "bitness": "64", "platform_version": "14.5.0" }, "extensions": [ { "slug": "ublock-origin", "name": "uBlock Origin", "category": "adblock", "risky": false, "store_url": "https://chromewebstore.google.com/detail/cjpalhdlnbpafiamejdnhcphjbkeiagm" } ], "bot": { "result": "human", "score": 4.5, "antidetect_score": 2.1 }, "identification": { "confidence": 0.97, "incognito": false, "match_type": "exact", "match_confidence": 0.99 }, "device_info": { "device_id": "d_4f9c2e", "cross_browser": true, "confidence": 0.88, "linked_browsers": 2 }, "decision": { "action": "real", "risk_score": 12, "suspect_score": 3 } }, "meta": { "plan": "business", "retention_days": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}| Поле | Значення |
|---|---|
visits, incognito_visits | Усього візитів у вікні та скільки з них були у приватному вікні |
unique_ips, unique_countries | Різні адреси та країни, зафіксовані у вікні |
browsers, os, devices | Різні середовища, у яких з’являвся цей відвідувач |
risk.max_risk_score | Найвища оцінка ризику, зафіксована у вікні, 0..100 |
risk.last_decision | Рішення, зафіксоване для найсвіжішого візиту |
risk.avg_bot_score, risk.bot_sessions | Середня оцінка бота та кількість ботових сесій — Business і вище |
network.*_seen | Чи траплялися колись у цього відвідувача VPN, проксі, вихідний вузол Tor або адреса ЦОД |
network.proxy_detected_seen | Чи виходив хоча б один візит у вікні через проксі або VPN перед браузером — див. network.proxy_detected у розділі Факти про пристрій |
network.last_isp | Найсвіжіший ISP — Business і вище |
network.last_real_ip | Найсвіжіша адреса, яку спостерігали за проксі або VPN (address, country, isp), — Business і вище; відсутня, коли жоден візит її не приніс |
last_session | Повний об’єкт сесії для найсвіжішого візиту |
meta | Тариф, його строк зберігання у днях і фактично застосоване вікно |
Відвідувач, щодо якого немає даних усередині вікна зберігання, віддає 404 not_found
з повідомленням visitor not found in the retention window — це не помилка вашої
інтеграції, а ознака того, що відвідувач новий або вже вийшов за строк зберігання.
Сесія несе два вердикти, і вони відповідають на різні питання — чи був клієнт автоматизованим і до якого загального висновку дійшов рушій ризику:
| Поле | Значення |
|---|---|
bot.result | human, bot, uncertain |
bot.type | Присутнє, коли bot.result дорівнює bot: або конкретний інструмент (playwright, puppeteer, selenium, jsdom, claude_computer_use…), або перевірений ШІ-агент (ai_agent:<vendor>), або сімейство, коли інструмент не названо, — automation, headless, antidetect, extension, privacy_browser, impersonation, other |
decision.action | real, fake, suspicious |
bot.score і decision.risk_score обидва йдуть у шкалі 0..100. На Business і вище
guidance перетворює їх на рекомендації для кожного сценарію на драбині
allow → challenge → review → deny — що означає кожен щабель, див. у розділі
Guidance. Значення та шкали збігаються з
тілом вебхука v3 для того самого візиту, а guidance обчислюється за тими самими
правилами.
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions?limit=100&min_risk_score=50"| Параметр | За замовчуванням | Примітки |
|---|---|---|
limit | 50 | Обмежений зверху 500; більше значення підрізається, а не відхиляється |
from, to | Строк зберігання тарифу | Спільне часове вікно, описане вище |
cursor | — | Непрозорий курсор пагінації з попередньої сторінки |
bot_result | — | Залишити лише сесії з цим вердиктом бота |
min_risk_score | — | Залишити лише сесії з оцінкою ризику не нижче цієї, 0..100 |
Сесії повертаються починаючи з найсвіжіших:
{ "items": [ { "request_id": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitor_id": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "timestamp": "2026-07-25T08:00:00Z" } ], "next_cursor": "MTcyMTg5NDQwMDAwMDphYmMxMjM", "has_more": true, "meta": { "plan": "business", "retention_days": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}Посторінкова вибірка побудована на курсорах. Параметрів page або offset немає:
передайте отриманий next_cursor назад як cursor і продовжуйте, доки has_more
дорівнює true. Остання сторінка може взагалі не містити next_cursor, тож не робіть
це поле обов'язковим.
async function allSessions(visitorId: string, secretKey: string) { const sessions = [] let cursor: string | undefined
do { const url = new URL(`https://api.tracio.ai/v2/visitors/${visitorId}/sessions`) url.searchParams.set("limit", "500") if (cursor) url.searchParams.set("cursor", cursor)
const res = await fetch(url, { headers: { Authorization: `Bearer ${secretKey}` } }) if (!res.ok) throw new Error(`Data API: ${res.status}`)
const page = await res.json() sessions.push(...page.items) cursor = page.has_more ? page.next_cursor : undefined } while (cursor)
return sessions}Вважайте курсор непрозорим — його вміст є деталлю реалізації і може змінитися.
Відредагований курсор відхиляється з 400 invalid_request і повідомленням
malformed cursor.
Окрім браузера та ОС, узятих із User-Agent, сесія несе те, що браузер відвідувача повідомляє про машину, очищене на нашому боці. Кожне поле відсутнє, коли візит таких даних не приніс, тож вважайте будь-яке з них необов'язковим.
| Поле | Значення |
|---|---|
gpu | Модель відеоадаптера, як її повідомляє браузер (WebGL), нормалізована до читабельного імені — Intel Iris Xe Graphics, Apple M1 Pro, Qualcomm Adreno 830; Software renderer означає, що справжнього GPU немає (віртуальна машина або headless-середовище); Safari повідомляє Apple GPU |
network.proxy_detected | HTTP-трафік візиту та його сирі мережеві шляхи виходять через різні мережі — перед браузером стоїть проксі або VPN; дві адреси того самого провайдера (NAT оператора, другий вихід того самого VPN) не рахуються; прапорець не встановлюється, коли адреси неможливо порівняти (iCloud Private Relay, IPv4 поруч з IPv6) |
network.real_ip.address, .country, .isp | Публічна адреса, яку спостерігали на сирому мережевому шляху, тобто адреса за проксі або VPN, разом із її країною та ISP — Business і вище; відсутня, коли такої адреси не спостерігали (country та isp відсутні, коли їх не вдалося визначити) |
device_info.device_id, .cross_browser, .confidence, .linked_browsers | Присутнє, коли ідентичність пристрою вдалося визначити: стабільний ідентифікатор фізичного пристрою, спільний для браузерів на ньому, чи прийшов цей візит через інший браузер, ніж раніше, впевненість цього збігу та скільки різних відвідувачів (браузерів) ділять пристрій — більше одиниці означає одну машину під кількома браузерними ідентичностями — Business і вище |
os_environment | Середовище робочого столу, виміряне на машині з Linux (Mint 22+, Ubuntu 25.04+, Ubuntu, GNOME, KDE) — Business і вище; відсутнє, коли не визначене |
spoofing | Що візит заявив проти того, що виміряли незалежні перевірки (claimed, real, spoofed_axes із os, gpu, screen, network, browser; anonymous_browser з назвами продуктів) — Business і вище; присутнє лише тоді, коли підміну виявлено |
screen.width, .height, .color_depth, .pixel_ratio | Роздільна здатність екрана, глибина кольору та device pixel ratio, як їх повідомляє браузер — Business і вище |
locale.languages, locale.timezone | Власні бажані мови браузера та його часовий пояс — на відміну від geo.timezone, який виводиться з IP-адреси; розбіжність між ними — часта ознака підміненого розташування — Business і вище |
client_hints.architecture, .bitness, .model, .device_name, .platform_version | User-Agent Client Hints: архітектура та розрядність процесора, код моделі пристрою (Android, наприклад SM-A556B) разом із її маркетинговою назвою зі списку пристроїв Google Play (device_name, наприклад Samsung Galaxy A55 5G) і точна версія платформи; лише браузери на Chromium — Business і вище |
environment.virtual_machine, environment.hypervisor | Присутнє лише тоді, коли відеоадаптер сам відрекомендувався віртуальним; hypervisor — закритий словник (vmware, virtualbox, parallels, qemu, hyperv, bochs, intel-gvt, vgpu). Відсутність блока означає, що таких свідчень немає — Business і вище |
extensions перелічує розширення браузера, виявлені під час візиту, — Pro і вище.
Кожен елемент — об’єкт:
| Поле | Значення |
|---|---|
slug | Стабільний машинний ідентифікатор розширення, те саме значення, яке доставляє вебхук |
name | Зрозуміла людині назва |
category | Укрупнений клас — adblock, privacy, automation, wallet, vpn, devtools, other і так далі |
risky | true для розширень, пов’язаних з автоматизацією, підміною або крадіжкою облікових даних |
store_url | Посилання на картку розширення в магазині, коли воно відоме |
Знахідка повідомляється лише після того, як пройшла наші перевірки довіри, — середовище, яке відповідає «встановлено» на будь-яку пробу, або партія довша за дванадцять імен відбраковуються як ненадійні. Тому порожній або відсутній список означає «нічого, що ми змогли підтвердити», а не «розширень не встановлено». Читайте його як свідчення, а не як інвентарний перелік.
fields містить користувацькі пари ключ–значення, які ваша інтеграція прикріпила до
візиту, — номер замовлення, назву тарифу, результат оплати. Ключі та значення завжди є
рядками: прикріплене число або логічне значення повертається в текстовому вигляді. Як
і решта сесії, поле доступне на будь-якому тарифі з доступом до API (Pro і вище) і
відсутнє, якщо візит не має полів.
fields читається наново під час кожного запиту, а не копіюється в момент візиту.
Поля, прикріплені після візиту (див. Прикріплення полів після візиту),
теж потрапляють сюди, тому для того самого візиту fields може містити більше, ніж
доставив вебхук.
Не додавайте до користувацьких полів персональні дані — імена, адреси електронної пошти, номери телефонів: натомість прикріплюйте ідентифікатор, який розпізнають ваші власні системи, а те, хто стоїть за акаунтом, передавайте записом акаунта (нижче).
account — це ваш запис про акаунт, що стоїть за візитом, — те, що ви востаннє
надіслали для цього account_id через POST /v2/accounts/metadata:
{ "account": { "id": "user-42", "email": "ann@example.com", "display_name": "Ann Lee" }}| Поле | Опис |
|---|---|
id | Ваш ідентифікатор акаунта — те саме значення, що й account_id |
email | Адреса email, яку ви надіслали для акаунта; відсутня, якщо порожня |
display_name | Відображуване ім'я, яке ви надіслали; відсутнє, якщо порожнє |
Запис читається наново під час кожного запиту, тож перейменування видно і на старих візитах: блок описує акаунт таким, яким він є зараз, а не яким був у момент візиту. Він доступний на будь-якому тарифі з доступом до API (Pro і вище). Мітки, які ви надіслали разом із записом, не повертаються.
Блок відсутній, коли візит не має пов'язаного акаунта, коли запису для нього немає (або ви очистили його, надіславши порожні значення), і — рідко — коли запис не вдалося прочитати: сесія все одно повертається повністю, а запит не падає, тож вважайте відсутній блок «невідомо», а не «у цього акаунта немає email». Вебхуки цей блок не несуть.
Найсвіжіша:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions/latest"Повертається голий об’єкт сесії — не масив і не загорнутий у конверт. Відвідувач без
сесій у вікні віддає 404 not_found з повідомленням
no sessions for this visitor in the retention window.
Або за request_id — ідентифікатором, який трапляється й у payload вебхука:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/sessions/9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31?visitor_id=X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"visitor_id тут необов’язковий, але якщо ви його знаєте, передача помітно прискорює
пошук.
identification.drift_score — згладжена поведінкова оцінка, на якій побудовано
вердикт про захоплення акаунта, Business і вище, — повертається лише цим читанням
однієї сесії. Поведінковий дрейф вимірюється під час візиту, уже після первинної
ідентифікації, тож маршрути списку та останньої сесії його опускають. Візит, поведінку
якого так і не було оцінено, не має drift_score. Те саме значення надходить до вас
через вебхук account_takeover.
Вебхук може доставити візит більше одного разу: спочатку primary, потім late або
correction у міру надходження повільніших сигналів і поведінкових свідчень, — і
пізніша фаза може перевернути попередній вердикт. Data API відповідає за записом
primary. Пізніші фази в нього не вливаються, тож для виправленого візиту останній
вебхук — новіша відповідь. Якщо ви дієте через кілька хвилин після візиту, надавайте
перевагу фазі, отриманій останньою, а не свіжому читанню тут.
Одне працює у зворотний бік: щойно детектор захоплення акаунта спрацював для візиту,
guidance тут це відображає, тоді як тіла вебхука identification того самого візиту
цієї осі не несуть — вона надходить окремою доставкою account_takeover.
Velocity відповідає на питання «скільки цей відвідувач устиг наробити останнім часом» — саме так виглядають перебір облікових даних, тестування карток і масові реєстрації.
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/velocity?window=1h"window приймає 1h, 24h або 7d, за замовчуванням — 24h. Будь-яке інше
значення відхиляється з 400 invalid_request і повідомленням
window must be one of: 1h, 24h, 7d.
{ "window": "1h", "events": 37, "unique_ips": 9, "unique_countries": 3, "unique_accounts": 12, "bot_events": 4, "meta": { "plan": "business", "retention_days": 90, "from": "2026-07-25T11:00:00Z", "to": "2026-07-25T12:00:00Z" }}unique_accounts рахує різні значення linkedId, які ви надіслали для цього
пристрою, — див. Зв’язування акаунтів. bot_events доступне
на Business і вище; на Pro ключ відсутній.
TRACIO знає ваші акаунти лише за ідентифікатором, який ваш сайт передає як linkedId,
— непрозорим рядком на кшталт usr_8412. Надішліть зрозумілі людині мітки один раз, і
кожен екран дашборда, де показано цей акаунт, покаже ім'я або email замість сирого
ідентифікатора, а об'єкт сесії поверне їх у своєму блоці account.
Ніщо тут не впливає на детекцію та оцінку — це шар відображення.
curl -s -X POST "https://api.tracio.ai/v2/accounts/metadata" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"accounts":[ {"account_id":"usr_8412","email":"ann@example.com","display_name":"Ann Lee","labels":{"tier":"vip"}}, {"account_id":"usr_9130","display_name":"Bob Ray"} ]}'{ "updated": 2 }fields. Email чи ім'я,
надіслані сюди, живуть лише в записі акаунта вашого workspace: вони не зберігаються
для кожного візиту, не записуються в сторінку, а одне надсилання оновлює кожен візит
цього акаунта.400 invalid_request, і один хибний елемент
відхиляє весь пакет — помилка називає його позицію. Повторювані ідентифікатори
акаунтів в одному пакеті допустимі: перемагає останній.Ліміти: 1000 акаунтів на запит, тіло 1 МіБ, account_id ≤ 256 символів,
email ≤ 320, display_name ≤ 256, не більше 16 міток із ключами ≤ 64 і значеннями
≤ 256 символів.
Браузер може надіслати лише те, що сторінка знає в момент рендеру, — номер замовлення, але ніколи не результат перевірки платежу чи щось інше, що з'ясовується пізніше. Цей маршрут закриває прогалину: знайдіть візит за полем, яке він уже має, і прикріпіть до нього додаткові поля на боці сервера.
curl -s -X POST "https://api.tracio.ai/v2/events/fields" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"match":{"key":"order_ref","value":"A-1029"},"fields":{"amount":"120.00"}}'{ "updated": 1 }match знаходить візит за полем, яке він уже має, а не за request_id, у межах
workspace і середовища вашого ключа.404 not_found — записуйте
поле невдовзі після того, як результат з'ясувався.updated рахує різні візити. Значення більше за 1 лише тоді, коли ваш match
влучає в кілька візитів, — пара ключ/значення, не унікальна для одного замовлення чи
кошика. match, що влучає більше ніж у 100 подій, відхиляється з
400 invalid_request, а не застосовується до довільної підмножини.server і мають
пріоритет над значенням з тим самим ключем, записаним браузером.404 not_found, а не порожній 200.Ліміти збігаються з браузерним каналом: 50 полів за виклик, ключі ≤ 40 байтів,
значення ≤ 500 байтів — байтів, а не символів, — набір символів ключа
A-Za-z0-9_.:-, тіло 1 МіБ.
Стирає користувацькі поля — але ніколи не сам візит. Використовуйте його для значень, які більше не потрібно тримати прив'язаними до візиту, наприклад суми замовлення. Уже надіслані вебхуки та вже зроблені вивантаження не змінюються.
# by request_id — clears every field on this one visitcurl -s -X POST "https://api.tracio.ai/v2/events/fields/delete" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"request_id":"9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31"}'
# by match — clears "order_ref" from every visit currently holding "A-1029"curl -s -X POST "https://api.tracio.ai/v2/events/fields/delete" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"match":{"key":"order_ref","value":"A-1029"}}'{ "deleted": 1 }request_id і match взаємовиключні — якщо надіслати обидва або жодного, буде
400 invalid_request. match використовує те саме 24-годинне вікно і ту саму стелю
в 100 подій, що й прикріплення.deleted рахує поля, видалені з візиту (за request_id), або візити, з яких
поле було видалено (за match).404 not_found.Ті самі списки, якими ваші оператори керують у дашборді, доступні з вашого власного
бек-офісу. Тип списку — це його дія щодо візиту, який збігся, — block,
manual_review, challenge, allow, — а його режим вирішує, чи застосовується
дія: observe лише рахує збіги, enforce застосовує її до guidance (вісь list).
Списки та їхній режим створюються в дашборді; Data API читає списки, а також додає й
видаляє елементи.
curl -s "https://api.tracio.ai/v2/lists" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX"[ { "id": "7f3a9d2e-4c1b-4e8f-9a6d-1b2c3d4e5f60", "name": "Chargeback accounts", "type": "block", "mode": "enforce", "entries_count": 128 }]# ban an account for 30 dayscurl -s -X POST "https://api.tracio.ai/v2/lists/7f3a9d2e-4c1b-4e8f-9a6d-1b2c3d4e5f60/entries" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"value":"usr_8412","value_type":"linked_id","ttl_minutes":43200}'{ "id": "02b4c8d1-6e7f-4a90-b1c2-d3e4f5a6b7c8", "value": "usr_8412", "value_type": "linked_id", "expires_at": "2026-10-19T12:00:00Z", "propagation": "immediate"}Видаліть елемент тим самим тілом за адресою POST /v2/lists/{list_id}/entries/delete;
відповідь — { "removed": true, "propagation": "immediate" }.
value_type — те, з чим зіставляється значення: linked_id, visitor_id,
device_id, ip, cidr або country. Значення, яке не розбирається для свого
типу, — це 400 invalid_request.linked_id →
visitor_id → device_id → ip → cidr → country, — а всередині нього перемагає
найсуворіша дія.ttl_minutes необов'язковий. Якщо його опустити, застосовується TTL списку за
замовчуванням; якщо немає й його, елемент не спливає ніколи (expires_at дорівнює
null). Повторне додавання елемента подовжує його.propagation повідомляє, коли зміна набуває чинності: immediate або ttl —
приблизно протягом п'яти хвилин.200 з removed: false; 404
зарезервовано за невідомим списком.Відсутнє поле означає «немає даних», а не нуль. Поля без значення опускаються
цілком, а не надсилаються як 0, "" чи null: у зовсім нового відвідувача немає
match_confidence, у чистого візиту немає antidetect_score та suspect_score.
Єдиний навмисний виняток — bot.score: воно присутнє завжди, навіть коли дорівнює
нулю. Читайте поля захисно.
Payload залежить від вашого тарифу. Доступ до API починається з Pro, і Pro отримує
базову сесію — ідентифікатори, таймстамп, URL, IP, user agent, браузер, ОС, пристрій,
гео, мережа, бот, ідентифікація та рішення — разом з identification.match_type,
identification.match_confidence, bot.score, bot.type, bot.antidetect_score,
gpu, network.proxy_detected, extensions, fields і account. Business та
Enterprise додають geo.isp, network.asn, network.real_ip,
decision.suspect_score, identification.drift_score, reasons, behavior,
guidance, device_info, spoofing, os_environment, screen, locale,
client_hints та environment. Поля рівня персони (person_id, reputation,
linked_accounts_count, linked_visitors_count) зарезервовані за Business та
Enterprise і з’являться, коли буде увімкнено шар персон, — сьогодні він працює в
режимі спостереження, і ці поля не віддаються. Відсутність поля рівня Business на
тарифі Pro — не помилка.
Внутрішнє на рівні сигналів не повертається ніколи, на жодному тарифі: імена окремих сигналів, їхні ваги, пороги за вердиктом, сирі значення сигналів і розкладка оцінок залишаються на нашому боці. Оцінка, яку можна зворотною розробкою звести до її вхідних даних, перестає бути захистом.
Будь-який збій використовує один конверт:
{ "error": { "code": "unauthorized", "message": "missing Authorization: Bearer <secret key>", "request_id": "8f14e45fceea167a5a36dedd" }}Цей request_id — не ідентифікатор візиту. Ім’я ділять два різні значення:
всередині payload сесії request_id — це UUID візиту, той самий, який доставляє
вебхук; у конверті помилки це 24-символьний ідентифікатор трасування, що
випускається на кожен HTTP-виклик. Ідентифікатор трасування повертається ще й у
заголовку X-Request-Id на кожній відповіді, успішній чи ні. Додайте його, коли
звертаєтесь до підтримки, — саме за ним ми знаходимо ваш конкретний виклик.
| HTTP | code | Значення |
|---|---|---|
| 400 | invalid_request | Параметр відсутній або хибно оформлений |
| 401 | unauthorized | Ключ відсутній, недійсний, відкликаний або сплив |
| 402 | upgrade_required | Ваш тариф не включає доступ до API |
| 404 | not_found | Усередині вікна зберігання нічого не знайдено, або дані з іншого середовища |
| 405 | method_not_allowed | Маршрут існує, але не для цього методу |
| 429 | rate_limited | Перевищено запити за секунду або денну квоту |
| 500 | internal | Щось зламалося на нашому боці |
| 503 | unavailable | Сховище за API тимчасово недоступне |
Перевірки йдуть у фіксованому порядку — ключ, потім тариф, потім ліміти, — тож запит
із поганим ключем завжди повідомляє спершу про ключ, а не про проблему з квотою. Дані
іншого workspace не відрізнити від даних, яких не існує: вони дають 404, а не 403.
Два випадки 401 навмисно читаються по-різному: missing Authorization: Bearer <secret key>
означає, що заголовок узагалі не надійшов, а invalid or revoked API key — що він
надійшов і не збігся. 402 несе Data API requires the Pro plan or higher.
Повторюйте 429 і 503 зі зростаючою паузою; повторювати інші 4xx марно — вони
означають, що виправити потрібно сам запит.
Відповіді, для яких ключ розпізнано, несуть ваше поточне становище (відповіді 401 і
402 його не несуть, а Enterprise, у якого немає денної квоти, не отримує заголовків
квоти):
| Заголовок | Значення |
|---|---|
X-RateLimit-Limit | Ваша денна квота; у разі відмови за посекундним лімітом — посекундний ліміт |
X-RateLimit-Remaining | Скільки викликів залишилося сьогодні |
X-RateLimit-Reset | Unix-час скидання — північ UTC |
Retry-After | Скільки секунд чекати, надсилається лише з 429 — орієнтуйтеся на нього: він правильний для обох лімітів |
| Тариф | Запитів за секунду | Запитів на добу | Глибина історії |
|---|---|---|---|
| Free | Доступу до API немає | — | 7 днів |
| Pro | 10 | 10 000 | 30 днів |
| Business | 50 | 100 000 | 90 днів |
| Enterprise | 200 | Без обмежень | 365 днів |