TRACIO analyseert het IP-adres van elke bezoeker aan de serverkant. Het markeert VPN's, proxy's, Tor-exitnodes en datacenterherkomsten en herleidt de geolocatie op stadsniveau. De volledige analyse draait aan de serverkant, zonder afhankelijkheden aan de clientkant.
IP Intelligence bereikt je applicatie via de webhook-payload: het network-object
(VPN-/proxy-/Tor-/datacenter-booleans, verbindingstype en, vanaf Pro, proxy_detected) en het
geo-object (land, stad, coördinaten, tijdzone) worden bij elke webhook geleverd. ISP, ASN en
het real_ip-object komen erbij vanaf Business. Zie Webhooks voor de
volledige payloadstructuur en de handtekeningverificatie.
De classificatie van VPN, proxy, Tor en datacenter wordt herleid uit het verbindende IP-adres
met behulp van commerciële IP-intelligence-databases (IP2Location voor het VPN-/proxy-/Tor-type,
MaxMind voor geolocatie en ASN). Elk van deze vier flags wordt weergegeven als één enkele boolean in het
network-object van de webhook — in de openbare payload is er geen uitsplitsing per methode
en geen betrouwbaarheidsscore.
| Flag | Veld | Betekenis |
|---|---|---|
| VPN | network.vpn | IP behoort tot een bekende VPN-provider |
| Proxy | network.proxy | IP is een datacenter- of residentiële proxy |
| Tor | network.tor | IP is een bekende Tor-exitnode |
| Datacenter | network.datacenter | IP behoort tot een cloud-/hostingprovider |
{ "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}Datacenter- en residentiële proxy's verschijnen beide als network.proxy; de datacenterherkomst
wordt daarnaast gemeld als network.datacenter. De classificatie komt uit
de IP2Location-proxydatabase, die de grote cloud-/hostingproviders dekt (AWS,
Google Cloud, Azure, Oracle Cloud, Alibaba Cloud, DigitalOcean, Hetzner, OVH,
Linode/Akamai, Vultr en andere).
{ "network": { "vpn": false, "proxy": true, "tor": false, "datacenter": true, "connection_type": "DCH" }}network.proxy classificeert het adres waarvandaan de verbinding binnenkwam. Een aparte
controle vergelijkt het paginaverkeer van een bezoek met het ruwe netwerkpad ervan: gaan die
twee via verschillende netwerken naar buiten, dan zit er een proxy of VPN tussen de browser en
je site, en wordt het bezoek gemeld met network.proxy_detected: true. Twee adressen van
dezelfde provider — carrier-NAT, een tweede uitgang van dezelfde VPN — tellen niet mee.
Vanaf Business wordt het publieke adres dat achter de proxy of VPN is waargenomen geleverd
naast het adres waarvandaan de verbinding binnenkwam, met het land en de ISP ervan, als
network.real_ip. Het ontbreekt wanneer zo'n adres niet is waargenomen, dus lees het met een
guard (network.real_ip?.country); country en isp ontbreken wanneer ze niet konden worden
herleid.
{ "network": { "proxy": false, "proxy_detected": true, "real_ip": { "address": "203.0.113.7", "country": "NL", "isp": "KPN" } }}In Webhooks komen beide velden bij elk bezoek onder dezelfde namen binnen.
De bezoekerssamenvatting van de Data API aggregeert ze als
network.proxy_detected_seen (of er ooit een proxy vóór zat) en network.last_real_ip (het meest recente adres, met het land en de ISP ervan).
Een overeenkomst met een Tor-exitnode op het verbindende IP-adres verschijnt als network.tor. Los daarvan
wordt de Tor-browser zelf aan de clientkant herkend aan zijn anti-fingerprinting-configuratie,
onafhankelijk van het netwerkpad — zie
Smart Signals.
Geolocatie op stadsniveau wordt aan de serverkant herleid uit het verbindende IP-adres
(MaxMind) en geleverd in het geo-object van de webhook.
| Veld | Type | Beschrijving | Plan |
|---|---|---|---|
geo.country | string | ISO 3166-1 alpha-2 landcode | Alle |
geo.city | string | Naam van de stad | Alle |
geo.lat | number | Geschatte breedtegraad | Alle |
geo.lon | number | Geschatte lengtegraad | Alle |
geo.timezone | string | IANA-tijdzone-identifier | Alle |
{ "geo": { "country": "CZ", "city": "Prague", "lat": 50.05, "lon": 14.4, "timezone": "Europe/Prague" }}Op de plannen Business en Enterprise wordt ook de provider geïdentificeerd. In de
webhook-payload staan beide velden op het network-object, en de ISP wordt herhaald als geo.isp:
{ "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "isp": "Comcast Cable", "asn": 7922 }}Bij een sessie die via de Data API wordt gelezen, is de verdeling
net iets anders: isp staat alleen op geo en asn op network. Dezelfde gegevens, twee
oppervlakken — lees het veld daar waar het oppervlak dat je gebruikt het plaatst.
Vanaf Pro draagt de webhook een velocity-blok mee — hoeveel de bezoeker zich recent heeft
verplaatst:
| Veld | Type | Beschrijving |
|---|---|---|
velocity.events5m | number | Events van deze bezoeker in de laatste 5 minuten |
velocity.unique_ips | number | Verschillende IP's gezien voor deze bezoeker |
velocity.unique_locations | number | Verschillende locaties gezien voor deze bezoeker |
Het blok is aanwezig wanneer de bezoekerstellers beschikbaar zijn op het moment van het
event (normaal gesproken de primary-fase). Een ontbrekend blok betekent “geen gegevens”,
niet nullen — behandel de afwezigheid ervan niet als “geen ongebruikelijke activiteit”.
Het matchen tegen IP-blokkeerlijsten maakt geen deel uit van het openbare contract: noch
de webhook-payload noch het dashboard stelt blokkeerlijstcategorieën beschikbaar. Het
webhook-oppervlak voor netwerkrisico's bestaat uit de booleaanse network-flags,
proxy_detected, het real_ip-object vanaf Business, het verbindingstype en de bovenstaande
velocity-tellers — gebruik deze samen met de velden decision en bot (zie
Smart Signals) voor risicobeslissingen.
Dit leest het network-object van de webhook-payload rechtstreeks. Zie
Webhooks voor de volledige payload en de handtekeningverificatie.
// `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 }}