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/checkContent-Type: application/json. CORS-enabled for browser clients. IPv4 only at the moment (IPv6 support is planned).
Request body
| Field | Type | Description |
|---|---|---|
| ip | string? | IPv4 to check. Omit to check the caller's source IP. |
| user_agent | string? | Client user-agent, used for OS/browser fingerprint cross-check. |
| timezone | string? | IANA timezone (e.g. America/New_York). Used for tz-mismatch signal. |
| language | string? | BCP47 language tag. Used for lang-mismatch signal. |
| webrtc_ip | string? | Public IP revealed by WebRTC ICE gathering. |
| tcp_rtt_ms | number? | Client-measured TCP handshake RTT for SNITCH analysis. |
| tls_rtt_ms | number? | 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 type | Layer | Meaning |
|---|---|---|
| known_vpn_exact | IP intel | IP is on a curated VPN server list |
| known_vpn_cidr | IP intel | IP falls inside a known VPN CIDR range |
| tor_exit | IP intel | IP is in the current Tor exit-node list |
| vpn_asn | IP intel | ASN classified as a commercial VPN provider |
| vpn_org_keyword | IP intel | ASN org name contains a VPN keyword |
| dc_ip | IP intel | Datacenter / hosting-provider IP |
| mtu_anomaly | TCP/IP | Non-standard TCP MSS consistent with tunneling |
| ttl_os_mismatch | TCP/IP | TTL does not match claimed OS |
| tcp_window_anomaly | TCP/IP | Non-default TCP window size |
| ja3_known_vpn | TLS | JA3/JA4 hash matches a known VPN client |
| rtt_snitch | RTT | TCP vs TLS RTT differential (NDSS 2025) |
| geo_rtt_mismatch | RTT | Cross-layer RTT inconsistent with geolocation |
| active_probe_openvpn | Probe | Port 1194 responds to OpenVPN HARD_RESET |
| active_probe_wireguard | Probe | Port 51820 responds to WireGuard init |
| active_probe_ikev2 | Probe | Port 500 responds to IKEv2 SA_INIT |
| active_probe_reality | Probe | REALITY cert-switch on SNI fuzzing |
| tz_mismatch | Client | Browser timezone differs from IP geo |
| lang_mismatch | Client | Browser language incongruent with region |
| webrtc_leak | Client | WebRTC exposes a different public IP |
| nonstandard_port | Port | Service 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.