A TRACIO analisa o endereço IP de cada visitante no servidor. Ela sinaliza VPNs, proxies, nós de saída Tor e origens de datacenter, e resolve geolocalização em nível de cidade. Toda a análise roda no servidor, sem dependências no lado do cliente.
A IP intelligence chega à sua aplicação através do payload do webhook: o objeto network
(booleanos de VPN/proxy/Tor/datacenter, o tipo de conexão e, no Pro e acima, proxyDetected)
e o objeto geo (país, cidade, coordenadas, fuso horário) são entregues em cada webhook. ISP,
ASN e o objeto realIp são adicionados no Business e acima. Consulte
Webhooks para a forma completa do payload e a verificação de assinatura.
A classificação de VPN, proxy, Tor e datacenter é resolvida a partir do IP de
conexão usando bancos de dados comerciais de inteligência de IP (IP2Location para
o tipo VPN/proxy/Tor, MaxMind para geolocalização e ASN). Cada uma dessas quatro sinalizações é exposta como
um único booleano no objeto network do webhook — não há detalhamento por método
nem pontuação de confiança no payload público.
| Sinalização | Campo | Significado |
|---|---|---|
| VPN | network.vpn | O IP pertence a um provedor de VPN conhecido |
| Proxy | network.proxy | O IP é um proxy de datacenter ou residencial |
| Tor | network.tor | O IP é um nó de saída Tor conhecido |
| Datacenter | network.datacenter | O IP pertence a um provedor de nuvem/hospedagem |
{ "network": { "vpn": true, "proxy": true, "tor": false, "datacenter": false, "connectionType": "VPN" }}// `payload` is the webhook delivery body (/docs/webhooks)if (payload.network.vpn) { // visitor is connecting through a VPN}Proxies de datacenter e residenciais aparecem ambos como network.proxy; a origem
de datacenter é adicionalmente reportada como network.datacenter. A classificação
vem do banco de dados de proxy do IP2Location, que cobre os principais provedores
de nuvem/hospedagem (AWS, Google Cloud, Azure, Oracle Cloud, Alibaba Cloud,
DigitalOcean, Hetzner, OVH, Linode/Akamai, Vultr, e outros).
{ "network": { "vpn": false, "proxy": true, "tor": false, "datacenter": true, "connectionType": "DCH" }}network.proxy classifica o endereço de onde a conexão chegou. Uma verificação separada
compara o tráfego de páginas de uma visita com o caminho de rede bruto dela: quando os dois
saem por redes diferentes, há um proxy ou VPN entre o navegador e o seu site, e a visita é
reportada com network.proxyDetected: true. Dois endereços do mesmo provedor — NAT da
operadora, uma segunda saída da mesma VPN — não contam.
Em Business e acima, o endereço público observado atrás do proxy ou da VPN é entregue ao lado
do endereço de onde a conexão chegou, com o país e o ISP dele, como network.realIp. Ele fica
ausente quando nenhum endereço desse tipo foi observado, então leia-o com uma guarda
(network.realIp?.country); country e isp ficam ausentes quando não puderam ser
resolvidos.
{ "network": { "proxy": false, "proxyDetected": true, "realIp": { "address": "203.0.113.7", "country": "NL", "isp": "KPN" } }}Nos Webhooks, ambos os campos chegam com os mesmos nomes em cada visita.
O resumo do visitante da Data API os agrega como
network.proxyDetectedSeen (se algum dia houve um proxy à frente) e network.lastRealIp
(o endereço mais recente, como uma string simples).
Uma correspondência de nó de saída Tor no IP de conexão aparece como network.tor.
Separadamente, o próprio Tor Browser é reconhecido no lado do cliente por sua
configuração anti-fingerprinting, independentemente do caminho de rede — consulte
Smart Signals.
A geolocalização em nível de cidade é resolvida no servidor a partir do
IP de conexão (MaxMind) e entregue no objeto geo do webhook.
| Campo | Tipo | Descrição | Plano |
|---|---|---|---|
geo.country | string | Código de país ISO 3166-1 alpha-2 | Todos |
geo.city | string | Nome da cidade | Todos |
geo.lat | number | Latitude aproximada | Todos |
geo.lon | number | Longitude aproximada | Todos |
geo.timezone | string | Identificador de fuso horário IANA | Todos |
{ "geo": { "country": "CZ", "city": "Prague", "lat": 50.05, "lon": 14.4, "timezone": "Europe/Prague" }}Nos planos Business e Enterprise a operadora também é identificada. No payload do
webhook, ambos os campos ficam no objeto network:
{ "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "isp": "Comcast Cable", "asn": 7922 }}Na leitura de uma sessão pela Data API a divisão é um pouco
diferente: isp fica em geo e asn em network. Os mesmos dados, duas superfícies —
leia o campo de onde a superfície que você usa o coloca.
No Pro e acima o webhook carrega um bloco velocity — o quanto o visitante vem se
movimentando recentemente:
| Campo | Tipo | Descrição |
|---|---|---|
velocity.events5m | number | Eventos deste visitante nos últimos 5 minutos |
velocity.uniqueIps | number | IPs distintos observados para este visitante |
velocity.uniqueLocations | number | Localizações distintas observadas para este visitante |
O bloco está presente quando os contadores do visitante estão disponíveis no momento
do evento (normalmente a fase primary). A ausência do bloco significa “sem dados”,
não zeros — não trate a falta dele como “nenhuma atividade incomum”.
A correspondência com listas de bloqueio de IP não faz parte do contrato público: nem o
payload do webhook nem o dashboard expõem categorias de lista de bloqueio. A superfície do
webhook para risco de rede são as sinalizações booleanas de network, proxyDetected, o
objeto realIp no Business, o tipo de conexão e os contadores de velocity acima — use-os em
conjunto com os campos decision e bot (consulte Smart Signals) para
decisões de risco.
Isto lê diretamente o objeto network do payload do webhook. Consulte
Webhooks para o payload completo e a verificação de assinatura.
// `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 }}