Docs
OpenAPI ao vivo em https://api.traceexit.com/swagger-ui
Exemplos de consulta
curl https://api.traceexit.com/v1/ip/203.0.113.10 \
-H "Authorization: Bearer te_live_…" \
-H "Accept: application/json"const res = await fetch("https://api.traceexit.com/v1/ip/203.0.113.10", {
headers: { Authorization: "Bearer " + process.env.TRACE_EXIT_API_KEY },
});
const dto = await res.json();import { TraceExitClient } from "@traceexit/sdk";
const client = new TraceExitClient({
apiKey: process.env.TRACE_EXIT_API_KEY,
});
const dto = await client.lookupIp("203.0.113.10");import os
import requests
res = requests.get(
"https://api.traceexit.com/v1/ip/203.0.113.10",
headers={"Authorization": f"Bearer {os.environ['TRACE_EXIT_API_KEY']}"},
)
dto = res.json()req, _ := http.NewRequest("GET", "https://api.traceexit.com/v1/ip/203.0.113.10", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("TRACE_EXIT_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()$ch = curl_init('https://api.traceexit.com/v1/ip/203.0.113.10');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TRACE_EXIT_API_KEY'),
'Accept: application/json',
],
CURLOPT_RETURNTRANSFER => true,
]);
$dto = json_decode(curl_exec($ch), true);HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.traceexit.com/v1/ip/203.0.113.10"))
.header("Authorization", "Bearer " + System.getenv("TRACE_EXIT_API_KEY"))
.header("Accept", "application/json")
.GET()
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer",
Environment.GetEnvironmentVariable("TRACE_EXIT_API_KEY"));
var json = await client.GetStringAsync("https://api.traceexit.com/v1/ip/203.0.113.10");require "net/http"
require "json"
uri = URI("https://api.traceexit.com/v1/ip/203.0.113.10")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['TRACE_EXIT_API_KEY']}"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
dto = JSON.parse(res.body)let client = reqwest::Client::new();
let dto = client
.get("https://api.traceexit.com/v1/ip/203.0.113.10")
.bearer_auth(std::env::var("TRACE_EXIT_API_KEY")?)
.send()
.await?
.json::<serde_json::Value>()
.await?;{
"mcpServers": {
"traceexit": {
"command": "npx",
"args": ["-y", "@traceexit/mcp"],
"env": {
"TRACE_EXIT_API_KEY": "te_live_…",
"TRACE_EXIT_BASE_URL": "https://api.traceexit.com"
}
}
}
}Ferramentas: lookup_ip, check_privacy, check_fraud, compare_network, lookup_ip_batch. Mesmas chaves e cotas do REST. Conectar MCP.
Autenticação
Envie sua chave de API como token Bearer em cada consulta. Crie chaves no console em Keys. As chaves começam com te_live_ (produção) ou te_test_ (sandbox). Cookies de sessão do navegador autenticam apenas o console — não as consultas /v1/ip.
Authorization: Bearer te_live_…Limites de taxa e cota
Há dois limites: um teto de solicitações por segundo conforme o plano e uma cota mensal de consultas (diária × 30, UTC). REST e MCP compartilham um medidor. Se atingir o teto de RPS, aguarde um momento e tente de novo. Se a cota mensal do Free acabar, as solicitações param até o próximo mês UTC; planos pagos podem permitir excesso.
RPS suave por plano (aprox.): Free 10 · Lite 25 · Starter 50 · Pro 100 · Business 200 · Scale 500. Veja Pricing para cotas diárias.
Erros
Erros usam application/problem+json com pelo menos title e status. Casos comuns:
- 401 — Chave de API ausente ou inválida. Verifique o cabeçalho Authorization.
- 429 — Muitas solicitações em pouco tempo. Respeite Retry-After (muitas vezes 1 segundo) e reduza a taxa.
- 429 — Cota mensal esgotada. Faça upgrade, aguarde o próximo mês UTC ou reduza o volume. X-Quota-Remaining pode ser 0.
- 400 / 404 — IP ou caminho inválido. Corrija a solicitação; não tente de novo às cegas.
- 5xx — Problema temporário. Tente de novo com backoff exponencial; trate privacidade não resolvida como desconhecida se precisar decidir imediatamente.
Exemplo de corpo problem
{
"title": "Monthly quota exceeded",
"status": 429,
"detail": "Upgrade plan or wait for next UTC month"
}Formato da resposta
Resposta de consulta aninhada com location, network, privacidade tri-estado, risk, fraud e meta.
{
"ip": "203.0.113.10",
"ipVersion": 4,
"privacy": {
"vpn": false,
"proxy": false,
"tor": false,
"datacenter": true,
"residentialProxy": false,
"anonymizer": false
},
"risk": {
"score": 42,
"level": "medium",
"reasons": ["datacenter"]
},
"location": {
"countryCode": "US",
"city": "Ashburn"
},
"meta": {
"cacheHit": true,
"partial": false,
"confidence": 85
}
}Resultados parciais e confiança
Use meta.partial e meta.confidence junto com privacidade tri-estado (true / false / null) para decidir o quão rígido ser.
meta.partial
Quando true, a consulta não reuniu evidência suficiente para tratar todos os campos de privacidade como definidos. Scores e flags ainda são retornados — prefira aplicação suave (desafio, revisão ou permitir com registro) em vez de bloqueios duros, a menos que outros sinais concordem. Quando false, a leitura principal de privacidade foi completa o bastante para confiar.
meta.confidence
Confiança geral nesta resposta, 0–100 (maior é melhor). Faixas orientativas: 80+ alta — aja com flags de privacidade claros; 55–79 moderada — combine com seu contexto; abaixo de 55 limitada — trate privacidade desconhecida como desconhecida, não como segura. A confiança cai quando meta.partial é true, campos-chave ficam sem resolver ou a evidência é fraca.
risk.reasons e fraud.reasons
Tags curtas que explicam por que um score subiu. Use para logging, allowlists e ajuste de regras — não como lista de negação única.
- vpn, proxy, tor, residential_proxy — um flag de privacidade correspondente contribuiu para o risco.
- datacenter, hosting_asn — o endereço mapeia para infraestrutura de hosting ou datacenter.
- high_network_abuse, elevated_network_abuse — tráfego amostrado nesta rede mostra uso elevado de anonimizadores.
- anonymizer — o flag derivado de anonimizador contribuiu para fraude.
- high_geo_risk — contexto geográfico adiciona risco em checkout ou fraude.
- ml_anonymizer — mascaramento provável quando a privacidade não está totalmente confirmada; combine com meta.partial e confidence.
- feedback_abuse — relatórios anteriores de operadores sinalizaram esta rede.
CGNAT / móvel
NATs compartilhados de operadoras podem ser ruidosos. Prefira allowlists de ASN para faixas móveis conhecidas; veja a orientação enterprise ao escalar.
Webhooks
Configure uma URL de webhook HTTPS em Configurações para receber notificações de mudanças. Cada entrega é um POST com corpo JSON e cabeçalhos assinados.
Destino
Defina a URL do webhook em Configurações. Apenas endpoints HTTPS são aceitos.
Eventos
- quota.threshold — uso mensal cruza 80% ou 100%.
- watch.privacy_changed — flags de privacidade ou primaryType de um IP monitorado mudaram.
- watch.risk_changed — score de risco passou do seu limiar ou a faixa de nível mudou.
- watch.network_changed — ASN, organização ou identidade de rede mudou para um alvo monitorado.
- watch.location_changed — código de país mudou para um IP monitorado.
Cabeçalhos
Cada entrega inclui Content-Type: application/json mais:
- X-TraceExit-Event-Id — id único desta entrega (igual a eventId no corpo).
- X-TraceExit-Signature — HMAC sha256=<hex> do payload.
- X-TraceExit-Signature-Timestamp — segundos Unix usados na assinatura.
Verificar assinaturas
Calcule HMAC-SHA256 de {timestamp}.{rawBody} com seu segredo de assinatura (UTF-8), onde timestamp é X-TraceExit-Signature-Timestamp e rawBody são os bytes exatos do corpo. Compare com X-TraceExit-Signature (sha256=<hex>). Rejeite solicitações se o timestamp estiver mais de 5 minutos distante do seu relógio.
Exemplo: watch.risk_changed
{
"event": "watch.risk_changed",
"eventId": "550e8400-e29b-41d4-a716-446655440000",
"occurredAt": "2026-07-27T12:00:00Z",
"organizationId": 42,
"watch": {
"id": 7,
"label": "Login gateway",
"targetType": "ip",
"targetValue": "203.0.113.10"
},
"subject": {
"ip": "203.0.113.10",
"ipVersion": 4
},
"changes": [
{
"field": "risk.score",
"previous": 25,
"current": 72
},
{
"field": "risk.level",
"previous": "low",
"current": "high"
}
]
}Entregas são at-least-once. Use eventId para deduplicar do seu lado.
Rotacione o segredo de assinatura em Configurações. O novo segredo é exibido uma vez — guarde antes de sair da página.