Base URL
/api/v1/vpn/* to the WXA VPN backend. All
URLs in this reference are relative to the base.
Endpoint inventory
Lookup
Aggregates
Bulk exports
Conventions
IP format
Always use canonical string form. IPv4 and IPv6 addresses are both accepted:- IPv4:
1.1.1.1 - IPv6:
2606:4700:4700::1111
Phase 1 detection coverage is IPv4-first. Our scanning, proxy enumeration,
and NetFlow signals are IPv4, so an IPv6 lookup is accepted but currently
returns little or no classification data (an empty result, not an error).
Broader IPv6 coverage is on the post-launch roadmap.
400 invalid_ip_reserved — we don’t
classify them. This covers RFC 1918 private space, RFC 6598 / CGNAT, loopback,
multicast, link-local, and TEST-NET ranges (e.g. GET /api/v1/ip/0.0.0.0 →
400 invalid_ip_reserved).
Response shape
The pinned fields (see CONTRACT.md) are stable. Field availability depends on tier — see tiers. Tier-gated fields keep their keys present rather than being omitted — gate on your own tier, not on field presence:- The residential-attribution precision sub-flags
(
is_residential_proxy_high_confidence,is_residential_proxy_mobile) are always present but forced tofalsebelow the pro tier. (The baseis_residential_proxyboolean is shown to all tiers.) provider(and operator name) isnullbelow the starter tier.
asn_abuse and sanctions_risk are legitimately object-or-null
(present as null when there is no data, regardless of tier) — that null
is a real “no data” signal, not a tier strip.
Caching
Aggregate endpoints (/stats, /providers, /stats/country/*,
/stats/asn-abuse) are server-side cached for 60 s – 5 min. The
Cache-Control header reflects this. Lookup endpoints are not cached
server-side — every request hits the live database.
Time
All timestamps are ISO 8601 with a numeric UTC offset and microsecond precision:2026-05-02T04:53:02.210236+00:00. This applies to every
timestamp field the API emits (first_seen, last_seen, last_updated,
computed_at). Use a lenient ISO 8601 parser — don’t hard-code a Z-suffix
format string or regex.