iplogs.com

API documentation

The IPLogs detection engine is exposed as a single REST endpoint. No authentication, no signup, no SDK required. Below you'll find the full request/response schema, every signal the engine can emit, rate limits, and copy-paste examples in curl, Python, Node.js, and Go.

Endpoint

POST https://iplogs.com/v1/check

Content-Type: application/json. CORS-enabled for browser clients. IPv4 only at the moment (IPv6 support is planned).

Request body

FieldTypeDescription
ipstring?IPv4 to check. Omit to check the caller's source IP.
user_agentstring?Client user-agent, used for OS/browser fingerprint cross-check.
timezonestring?IANA timezone (e.g. America/New_York). Used for tz-mismatch signal.
languagestring?BCP47 language tag. Used for lang-mismatch signal.
webrtc_ipstring?Public IP revealed by WebRTC ICE gathering.
tcp_rtt_msnumber?Client-measured TCP handshake RTT for SNITCH analysis.
tls_rtt_msnumber?Client-measured TLS handshake RTT for SNITCH analysis.

Response

{
  "verdict": "clean" | "suspicious" | "vpn_likely" | "vpn_detected",
  "score": 0.0 .. 1.0,
  "is_vpn": boolean,
  "confidence": 0.0 .. 1.0,
  "ip_info": {
    "ip": "8.8.8.8",
    "asn": "AS15169",
    "org": "Google LLC",
    "isp": "Google LLC",
    "country": "United States",
    "country_code": "US",
    "city": "Mountain View",
    "lat": 37.422,
    "lon": -122.085,
    "type": "datacenter" | "isp" | "hosting" | "cellular",
    "is_vpn": false,
    "is_proxy": false,
    "vpn_provider": "..."
  },
  "signals": [
    { "type": "dc_ip", "weight": 0.1, "matched": true,
      "detail": "Datacenter / hosting ASN AS15169 (Google LLC)" },
    ...
  ],
  "request_id": "req_6d740eec-9ed"
}

Signal catalog

Every detection verdict is composed of 25+ signals. A signal is either matched (contributed to the score) or checked (evaluated and did not match). Below is the complete catalog.

Signal typeLayerMeaning
known_vpn_exactIP intelIP is on a curated VPN server list
known_vpn_cidrIP intelIP falls inside a known VPN CIDR range
tor_exitIP intelIP is in the current Tor exit-node list
vpn_asnIP intelASN classified as a commercial VPN provider
vpn_org_keywordIP intelASN org name contains a VPN keyword
dc_ipIP intelDatacenter / hosting-provider IP
mtu_anomalyTCP/IPNon-standard TCP MSS consistent with tunneling
ttl_os_mismatchTCP/IPTTL does not match claimed OS
tcp_window_anomalyTCP/IPNon-default TCP window size
ja3_known_vpnTLSJA3/JA4 hash matches a known VPN client
rtt_snitchRTTTCP vs TLS RTT differential (NDSS 2025)
geo_rtt_mismatchRTTCross-layer RTT inconsistent with geolocation
active_probe_openvpnProbePort 1194 responds to OpenVPN HARD_RESET
active_probe_wireguardProbePort 51820 responds to WireGuard init
active_probe_ikev2ProbePort 500 responds to IKEv2 SA_INIT
active_probe_realityProbeREALITY cert-switch on SNI fuzzing
tz_mismatchClientBrowser timezone differs from IP geo
lang_mismatchClientBrowser language incongruent with region
webrtc_leakClientWebRTC exposes a different public IP
nonstandard_portPortService on non-standard port

Client examples

curl

curl -X POST https://iplogs.com/v1/check \
  -H 'content-type: application/json' \
  -d '{"ip":"45.82.245.81"}'

Python

import requests
r = requests.post("https://iplogs.com/v1/check",
                  json={"ip": "45.82.245.81"}, timeout=10)
print(r.json()["verdict"])

Node.js

const r = await fetch("https://iplogs.com/v1/check", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ ip: "45.82.245.81" }),
});
console.log((await r.json()).verdict);

Go

body := strings.NewReader(`{"ip":"45.82.245.81"}`)
resp, _ := http.Post("https://iplogs.com/v1/check",
    "application/json", body)
defer resp.Body.Close()

Rate limits

Soft limit: about 60 requests per minute per source IP. Abuse is throttled, not blocked — you'll see a 429 if you exceed the threshold. For sustained high-volume workloads, email admin@iplogs.com to discuss a dedicated tier.