TRACIO analizuje adres IP każdego odwiedzającego po stronie serwera. Oznacza sieci VPN, proxy, węzły wyjściowe Tor oraz połączenia z centrów danych, a także ustala geolokalizację na poziomie miasta. Cała analiza działa po stronie serwera, bez żadnych zależności po stronie klienta.
IP Intelligence dociera do Twojej aplikacji przez payload webhooka: obiekt network
(wartości logiczne VPN/proxy/Tor/centrum danych, typ połączenia oraz, od planu Pro wzwyż,
proxy_detected) oraz obiekt geo (kraj, miasto, współrzędne, strefa czasowa) są dostarczane
z każdym webhookiem. ISP, ASN i obiekt real_ip dochodzą od planu Business wzwyż. Pełną
strukturę payloadu oraz weryfikację podpisu opisano w sekcji Webhooks.
Klasyfikacja VPN, proxy, Tor i centrum danych jest ustalana na podstawie łączącego się IP
przy użyciu komercyjnych baz danych IP intelligence (IP2Location dla typu VPN/proxy/Tor,
MaxMind dla geolokalizacji i ASN). Każda z tych czterech flag jest udostępniana jako pojedyncza wartość logiczna w
obiekcie network webhooka — w publicznym payloadzie nie ma podziału na poszczególne metody ani wskaźnika
pewności.
| Flaga | Pole | Znaczenie |
|---|---|---|
| VPN | network.vpn | IP należy do znanego dostawcy VPN |
| Proxy | network.proxy | IP jest proxy z centrum danych lub residential |
| Tor | network.tor | IP jest znanym węzłem wyjściowym Tor |
| Datacenter | network.datacenter | IP należy do dostawcy chmury/hostingu |
{ "network": { "vpn": true, "proxy": true, "tor": false, "datacenter": false, "connection_type": "VPN" }}// `payload` is the webhook delivery body (/docs/webhooks)if (payload.network.vpn) { // visitor is connecting through a VPN}Proxy z centrów danych oraz proxy residential pojawiają się obie jako network.proxy; pochodzenie z centrum
danych jest dodatkowo raportowane jako network.datacenter. Klasyfikacja pochodzi z
bazy danych proxy IP2Location, która obejmuje głównych dostawców chmury/hostingu (AWS,
Google Cloud, Azure, Oracle Cloud, Alibaba Cloud, DigitalOcean, Hetzner, OVH,
Linode/Akamai, Vultr i innych).
{ "network": { "vpn": false, "proxy": true, "tor": false, "datacenter": true, "connection_type": "DCH" }}network.proxy klasyfikuje adres, z którego nadeszło połączenie. Osobna kontrola porównuje
ruch stron wizyty z jej surową ścieżką sieciową: jeśli oba wychodzą przez różne sieci, między
przeglądarką a Twoją witryną znajduje się proxy lub VPN, a wizyta jest raportowana z
network.proxy_detected: true. Dwa adresy tego samego dostawcy — NAT operatora, drugie wyjście
tego samego VPN — nie liczą się.
W planach Business i wyżej publiczny adres zaobserwowany za proxy lub VPN jest dostarczany
obok adresu, z którego nadeszło połączenie, wraz z jego krajem i ISP, jako network.real_ip.
Brakuje go, gdy takiego adresu nie zaobserwowano, więc odczytuj go z zabezpieczeniem
(network.real_ip?.country); country i isp są nieobecne, gdy nie udało się ich ustalić.
{ "network": { "proxy": false, "proxy_detected": true, "real_ip": { "address": "203.0.113.7", "country": "NL", "isp": "KPN" } }}W Webhooks oba pola trafiają pod tymi samymi nazwami przy każdej wizycie.
Podsumowanie odwiedzającego w Data API agreguje je jako
network.proxy_detected_seen (czy proxy kiedykolwiek stało z przodu) i network.last_real_ip
(ostatni zaobserwowany adres wraz z jego krajem i ISP).
Dopasowanie węzła wyjściowego Tor na łączącym się IP pojawia się jako network.tor. Osobno
sama przeglądarka Tor jest rozpoznawana po stronie klienta po jej konfiguracji anty-fingerprintingowej,
niezależnie od trasy sieciowej — zobacz
Smart Signals.
Geolokalizacja na poziomie miasta jest ustalana po stronie serwera na podstawie łączącego się IP
(MaxMind) i dostarczana w obiekcie geo webhooka.
| Pole | Typ | Opis | Plan |
|---|---|---|---|
geo.country | string | Kod kraju ISO 3166-1 alpha-2 | Wszystkie |
geo.city | string | Nazwa miasta | Wszystkie |
geo.lat | number | Przybliżona szerokość geograficzna | Wszystkie |
geo.lon | number | Przybliżona długość geograficzna | Wszystkie |
geo.timezone | string | Identyfikator strefy czasowej IANA | Wszystkie |
{ "geo": { "country": "CZ", "city": "Prague", "lat": 50.05, "lon": 14.4, "timezone": "Europe/Prague" }}W planach Business i Enterprise identyfikowany jest także operator. W payloadzie
webhooka oba pola znajdują się w obiekcie network, a ISP jest powtórzony jako geo.isp:
{ "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "isp": "Comcast Cable", "asn": 7922 }}Przy odczycie sesji przez Data API podział jest nieco inny:
isp znajduje się tylko w geo, a asn w network. Te same dane, dwie powierzchnie —
odczytuj pole stamtąd, gdzie umieszcza je używana przez Ciebie powierzchnia.
Od planu Pro wzwyż webhook niesie blok velocity — jak bardzo odwiedzający przemieszczał
się ostatnio:
| Pole | Typ | Opis |
|---|---|---|
velocity.events5m | number | Zdarzenia tego odwiedzającego z ostatnich 5 minut |
velocity.unique_ips | number | Różne adresy IP zaobserwowane dla tego odwiedzającego |
velocity.unique_locations | number | Różne lokalizacje zaobserwowane dla tego odwiedzającego |
Blok jest obecny, gdy liczniki odwiedzającego są dostępne w momencie zdarzenia (zwykle faza
primary). Brak bloku oznacza „brak danych”, a nie zera — nie traktuj jego nieobecności
jako „brak nietypowej aktywności”.
Dopasowywanie do list blokujących IP nie jest częścią publicznego kontraktu: ani payload
webhooka, ani dashboard nie udostępniają kategorii list blokujących. Powierzchnia webhooka dla
ryzyka sieciowego to logiczne flagi network, proxy_detected, obiekt real_ip od planu
Business, typ połączenia oraz powyższe liczniki velocity — używaj ich razem z polami
decision i bot (zobacz Smart Signals) do decyzji o ryzyku.
To odczytuje bezpośrednio obiekt network z payloadu webhooka. Pełny payload oraz weryfikację podpisu opisano w sekcji
Webhooks.
// `payload` is the webhook delivery body (/docs/webhooks)function assessIPRisk(payload: WebhookPayload) { const { vpn, proxy, tor, datacenter } = payload.network
const risks: string[] = [] let riskLevel = "low"
if (tor) { risks.push("Tor exit node") riskLevel = "critical" }
if (vpn) { risks.push("VPN detected") riskLevel = riskLevel === "low" ? "medium" : riskLevel }
if (proxy) { risks.push("Proxy detected") riskLevel = riskLevel === "low" ? "medium" : riskLevel }
if (datacenter) { risks.push("Datacenter IP") riskLevel = riskLevel === "low" ? "medium" : riskLevel }
return { riskLevel, risks }}