POST
https://api.ipscope.io/v1/ip/batchResolves between 1 and 100 IPv4 or IPv6 addresses in one HTTP round-trip (POST /v1/ip/batch). Requires an API key with the batch scope.
# Code examples
curl -sS -X POST "https://api.ipscope.io/v1/ip/batch" \
-H "Authorization: Bearer $IPSCOPE_KEY" \
-H "Content-Type: application/json" \
-d '{"ips":["198.51.100.7","203.0.113.42","2606:4700:4700::1111"]}'# Responses
Batch lookup results pinned to a single consistent dataset_version.
{
"dataset_version": "2026-10-27T00:00:00Z.crawl-1793088000000",
"count": 3,
"results": [
{
"ip": "198.51.100.7",
"ip_version": 4,
"matched_network": "198.51.100.0/24",
"geo": {
"country_code": "US",
"declared_country_code": "US",
"physical_country_code": "US",
"is_virtual_location": false,
"location_type": "physical",
"confidence": 0.94,
"subdivision": "Virginia",
"city": "Ashburn",
"postal_code": "20147",
"latitude": 39.0438,
"longitude": -77.4874,
"accuracy_radius_km": 10,
"timezone": "America/New_York"
},
"network": {
"asn": 64501,
"organization": "Example Cloud LLC"
},
"connection": {
"connection_type": "hosting",
"is_hosting": true,
"is_residential": false,
"is_mobile": false,
"is_business": false
},
"security": {
"is_vpn": true,
"is_hosting": true,
"is_tor_exit": false,
"is_proxy": false,
"anonymizer_type": "vpn",
"confidence": 0.96,
"reason_codes": [
"vpn_handshake_confirmed",
"datacenter_asn_range"
]
},
"security_extensions": {
"abuse_velocity_score": 18,
"is_known_scanner": false,
"observation_recency_hours": 12,
"anonymizer_reason": "vpn_handshake_confirmed",
"threat_level": "medium",
"abuse_velocity": "low",
"confidence": 0.96
},
"dataset_version": "2026-10-27T00:00:00Z.crawl-1793088000000",
"updated_at": "2026-10-27T00:00:00Z"
},
{
"ip": "203.0.113.42",
"ip_version": 4,
"matched_network": "203.0.113.0/24",
"geo": {
"country_code": "DE",
"declared_country_code": "DE",
"physical_country_code": "DE",
"is_virtual_location": false,
"location_type": "physical",
"confidence": 0.92,
"subdivision": "Hesse",
"city": "Frankfurt am Main",
"accuracy_radius_km": 10,
"timezone": "Europe/Berlin"
},
"network": {
"asn": 24940,
"organization": "Hetzner Online GmbH"
},
"connection": {
"connection_type": "hosting",
"is_residential": false,
"is_mobile": false,
"is_business": false,
"is_hosting": true
},
"security": {
"is_vpn": false,
"is_hosting": true,
"is_tor_exit": false,
"is_proxy": false,
"anonymizer_type": "none",
"confidence": 0.91,
"reason_codes": [
"datacenter_asn_range"
]
},
"dataset_version": "2026-10-27T00:00:00Z.crawl-1793088000000",
"updated_at": "2026-10-27T00:00:00Z"
}
]
}# Snapshot consistency & atomic validation
- Pre-debit validation: Every address in
ipsis validated viatryParseIp(ip)before any credits are debited. If even one address in the array is invalid, the entire request fails with400 Bad Requestand 0 credits are charged. - Pinned snapshot reference:
LookupControllercaptures a singleSnapshotLoaderServicesnapshot reference at the start of the batch (const snapshot = this.snapshotLoader.getCurrentSnapshot()), guaranteeing that all items inresults[]are evaluated against the exact samedataset_versioneven if an atomic snapshot reload occurs mid-request. - Order preservation:
results[]is returned in the exact index order of the inputips[]array.
# Streaming 10,000+ IPs with Official Server SDKs
When enriching large log files, SIEM queues, or backfill datasets with thousands of IPs, use lookupBatchChunked or lookupBatchStream in any official server SDK. The SDK automatically deduplicates addresses, checks its local O(1) LRU cache first, and streams 100-IP chunks with bounded concurrency.
import { IpScopeClient } from '@ipscope/sdk-node';
const client = new IpScopeClient({ apiKey: process.env.IPSCOPE_KEY });
for await (const chunk of client.lookupBatchStream(tenThousandIps, { concurrency: 4 })) {
for (const record of chunk.results) {
console.log(record.ip, record.geo?.country_code, record.security?.is_vpn);
}
}