Docs
OpenAPI en vivo en https://api.traceexit.com/swagger-ui
Ejemplos 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"
}
}
}
}Herramientas: lookup_ip, check_privacy, check_fraud, compare_network, lookup_ip_batch. Mismas claves y cuotas que REST. Conectar MCP.
Autenticación
Envíe su clave API como token Bearer en cada consulta. Cree claves en la consola bajo Keys. Las claves empiezan por te_live_ (producción) o te_test_ (sandbox). Las cookies de sesión del navegador autentican solo la consola — no las consultas /v1/ip.
Authorization: Bearer te_live_…Límites de tasa y cuota
Hay dos límites: un tope de solicitudes por segundo según el plan y una asignación mensual de consultas (diaria × 30, UTC). REST y MCP comparten un medidor. Si alcanza el tope de RPS, espere un momento y reintente. Si la cuota mensual de Free se agota, las solicitudes se detienen hasta el próximo mes UTC; los planes de pago pueden permitir exceso.
RPS suave por plan (aprox.): Free 10 · Lite 25 · Starter 50 · Pro 100 · Business 200 · Scale 500. Vea Pricing para asignaciones diarias.
Errores
Los errores usan application/problem+json con al menos title y status. Casos frecuentes:
- 401 — Clave API ausente o inválida. Revise el encabezado Authorization.
- 429 — Demasiadas solicitudes en poco tiempo. Respete Retry-After (a menudo 1 segundo) y reduzca la tasa.
- 429 — Cuota mensual agotada. Actualice el plan, espere al próximo mes UTC o reduzca el volumen. X-Quota-Remaining puede ser 0.
- 400 / 404 — IP o ruta inválida. Corrija la solicitud; no reintente a ciegas.
- 5xx — Problema temporal. Reintente con retroceso exponencial; trate la privacidad no resuelta como desconocida si debe decidir de inmediato.
Ejemplo de cuerpo problem
{
"title": "Monthly quota exceeded",
"status": 429,
"detail": "Upgrade plan or wait for next UTC month"
}Forma de la respuesta
Respuesta de consulta anidada con location, network, privacidad tri-estado, risk, fraud y 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 parciales y confianza
Use meta.partial y meta.confidence junto con la privacidad tri-estado (true / false / null) para decidir qué tan estricto ser.
meta.partial
Cuando es true, la consulta no reunió evidencia suficiente para considerar resueltos todos los campos de privacidad. Las puntuaciones y flags se devuelven igual — prefiera aplicación suave (desafío, revisión o permitir con registro) frente a bloqueos duros salvo que otras señales coincidan. Cuando es false, la lectura principal de privacidad fue lo bastante completa para confiar.
meta.confidence
Confianza global en esta respuesta, 0–100 (más alto es mejor). Bandas orientativas: 80+ alta — actúe con flags de privacidad claros; 55–79 moderada — combine con su contexto; por debajo de 55 limitada — trate la privacidad desconocida como desconocida, no como segura. La confianza baja cuando meta.partial es true, campos clave quedan sin resolver o la evidencia es escasa.
risk.reasons y fraud.reasons
Etiquetas breves que explican por qué subió una puntuación. Úselas para registro, allowlists y afinado de reglas — no como lista de denegación única.
- vpn, proxy, tor, residential_proxy — un flag de privacidad coincidente contribuyó al riesgo.
- datacenter, hosting_asn — la dirección corresponde a infraestructura de hosting o datacenter.
- high_network_abuse, elevated_network_abuse — el tráfico muestreado en esta red muestra uso elevado de anonimizadores.
- anonymizer — el flag derivado de anonimizador contribuyó al fraude.
- high_geo_risk — el contexto geográfico añade riesgo en checkout o fraude.
- ml_anonymizer — enmascaramiento probable cuando la privacidad no está totalmente confirmada; combínelo con meta.partial y confidence.
- feedback_abuse — informes previos de operadores marcaron esta red.
CGNAT / móvil
Los NAT compartidos de operadores pueden generar ruido. Prefiera listas de ASN permitidos para rangos móviles conocidos; consulte la guía enterprise al escalar.
Webhooks
Configure una URL de webhook HTTPS en Ajustes para recibir notificaciones de cambios. Cada entrega es un POST con cuerpo JSON y encabezados firmados.
Destino
Defina la URL del webhook en Ajustes. Solo se aceptan endpoints HTTPS.
Eventos
- quota.threshold — el uso mensual cruza el 80 % o el 100 %.
- watch.privacy_changed — cambian flags de privacidad o primaryType de una IP vigilada.
- watch.risk_changed — el score de riesgo supera su umbral o cambia la banda de nivel.
- watch.network_changed — cambian ASN, organización o identidad de red de un objetivo vigilado.
- watch.location_changed — cambia el código de país de una IP vigilada.
Encabezados
Cada entrega incluye Content-Type: application/json más:
- X-TraceExit-Event-Id — id único de esta entrega (igual que eventId en el cuerpo).
- X-TraceExit-Signature — HMAC sha256=<hex> del payload.
- X-TraceExit-Signature-Timestamp — segundos Unix usados en la firma.
Verificar firmas
Calcule HMAC-SHA256 de {timestamp}.{rawBody} con su secreto de firma (UTF-8), donde timestamp es X-TraceExit-Signature-Timestamp y rawBody son los bytes exactos del cuerpo. Compare con X-TraceExit-Signature (sha256=<hex>). Rechace solicitudes si el timestamp difiere más de 5 minutos de su reloj.
Ejemplo: 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"
}
]
}Las entregas son at-least-once. Use eventId para deduplicar en su lado.
Rote el secreto de firma en Ajustes. El nuevo secreto se muestra una vez — guárdelo antes de salir de la página.