API documentation

IPzentra is a JSON API over HTTPS. Send an IP address, get back its country, network and risk signals.

Authentication

Create an API key in your dashboard and send it in the X-Api-Key header with every request. Keep keys secret: call the API from your server, never from code that runs in the browser.

Endpoints

Base URL: https://api.ipzentra.com

Look up an IP address

GET /v1/{ip}

Works with IPv4 and IPv6.

Check an IP against expected countries

GET /v1/check?ip={ip}&country=IN,SG

Pass one or more two-letter country codes. The response adds expected and country_match.

Look up the caller

GET /v1/

Returns the lookup for the address the request came from. Handy for testing your setup.

Response fields

Response fields
FieldTypeDescription
ipstringThe IP address, normalised.
versioninteger4 or 6.
country_codestring or nullISO 3166-1 alpha-2 code, for example IN.
country_namestring or nullCountry name in English.
asninteger or nullAutonomous system number of the network.
orgstring or nullOwner of the network.
is_vpnbooleanTrue when the IP belongs to a known commercial VPN network.
is_proxybooleanTrue when the IP is a known open proxy.
is_torbooleanTrue when the IP is a current Tor exit node.
is_hostingbooleanTrue for hosting, cloud and datacenter networks.
hosting_providerstring or nullProvider when is_hosting is true, for example aws.
riskstringlow; medium for VPN and hosting networks; high for Tor and open proxies.

The check endpoint also returns:

Check endpoint fields
FieldTypeDescription
expectedarrayThe country codes you passed.
country_matchbooleanTrue when country_code is one of the expected countries.

Example response for GET /v1/5.9.0.1:

{
  "ip": "5.9.0.1",
  "version": 4,
  "country_code": "DE",
  "country_name": "Germany",
  "asn": 24940,
  "org": "HETZNER-AS",
  "is_vpn": false,
  "is_proxy": false,
  "is_tor": false,
  "is_hosting": true,
  "hosting_provider": "hetzner",
  "risk": "medium"
}

We may add new fields over time. New fields never change or remove existing ones.

Errors

Errors return JSON in the form {"error": "code", "message": "explanation"} with these HTTP statuses:

Error codes
StatusError codeMeaning
400bad_ipNot a valid IPv4 or IPv6 address.
400bad_countrycountry is not a list of two-letter codes.
401invalid_keyThe API key is missing, wrong or revoked.
402subscription_requiredThe trial has ended or the subscription has lapsed.
404not_foundThe path does not exist.
429rate_limitedPer-second or daily limit reached.
500server_errorA problem on our side. Retry after a short wait.

Limits

Limits apply per account across all its keys. Daily limits reset at 00:00 UTC, and each response carries an X-RateLimit-Remaining-Day header.

  • Free trial: 100 lookups per day, 2 requests per second, for 20 days.
  • Pro: 20,000 lookups per day, 10 requests per second.

Code examples

cURL

curl -H "X-Api-Key: YOUR_API_KEY" https://api.ipzentra.com/v1/5.9.0.1

curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.ipzentra.com/v1/check?ip=49.207.48.1&country=IN,SG"

PHP

<?php
$ip = $_SERVER['REMOTE_ADDR'];
$ch = curl_init('https://api.ipzentra.com/v1/check?ip=' . urlencode($ip) . '&country=IN');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 3,
    CURLOPT_HTTPHEADER => ['X-Api-Key: ' . getenv('IPZENTRA_KEY')],
]);
$res = json_decode((string)curl_exec($ch), true);
if (!empty($res['country_match']) && empty($res['is_hosting']) && empty($res['is_tor'])) {
    // allow the visitor
}

Python

import os, requests

r = requests.get(
    "https://api.ipzentra.com/v1/check",
    params={"ip": "49.207.48.1", "country": "IN"},
    headers={"X-Api-Key": os.environ["IPZENTRA_KEY"]},
    timeout=3,
)
data = r.json()
if r.ok and data["country_match"] and not data["is_hosting"] and not data["is_tor"]:
    print("allow")

Node.js

const res = await fetch(
  "https://api.ipzentra.com/v1/check?ip=49.207.48.1&country=IN",
  { headers: { "X-Api-Key": process.env.IPZENTRA_KEY } }
);
const data = await res.json();
if (res.ok && data.country_match && !data.is_hosting && !data.is_tor) {
  console.log("allow");
}

Data sources and freshness

  • Country: IP geolocation data by IPLocate.io, licensed CC BY-SA 4.0, refreshed daily.
  • Network (ASN): refreshed daily.
  • Hosting and datacenter ranges: published cloud ranges and hosting networks, refreshed daily.
  • Tor exit nodes: the Tor Project exit list, refreshed hourly.
  • VPN networks: known VPN provider networks, refreshed daily.
  • Open proxies: verified open proxy lists, refreshed every 30 minutes.