Bulk IP Lookup API
POST up to 50 IPs to /api/bulk — free batch geolocation and ISP, no key, no signup
Need geolocation and ISP data for a list of IPs at once? HackMyIP’s bulk endpoint takes up to 50 IPs in a single POST and returns a result per IP — free, no key, no signup. It is faster than 50 sequential calls and easier on rate limits. There is also an interactive bulk lookup tool if you would rather paste a list in the browser. Full reference in the API docs.
POST /api/bulk
Send a JSON body with an "ips" array (max 50):
curl -X POST -H "Content-Type: application/json" \
-d '{"ips":["8.8.8.8","1.1.1.1","208.67.222.222"]}' \
https://hackmyip.com/api/bulk
Response — one row per IP with country, city, ISP, org, and coordinates:
{
"success": true,
"data": {
"total": 3,
"results": [
{ "ip": "8.8.8.8", "country": "US", "city": "...",
"isp": "Google LLC", "org": "...", "lat": 0, "lon": 0 },
{ "ip": "1.1.1.1", "country": "...", "city": "...",
"isp": "...", "org": "...", "lat": 0, "lon": 0 }
]
}
}
Invalid or unresolvable entries come back as { "ip": "...", "error": "invalid format" } so one bad IP never fails the whole batch.
Code examples
JavaScript (fetch)
const res = await fetch('https://hackmyip.com/api/bulk', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ips: ['8.8.8.8', '1.1.1.1', '9.9.9.9'] })
});
const { data } = await res.json();
data.results.forEach(r => console.log(r.ip, r.country, r.isp));
Python (requests)
import requests
ips = ['8.8.8.8', '1.1.1.1', '208.67.222.222']
r = requests.post('https://hackmyip.com/api/bulk', json={'ips': ips})
for row in r.json()['data']['results']:
print(row['ip'], row.get('country'), row.get('isp'))
Looking up more than 50 IPs
The bulk endpoint caps each request at 50 IPs. For a larger list, either chunk it into batches of 50, or loop the single-IP /api/lookup endpoint when you need richer per-IP fields like the numeric ASN. Stay within 60 requests/minute:
import requests, time
ips = [ ... ] # any number of IPs
for ip in ips:
r = requests.get('https://hackmyip.com/api/lookup', params={'ip': ip})
d = r.json()['data']
print(ip, d['network']['asn'], d['network']['isp'])
time.sleep(1) # stay under 60 requests/minute
Free bulk IP APIs compared
Bulk limits vary a lot between free IP APIs — some are keyless, some cap the batch small, some hide bulk behind a paid tier. Figures below were checked July 2026 from each provider’s own docs; providers change limits often, so verify on their site before you build against them.
| Service | IPs per request | Key required | Notes |
|---|---|---|---|
| HackMyIP (/api/bulk) | 50 | No | No signup, 60 req/min |
| ip-api.com (batch) | 100 | No | 15 req/min, non-commercial |
| ipapi.co (bulk) | 25 (free) | No (for 25) | More per request on paid plans |
| ipinfo.io (/batch) | 1000 | Yes (token) | Token required for batch |
| ipgeolocation.io | Paid only | Yes | Bulk on paid subscriptions |
For a full side-by-side of what each free IP API returns (not just bulk), see the best free IP geolocation API roundup.
Why batch beats one at a time
Batch endpoints exist to amortize rate limits. Every single-IP call spends one unit of your rate budget for one result; a batch packs many IPs under a single request. ip-api.com documents this directly — its batch takes 100 IPs per POST at 15 requests per minute (up to 1,500 IPs a minute), versus 45 requests per minute on the single endpoint. The rate limit is the ceiling either way; batching just fits far more IPs beneath it.
How accurate is bulk IP geolocation?
Bulk changes throughput, not accuracy — every IP is resolved against the same geolocation database whether you look up one or fifty. And that data is approximate by nature. MaxMind, a primary source for IP geolocation, states plainly that its data is "never precise enough to identify or locate a specific household, individual, or street address." Treat bulk results as country and city-level estimates for log analysis, abuse triage, and building allowlists or denylists — not as a home address.
Need to check a whole IP range? Expand a CIDR block into individual addresses with the CIDR calculator (or convert a range with IP range to CIDR), then paste the list. For the numeric ASN and organization behind an IP, loop the ASN lookup.
Frequently asked questions
Is there a free bulk IP lookup API?
Yes. HackMyIP’s POST /api/bulk takes a JSON array of up to 50 IPs per request and returns geolocation and ISP for each — no key, no signup. For more than 50 IPs, send multiple batches or loop the single-IP /api/lookup endpoint.
What about bulk IP WHOIS?
HackMyIP does not offer a bulk WHOIS endpoint. For network ownership, use the single-IP /api/lookup (returns ASN, ISP, and organization) or /api/asn?q={ip} per IP. The /api/whois endpoint is for domain RDAP, not IP WHOIS. Loop those endpoints over your list, respecting the 60 requests/minute limit.
How many IPs can I look up at once?
Up to 50 IPs per POST /api/bulk request. The endpoint caps the array at 50 and looks them up in parallel, so a batch is much faster than 50 sequential calls. Send additional batches for larger lists.
Do I need an API key for bulk IP lookup?
Not here — the HackMyIP /api/bulk endpoint needs no key and no signup. Across free services it varies: ip-api.com allows batch requests with no key (non-commercial, documented at 15 requests per minute), while providers such as ipinfo.io require a token and some put bulk behind a paid tier. Always check the specific service limit before you rely on it.
Is bulk IP geolocation as accurate as a single lookup?
Yes. Bulk and single lookups read the same geolocation database, so per-IP accuracy is identical — batching only changes how many you process per request, not the data quality. Keep in mind that IP geolocation is approximate: MaxMind states its data is never precise enough to identify a specific household or street address, so expect country and city-level estimates.
Can I bulk look up an IP range or CIDR block?
The bulk endpoint takes individual IPs, not CIDR notation directly. Expand a range such as 192.0.2.0/24 into its 256 addresses first with the CIDR calculator, then paste the list. This is handy when building an allowlist or denylist from a known block.