My IP
Answers what is known about the address this request came from, which is
the same answer GET /{ip} gives for that address: the presented key
decides which fields come back, and the request counts against the same
allowance.
The address is the one our edge observed, so a request through a proxy or a VPN reports the exit it left through rather than the machine that made it. That is usually the point of asking.
?apikey=<key>. Convenient in a browser; prefer a header elsewhere.
In: query
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://api.vpndetection.io/myip"{
"ip": "45.83.91.1",
"is_vpn": true
}{
"error": "invalid API key"
}{
"error": "source address not allowed for this API key"
}{
"error": "rate limit exceeded"
}{
"error": "lookup failed"
}Lookup GET
Answers what is known about a single IPv4 or IPv6 address. Which fields come back is decided by the presented key; with no key the answer is `ip` and `is_vpn`.
Batch POST
Answers up to 1000 addresses in one call. Each distinct string in `ips` is one lookup: it costs exactly what `GET /{ip}` costs for that address and comes back with exactly the fields that call would carry for your plan. Exact duplicates collapse to one entry and one lookup. Both maps in the answer are keyed by the string you sent, so nothing has to be lined up by position; the `ip` inside each result is the normalized form. An address that could not be answered sits in `errors` with the status and message the single lookup would have given, and never disturbs the others: a string that is not an address is a `400` there, and an allowance that runs out part way through leaves the remaining entries as `429`s. The call itself fails only for the reasons below, and a `429` on the call always carries `Retry-After`: the batch is admitted or refused whole by the rate limit, so a per-entry `429` is always a spent allowance and never a throttle.