Bulk IP Lookup API

Bulk IP Lookup — Look Up Multiple IP Addresses at Once

Batch geolocation, ISP/ASN owner data, proxy & threat detection for up to 100 IPs

Paste a list of IP addresses and instantly get geolocation, the ISP and autonomous system that own each address — the bulk IP WHOIS fields most people need — plus VPN, proxy, Tor, and threat flags for every IP. One API call. JSON or CSV. No sign-up required.

Up to 100 IPs per request
Credits deducted only on success
JSON API — no SDK required
Bulk IP Lookup

Enter IP addresses — one per line or comma-separated

Batch Input
Up to 100 IPs
Geolocation
Waiting...
Threat Signals
Pending...
{ } JSON Response

          
        
Trusted by thousands of businesses
Fast JSON API responses
Real-time validation
Simple integration, SDKs & examples
Features

Everything You Need in a Single Batch Request

Each IP in your batch is analyzed across geolocation, threat intelligence, and network classification — concurrently, in milliseconds.

Up to 100 IPs per Request

Submit up to 100 IP addresses in a single API call. Duplicates are automatically removed — you only pay for unique IPs processed.

Sub-Second Results

IPs are processed concurrently — a batch of 100 completes in the same time as a single lookup. Cached results return in under 50ms.

Proxy Detection

Identifies HTTP, HTTPS, and SOCKS proxies including transparent, anonymous, and elite proxy types. 99.5% accuracy, under 0.1% false positive rate.

VPN Detection

Detects commercial VPN providers, corporate VPN gateways, and self-hosted VPN servers. Coverage across 2,000+ VPN providers and 50M+ IP ranges.

Geolocation Accuracy

Country at 99.8% accuracy, city-level at 85–95%. Returns country, city, region, coordinates, ZIP code, timezone, and real-time local time.

Tor & Threat Intelligence

Real-time Tor exit node identification from official consensus data. Threat intelligence from 50+ global feeds — malware C&C, botnets, DDoS sources.

Batch enrichment is usually a means to an end — a CRM backfill, a log replay, or a territory assignment run. Using IP intelligence in sales and marketing covers what to do with the enriched rows once the batch finishes, and how IP geolocation works explains how far to trust the city field before you route on it.

Owner Data

Bulk IP WHOIS — Owner, ISP & Network for Every IP

IP WHOIS is the registration record behind an address: which organization holds the netblock, which autonomous system announces it, the country it is registered in, and the abuse contact. The batch endpoint returns the parts you most often need per IP — here is exactly which.

IP WHOIS field In POST /api/v1/ip/batch? Where else to get it
Organization / ISP Yesisp
Autonomous system (ASN) Yesasn
Country of registration Yeslocation.country
Network prefix (CIDR) No GET /api/v1/asn/{ip} — see ASN lookup
Abuse contact No Regional Internet Registry WHOIS
Registry (RIR) and allocation date No Regional Internet Registry WHOIS

Bulk IP WHOIS in One Script

Batch the addresses to get owner and location, then attach the network prefix per IP from the ASN endpoint if you need it. That gives you the columns most people mean when they ask for bulk IP WHOIS:

import csv, requests

KEY = "YOUR_API_KEY"
ips = ["8.8.8.8", "1.1.1.1", "45.33.32.156"]

batch = requests.post(
    "https://ip-api.io/api/v1/ip/batch",
    params={"api_key": KEY},
    json={"ips": ips},
).json()["results"]

with open("ip_whois.csv", "w", newline="") as fh:
    w = csv.writer(fh)
    w.writerow(["ip", "isp", "asn", "country", "city", "prefix"])
    for ip, rec in batch.items():
        # prefix is not part of the batch payload — one extra call per IP
        asn = requests.get(
            f"https://ip-api.io/api/v1/asn/{ip}", params={"api_key": KEY}
        ).json()
        w.writerow([
            ip,
            rec.get("isp"),
            rec.get("asn"),
            rec["location"].get("country"),
            rec["location"].get("city"),
            asn.get("network"),
        ])

Domain WHOIS vs. IP WHOIS

These are two different registries and two different questions. Domain WHOIS tells you who registered a domain name, when, and through which registrar — use the domain WHOIS lookup for that. IP WHOIS tells you which organization was allocated a block of addresses and which network announces it, which is what the fields above cover and what ASN lookup goes deeper on.

How-To

How to Do a Bulk IP Lookup

From a list of addresses to enriched rows, whether you use the tool or the API.

1

Collect the addresses

Pull the IPs out of your access logs, signup records, or CSV export. Duplicates are fine — they are deduplicated before processing, and you are only charged per unique address.

2

Paste them in, or POST the batch

Paste one address per line into the tool above, or send them as a JSON array to POST /api/v1/ip/batch. Up to 100 addresses per request, IPv4 and IPv6 mixed freely.

3

Read the results or export CSV

Each address comes back with geolocation, ISP and ASN owner, and the full set of proxy, VPN, Tor, and threat flags. The tool renders them as a table you can download as CSV; the API returns a JSON map keyed by IP address.

4

Chunk anything over 100 addresses

Larger lists just need slicing into batches of 100:

import requests

def lookup_all(ips, key, size=100):
    out = {}
    for i in range(0, len(ips), size):
        chunk = ips[i:i + size]
        res = requests.post(
            "https://ip-api.io/api/v1/ip/batch",
            params={"api_key": key},
            json={"ips": chunk},
        )
        res.raise_for_status()
        out.update(res.json()["results"])
    return out

Bulk IP Geolocation

Every address in the batch returns the full location object: country and country code, city, latitude and longitude, postal code, IANA timezone, and the computed local time. That makes bulk IP geolocation a single request rather than a loop — useful for backfilling a table of historical events, or for scoring a day's signups in one pass. For a single address, the IP geolocation API returns the same fields.

Bulk IP Checker vs. Bulk IP Locator

People reach for different words depending on what they are after. A bulk IP checker usually means the security question — is any address in this list a proxy, a VPN, a Tor exit, or a known threat — while a bulk IP locator means the geographic one. Both come back in the same response here, so you do not have to choose up front which one you are doing.

Bulk IP Lookup API

Bulk IP Lookup API

Integrate batch IP intelligence directly into your application. A single POST request returns geolocation and security data for up to 100 IPs.

Accepts a JSON array of IP addresses. Processes all IPs concurrently and returns a results map keyed by IP. API key is optional — anonymous requests are rate-limited by your IP address.
results — Map of IP → full intelligence object (geolocation + security flags)
total_processed — Number of unique IPs that were processed
successful_lookups — IPs that returned a geolocation result
failed_lookups — IPs that could not be resolved (private ranges, etc.)
suspicious_factors — Security flags: is_proxy, is_vpn, is_tor_node, is_threat, is_spam, is_datacenter, is_crawler
location — Geolocation: country, city, coordinates, zip, timezone, local_time
Read API Reference
Endpoint
POST /api/v1/ip/batch?api_key={key}
Example Request
curl -X POST "https://ip-api.io/api/v1/ip/batch?api_key=YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ips": ["8.8.8.8", "1.1.1.1", "203.0.113.195"]}'
Example Response
200
{
  "results": {
    "8.8.8.8": {
      "ip": "8.8.8.8",
      "isp": "Google LLC",
      "asn": "AS15169",
      "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_crawler": false,
        "is_datacenter": true,
        "is_vpn": false,
        "is_threat": false
      },
      "location": {
        "country": "United States",
        "country_code": "US",
        "city": "Mountain View",
        "latitude": 37.4056,
        "longitude": -122.0775,
        "zip": "94043",
        "timezone": "America/Los_Angeles",
        "local_time": "2024-01-15T10:30:00-08:00",
        "local_time_unix": 1705340400,
        "is_daylight_savings": false
      }
    }
  },
  "total_processed": 3,
  "successful_lookups": 3,
  "failed_lookups": 0
}
Endpoint
JSON Request Body
Example Request
{
  "ips": [
    "8.8.8.8",
    "1.1.1.1",
    "203.0.113.195"
  ]
}
Example Response
200
{
  "results": {
    "8.8.8.8": {
      "ip": "8.8.8.8",
      "isp": "Google LLC",
      "asn": "AS15169",
      "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_crawler": false,
        "is_datacenter": true,
        "is_vpn": false,
        "is_threat": false
      },
      "location": {
        "country": "United States",
        "country_code": "US",
        "city": "Mountain View",
        "latitude": 37.4056,
        "longitude": -122.0775,
        "zip": "94043",
        "timezone": "America/Los_Angeles",
        "local_time": "2024-01-15T10:30:00-08:00",
        "local_time_unix": 1705340400,
        "is_daylight_savings": false
      }
    }
  },
  "total_processed": 3,
  "successful_lookups": 3,
  "failed_lookups": 0
}
Endpoint
POST /api/v1/ip/batch?api_key={key}
Example Request
const response = await fetch(
  "https://ip-api.io/api/v1/ip/batch?api_key=YOUR_KEY",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ ips: ["8.8.8.8", "1.1.1.1", "203.0.113.195"] })
  }
);

const data = await response.json();

for (const [ip, info] of Object.entries(data.results)) {
  const sf = info.suspicious_factors;
  const risk = sf.is_proxy || sf.is_vpn || sf.is_tor_node || sf.is_threat;
  console.log(`${ip}: ${info.location.country} — ${risk ? "RISK" : "Clean"}`);
}
Example Response
200
{
  "results": {
    "8.8.8.8": {
      "ip": "8.8.8.8",
      "isp": "Google LLC",
      "asn": "AS15169",
      "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_crawler": false,
        "is_datacenter": true,
        "is_vpn": false,
        "is_threat": false
      },
      "location": {
        "country": "United States",
        "country_code": "US",
        "city": "Mountain View",
        "latitude": 37.4056,
        "longitude": -122.0775,
        "zip": "94043",
        "timezone": "America/Los_Angeles",
        "local_time": "2024-01-15T10:30:00-08:00",
        "local_time_unix": 1705340400,
        "is_daylight_savings": false
      }
    }
  },
  "total_processed": 3,
  "successful_lookups": 3,
  "failed_lookups": 0
}
Endpoint
POST /api/v1/ip/batch?api_key={key}
Example Request
import requests

response = requests.post(
    "https://ip-api.io/api/v1/ip/batch",
    params={"api_key": "YOUR_KEY"},
    json={"ips": ["8.8.8.8", "1.1.1.1", "203.0.113.195"]}
)
data = response.json()

for ip, info in data["results"].items():
    sf = info["suspicious_factors"]
    risk = sf["is_proxy"] or sf["is_vpn"] or sf["is_tor_node"] or sf["is_threat"]
    country = info["location"].get("country", "Unknown")
    print(f"{ip}: {country} — {'RISK' if risk else 'Clean'}")
Example Response
200
{
  "results": {
    "8.8.8.8": {
      "ip": "8.8.8.8",
      "isp": "Google LLC",
      "asn": "AS15169",
      "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_crawler": false,
        "is_datacenter": true,
        "is_vpn": false,
        "is_threat": false
      },
      "location": {
        "country": "United States",
        "country_code": "US",
        "city": "Mountain View",
        "latitude": 37.4056,
        "longitude": -122.0775,
        "zip": "94043",
        "timezone": "America/Los_Angeles",
        "local_time": "2024-01-15T10:30:00-08:00",
        "local_time_unix": 1705340400,
        "is_daylight_savings": false
      }
    }
  },
  "total_processed": 3,
  "successful_lookups": 3,
  "failed_lookups": 0
}
Endpoint
POST /api/v1/ip/batch?api_key={key}
Example Request
$ips = ["8.8.8.8", "1.1.1.1", "203.0.113.195"];

$ch = curl_init("https://ip-api.io/api/v1/ip/batch?api_key=YOUR_KEY");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(["ips" => $ips]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

foreach ($response["results"] as $ip => $info) {
    $sf = $info["suspicious_factors"];
    $risk = $sf["is_proxy"] || $sf["is_vpn"] || $sf["is_tor_node"] || $sf["is_threat"];
    $country = $info["location"]["country"] ?? "Unknown";
    echo "$ip: $country — " . ($risk ? "RISK" : "Clean") . "\n";
}
Example Response
200
{
  "results": {
    "8.8.8.8": {
      "ip": "8.8.8.8",
      "isp": "Google LLC",
      "asn": "AS15169",
      "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_crawler": false,
        "is_datacenter": true,
        "is_vpn": false,
        "is_threat": false
      },
      "location": {
        "country": "United States",
        "country_code": "US",
        "city": "Mountain View",
        "latitude": 37.4056,
        "longitude": -122.0775,
        "zip": "94043",
        "timezone": "America/Los_Angeles",
        "local_time": "2024-01-15T10:30:00-08:00",
        "local_time_unix": 1705340400,
        "is_daylight_savings": false
      }
    }
  },
  "total_processed": 3,
  "successful_lookups": 3,
  "failed_lookups": 0
}
Endpoint
POST /api/v1/ip/batch?api_key={key}
Example Request
require "net/http"
require "json"
require "uri"

uri = URI("https://ip-api.io/api/v1/ip/batch?api_key=YOUR_KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request.body = { ips: ["8.8.8.8", "1.1.1.1", "203.0.113.195"] }.to_json

data = JSON.parse(http.request(request).body)

data["results"].each do |ip, info|
  sf = info["suspicious_factors"]
  risk = sf["is_proxy"] || sf["is_vpn"] || sf["is_tor_node"] || sf["is_threat"]
  country = info.dig("location", "country") || "Unknown"
  puts "#{ip}: #{country} — #{risk ? "RISK" : "Clean"}"
end
Example Response
200
{
  "results": {
    "8.8.8.8": {
      "ip": "8.8.8.8",
      "isp": "Google LLC",
      "asn": "AS15169",
      "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_crawler": false,
        "is_datacenter": true,
        "is_vpn": false,
        "is_threat": false
      },
      "location": {
        "country": "United States",
        "country_code": "US",
        "city": "Mountain View",
        "latitude": 37.4056,
        "longitude": -122.0775,
        "zip": "94043",
        "timezone": "America/Los_Angeles",
        "local_time": "2024-01-15T10:30:00-08:00",
        "local_time_unix": 1705340400,
        "is_daylight_savings": false
      }
    }
  },
  "total_processed": 3,
  "successful_lookups": 3,
  "failed_lookups": 0
}
FAQ

Frequently Asked Questions

Everything you need to know about bulk IP lookup.

How do I do a bulk IP lookup?

Paste your addresses into the tool at the top of this page, one per line or comma-separated, and submit. For anything automated, send them as a JSON array to POST https://ip-api.io/api/v1/ip/batch — up to 100 addresses per request, with IPv4 and IPv6 mixed freely. Lists longer than 100 need slicing into successive batches.

Can I do a bulk IP WHOIS lookup?

Partly, and it is worth being precise about which parts. The batch endpoint returns the owner fields most people want per address — isp (the organization), asn (the announcing network), and the registered country. It does not return the network prefix, abuse contact, or registry allocation date; for the prefix use GET /api/v1/asn/{ip}, and for abuse contacts query the Regional Internet Registry directly. There is no single bulk WHOIS endpoint.

What's the difference between bulk IP lookup and bulk IP WHOIS?

Bulk IP lookup is the broader operation: geolocation, network owner, and security flags for each address. Bulk IP WHOIS refers specifically to the registration side — who holds the netblock and which AS announces it. In this API they arrive together, so a batch lookup already includes the WHOIS-style owner fields rather than requiring a second call.

Can I export bulk IP results to CSV?

Yes. The results table on this page has a CSV download containing every returned field, including ISP and ASN. If you are calling the API directly, the response is a JSON map keyed by IP address, which maps to CSV rows in a few lines — there is a worked example in the bulk IP WHOIS section above.

How many IP addresses can I look up at once?

You can look up up to 100 IP addresses per batch request. The interactive tool on this page accepts one IP per line or comma-separated. For the API, send a JSON object with an ips array containing up to 100 addresses in a single POST to https://ip-api.io/api/v1/ip/batch.

Do I need an API key for bulk IP lookup?

No API key is required for basic use — the tool works immediately using IP-based rate limiting. For higher limits and production use, add your API key as the api_key query parameter: POST /api/v1/ip/batch?api_key=YOUR_KEY. Free and paid plans are available; paid plans offer significantly higher rate limits and guaranteed SLAs.

What data does the bulk IP lookup return?

For each IP address the batch returns full intelligence data: geolocation (country, city, region, latitude, longitude, ZIP code, timezone, local time), and security flags (proxy detection, VPN detection, Tor node identification, spam source, threat intelligence, datacenter classification). Results are returned as a JSON map keyed by IP address, along with batch statistics (total processed, successful, failed).

How does billing work for bulk requests?

API credits are deducted only after a batch completes successfully — one credit per unique IP address. If the request fails, your quota is insufficient, or the service returns an error, no credits are charged. Duplicate IPs submitted in the same request are automatically deduplicated: submitting the same IP five times counts as one lookup.

What IP address formats are supported?

Both IPv4 (e.g., 8.8.8.8) and IPv6 (e.g., 2001:4860:4860::8888) addresses are supported. Invalid IP formats are rejected with HTTP 400 before any processing occurs — no credits are charged. Private ranges (10.x.x.x, 192.168.x.x, etc.) are valid IP addresses and will be processed, but may return limited geolocation data.

Pricing

Simple, transparent pricing

Start small, scale as you grow. No hidden fees.

Small
€10 /month
100,000 geo IP requests / month
10,000 advanced email validation requests
Location data
Email validation
Risk score calculation
Currency data
Time zone data
Threat data
Unlimited support
HTTPS encryption
Get started
Large
€49 /month
1,000,000 geo IP requests / month
100,000 advanced email validation requests
Location data
Email validation
Risk score calculation
Currency data
Time zone data
Threat data
Unlimited support
HTTPS encryption
Get started

Note: Your API key will be sent to your email after the subscription is confirmed.

Need support?

Explore how IP-API.io can enhance your security, provide robust bot protection, and improve IP geolocation accuracy for your applications.