Server API umožňuje vašemu backendu číst identifikační data, která už TRACIO pro váš workspace nasbíralo: historii návštěvníka, jednotlivé relace a čítače velocity za krátká okna.
Doplňuje Webhooky, nenahrazuje je:
| Webhooky | Server API | |
|---|---|---|
| Směr | TRACIO odesílá na váš endpoint | Váš backend si data vyžádá, když je potřebuje |
| Načasování | Ve chvíli každé identifikace | Kdykoli, v rámci vašeho okna uchovávání |
| Nejlepší na | Reakci na událost | Vyhledání dat při rozhodování, zpětné doplňování, vyšetřování |
Obě rozhraní jsou k dispozici od tarifu Pro výše.
https://api.tracio.ai/v1Jde o jiný host než endpoint pro prohlížeč (edge.tracio.ai) a než dashboard
(app.tracio.ai). Všechny tři jsou oddělené: prohlížeč mluví s edge pomocí vašeho
veřejného klíče, váš backend mluví se Server API pomocí vašeho tajného klíče.
Každý požadavek nese váš tajný klíč jako bearer token:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"Server API je výhradně server-to-server. Hlavičky CORS se záměrně nevracejí, takže ji prohlížeč nemůže zavolat — právě to drží váš tajný klíč mimo kód na straně klienta. Tajný klíč nikdy neposílejte do prohlížeče.
Vytvořte jej v dashboardu v sekci API Keys a zvolte typ secret.
tracio_sk_ následované 43 znaky, celkem 53. Dashboard jej
vypisuje podle prvních několika znaků, abyste klíče od sebe rozeznali.Rotace vydá nový klíč a starý nechá funkční ještě 7 dní, takže jej můžete nasadit bez výpadku. Nasaďte nový klíč, ověřte, že se provoz přesunul, a nechte starý vypršet. Veřejné klíče rotovat nelze — nejsou to tajemství a ve zdroji vaší stránky jsou vidět záměrně.
Každá routa je GET. Ve Server API nejsou žádné zápisové operace: čte data, zatímco
vaše konfigurace žije v dashboardu.
| Metoda | Cesta | Vrací |
|---|---|---|
GET | /v1/visitors/{visitorId} | Agregovanou historii jednoho návštěvníka a jeho poslední relaci |
GET | /v1/visitors/{visitorId}/sessions | Stránkovaný seznam relací tohoto návštěvníka |
GET | /v1/visitors/{visitorId}/sessions/latest | Jedinou, nejnovější relaci |
GET | /v1/visitors/{visitorId}/velocity | Čítače aktivity za krátké okno |
GET | /v1/sessions/{requestId} | Jednu relaci podle identifikátoru požadavku |
GET | /.well-known/webhook-keys | Veřejné klíče pro podpis platformy u webhooků (bez autentizace) |
Koncové lomítko se přijímá a ignoruje. Neznámá cesta nebo špatná metoda vrací stejnou chybovou JSON obálku jako všechno ostatní, nikdy HTML stránku ani prostý text.
Každé čtení je ohraničeno časovým oknem, které řídí dva volitelné parametry dotazu:
| Parametr | Přijímá |
|---|---|
from | YYYY-MM-DD nebo úplné časové razítko RFC 3339 |
to | YYYY-MM-DD nebo úplné časové razítko RFC 3339 |
to zahrnuje celý ten den.400 invalid_request a zprávou
time must be YYYY-MM-DD or RFC3339.meta, takže kontrolujte
meta.from a meta.to, místo abyste předpokládali, že váš požadavek byl splněn
doslova.curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"Odpověď nese agregovanou historii a vkládá do sebe poslední relaci, takže běžný případ potřebuje jeden požadavek místo dvou:
{ "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "firstSeenAt": "2026-05-02T10:11:12Z", "lastSeenAt": "2026-07-25T08:00:00Z", "visits": 42, "incognitoVisits": 3, "uniqueIps": 5, "uniqueCountries": 2, "browsers": ["Chrome"], "os": ["macOS"], "devices": ["desktop"], "risk": { "maxRiskScore": 63, "avgBotScore": 12.5, "botSessions": 7, "lastDecision": "real" }, "network": { "vpnSeen": false, "proxySeen": false, "torSeen": false, "datacenterSeen": true, "lastIsp": "Deutsche Telekom" }, "lastSession": { "requestId": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "accountId": "user_8842", "timestamp": "2026-07-25T08:00:00Z", "tag": "checkout", "url": "https://shop.example.com/checkout", "ip": "203.0.113.42", "userAgent": "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", "geo": { "country": "DE", "city": "Berlin", "timezone": "Europe/Berlin", "isp": "Deutsche Telekom" }, "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "asn": 3320 }, "bot": { "result": "human", "score": 4.5, "antidetectScore": 2.1 }, "identification": { "confidence": 0.97, "incognito": false, "matchType": "exact", "matchConfidence": 0.99 }, "decision": { "action": "real", "riskScore": 12 } }, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}| Pole | Význam |
|---|---|
visits, incognitoVisits | Celkový počet návštěv v okně a kolik jich proběhlo v anonymním okně |
uniqueIps, uniqueCountries | Odlišné adresy a země zaznamenané v okně |
browsers, os, devices | Odlišná prostředí, ve kterých se tento návštěvník objevil |
risk.maxRiskScore | Nejvyšší skóre rizika zaznamenané v okně, 0..100 |
risk.lastDecision | Rozhodnutí zaznamenané u nejnovější návštěvy |
risk.avgBotScore, risk.botSessions | Průměr bot skóre a počet botových relací — Business a vyšší |
network.*Seen | Zda u tohoto návštěvníka byla někdy zaznamenána VPN, proxy, výstupní uzel Tor nebo adresa datacentra |
network.lastIsp | Nejnovější ISP — Business a vyšší |
lastSession | Kompletní objekt relace pro nejnovější návštěvu |
meta | Tarif, jeho uchovávání ve dnech a skutečně použité okno |
Návštěvník bez dat uvnitř okna uchovávání vrací 404 not_found se zprávou
visitor not found in the retention window — to není chyba ve vaší integraci, znamená
to, že návštěvník je nový nebo mu data stářím vypadla z okna.
Relace nese dva verdikty a každý odpovídá na jinou otázku — zda byl klient automatizovaný a k čemu celkově dospěl rizikový engine:
| Pole | Hodnoty |
|---|---|
bot.result | human, bot, uncertain |
decision.action | real, fake, suspicious |
bot.score i decision.riskScore běží na škále 0..100. Na Business a vyšších z nich
guidance dělá doporučení pro jednotlivé scénáře na žebříčku
allow → challenge → review → deny — význam jednotlivých příček najdete v části
Guidance.
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions?limit=100&minRiskScore=50"| Parametr | Výchozí | Poznámky |
|---|---|---|
limit | 50 | Strop je 500; vyšší hodnota se zkrátí, neodmítne |
from, to | Uchovávání dle tarifu | Sdílené časové okno popsané výše |
cursor | — | Neprůhledný stránkovací kurzor z předchozí stránky |
botResult | — | Ponechá jen relace s tímto botovým verdiktem |
minRiskScore | — | Ponechá jen relace s tímto skóre rizika a vyšším, 0..100 |
Relace se vracejí od nejnovějších:
{ "items": [ { "requestId": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "timestamp": "2026-07-25T08:00:00Z" } ], "nextCursor": "MTcyMTg5NDQwMDAwMDphYmMxMjM", "hasMore": true, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}Stránkuje se pomocí kurzoru. Parametr page ani offset neexistuje: pošlete zpět
nextCursor, který jste dostali, jako cursor, a pokračujte, dokud je hasMore true.
async function allSessions(visitorId: string, secretKey: string) { const sessions = [] let cursor: string | undefined
do { const url = new URL(`https://api.tracio.ai/v1/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(`Server API: ${res.status}`)
const page = await res.json() sessions.push(...page.items) cursor = page.nextCursor } while (cursor)
return sessions}Ke kurzoru se chovejte jako k neprůhlednému — jeho obsah je implementační detail a může
se změnit. Upravený kurzor je odmítnut s 400 invalid_request a zprávou
malformed cursor.
Té nejnovější:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions/latest"Vrací holý objekt relace — ne pole a ne zabalený v obálce. Návštěvník bez relací v okně
vrací 404 not_found s no sessions for this visitor in the retention window.
Nebo podle requestId, identifikátoru, který se objevuje i v payloadu webhooku:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/sessions/9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31?visitorId=X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"visitorId je zde volitelné, ale když jej znáte, jeho předání vyhledávání výrazně
zrychlí.
Velocity odpovídá na otázku „kolik toho tento návštěvník poslední dobou dělá“ — tedy na tvar credential stuffingu, testování karet a hromadných registrací.
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/velocity?window=1h"window přijímá 1h, 24h nebo 7d a výchozí hodnota je 24h. Jakákoli jiná hodnota
je odmítnuta s 400 invalid_request a window must be one of: 1h, 24h, 7d.
{ "window": "1h", "events": 37, "uniqueIps": 9, "uniqueCountries": 3, "uniqueAccounts": 12, "botEvents": 4, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-07-25T11:00:00Z", "to": "2026-07-25T12:00:00Z" }}uniqueAccounts počítá odlišné hodnoty linkedId, které jste pro toto zařízení poslali
— viz Propojení účtů. botEvents je Business a vyšší.
Chybějící pole znamená „žádná data“, nikdy nulu. Pole bez hodnoty se zcela
vynechávají, místo aby se posílala jako 0, "" nebo null: zbrusu nový návštěvník
nemá matchConfidence, čistá návštěva nemá antidetectScore ani suspectScore.
Jedinou záměrnou výjimkou je bot.score, které je přítomno vždy, i když je nulové. Pole
čtěte obezřetně.
Payload závisí na vašem tarifu. Každý tarif s přístupem k API dostává základní relaci
— identifikátory, časové razítko, URL, IP, user agent, prohlížeč, operační systém,
zařízení, geo, síť, bot, identifikaci a rozhodnutí. Pro přidává
identification.matchType, identification.matchConfidence a bot.antidetectScore.
Business a Enterprise přidávají geo.isp, network.asn, decision.suspectScore,
identification.driftScore, reasons, behavior, guidance, deviceInfo a pole na
úrovni osoby (personId, reputation, linkedAccountsCount, linkedVisitorsCount).
Chybějící pole z tarifu Business na tarifu Pro není chyba.
Vnitřnosti na úrovni signálů se nevracejí nikdy, v žádném tarifu: názvy jednotlivých signálů, jejich váhy, prahy stojící za verdiktem, surové hodnoty signálů i rozpad skóre zůstávají na naší straně. Skóre, které lze zpětně rozložit na své vstupy, přestává být užitečné jako obrana.
Každé selhání používá jednu obálku:
{ "error": { "code": "unauthorized", "message": "missing Authorization: Bearer <secret key>", "requestId": "8f14e45fceea167a5a36dedd" }}Toto requestId není identifikátor návštěvy. Stejné jméno nesou dvě různé hodnoty:
uvnitř payloadu relace je requestId UUID návštěvy, totéž, které doručuje webhook;
uvnitř chybové obálky jde o 24znakový identifikátor trasování, vytvořený pro každé HTTP
volání. Identifikátor trasování se vrací i v hlavičce X-Request-Id u každé odpovědi,
úspěšné i neúspěšné. Uveďte jej, když se obracíte na podporu — právě podle něj vaše
konkrétní volání najdeme.
| HTTP | code | Význam |
|---|---|---|
| 400 | invalid_request | Parametr chybí nebo je poškozený |
| 401 | unauthorized | Klíč chybí, je neplatný, odvolaný nebo vypršel |
| 402 | upgrade_required | Váš tarif nezahrnuje přístup k API |
| 404 | not_found | Uvnitř okna uchovávání nic neodpovídalo |
| 405 | method_not_allowed | Routa existuje, ale ne pro tuto metodu |
| 429 | rate_limited | Překročen počet požadavků za sekundu nebo denní kvóta |
| 500 | internal | Něco selhalo na naší straně |
| 503 | unavailable | Podpůrné úložiště je dočasně nedostupné |
Kontroly probíhají v pevném pořadí — klíč, pak tarif, pak limity — takže požadavek se špatným klíčem hlásí vždy nejdřív klíč, nikdy problém s kvótou.
Dva případy 401 se čtou záměrně jinak:
missing Authorization: Bearer <secret key> znamená, že hlavička nikdy nedorazila,
zatímco invalid or revoked API key znamená, že dorazila a neodpovídala. 402 nese
Data API requires the Pro plan or higher.
Každá autentizovaná odpověď nese váš aktuální stav:
| Hlavička | Význam |
|---|---|
X-RateLimit-Limit | Vaše denní kvóta |
X-RateLimit-Remaining | Zbývající volání pro dnešek |
X-RateLimit-Reset | Unixový čas resetu — půlnoc UTC |
Retry-After | Kolik sekund čekat, posílá se jen s 429 |
| Tarif | Požadavků za sekundu | Požadavků za den | Hloubka historie |
|---|---|---|---|
| Free | Bez přístupu k API | — | 7 dní |
| Pro | 10 | 10 000 | 30 dní |
| Business | 50 | 100 000 | 90 dní |
| Enterprise | 200 | Neomezeně | 365 dní |