Work with this as data
Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/lookip-batch-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
OpenAPI Specification
openapi: 3.2.0
info:
title: Lookip Batch API
version: 1.0.0
summary: IP geolocation, ASN and VPN/proxy/Tor/hosting detection for any IPv4 or IPv6 address — we name the anonymising service, not just flag it. Prepaid credit, metered per query, no subscription.
description: 'IP intelligence over plain HTTP GET and POST. Two lookup kinds, chosen by URL path and never by a header or body field:
- **LITE** — geolocation and ASN from our local dataset. Sub-5ms p95.
- **MAX** — full enrichment: city geolocation, VPN/proxy/Tor/relay/residential-proxy detection, hosting and anycast flags, reverse DNS, mobile carrier.
## Billing
Prepaid credit, metered per query. No plans, no subscriptions, no monthly quotas — one balance funds both kinds. Amounts are in µUSD (micro-USD); 1 USD = 1,000,000 µUSD.
| Kind | Per query | Per 1,000 |
|------|-----------|-----------|
| LITE | 150 µUSD | $0.15 |
| MAX | 1,300 µUSD | $1.30 |
Every response that debited credit carries `X-Lookup-Kind`, `X-Credit-Debit-MicroUsd` and `X-Credit-Balance-MicroUsd`. Both amounts are decimal strings holding integers that can exceed 2^53 — parse them as BigInt or int64, never as a float. Bogon and error responses carry none of the three, because nothing was charged.
## Limits
50 requests/second per API key, shared across every authenticated endpoint and both kinds. A batch call counts as one request against the rate limit but debits for every resolvable address in it.
A second ceiling of 100 requests/second applies per calling address across all of `/v1`, including the public ASN endpoints. It sits in front of authentication, so it also bounds requests that carry no key or a rejected one. It is deliberately above the per-key cap and cannot be what stops a single key from reaching 50/second. Both refusals are `rate_limited` with status 429 and neither spends credit.
The public ASN endpoints need no key and are not metered — the ceiling above is a rate, not a charge.
## Errors
Every error body is `{ "error": { "code", "message" } }`. Retry `rate_limited`, `lite_db_unavailable`, `service_busy`, `upstream_error`, `internal_error` and any 5xx with jittered backoff; never retry `invalid_request`, `invalid_ip`, `unauthorized`, `insufficient_credit` or `insufficient_credit_for_max`. A charge taken for a lookup we then failed to serve is reversed before the response is sent, so a retry costs one lookup and not two.
A longer implementation spec written for code-generating agents is at https://lookip.io/llms.txt.'
termsOfService: https://lookip.io/legal/terms
contact:
name: Lookip
url: https://lookip.io/docs
email: hi@lookip.io
servers:
- url: https://api.lookip.io
description: Production
security:
- bearerAuth: []
tags:
- name: Batch
description: Up to 100 addresses per call.
paths:
/v1/batch/lite:
post:
tags:
- Batch
operationId: batchLite
summary: LITE Batch
description: Up to 100 addresses. Debited up front for the distinct resolvable addresses only — malformed entries and bogons are classified out before the wallet is touched, and a repeated address is charged once. If the balance cannot cover the batch the whole call is rejected with 402 and nothing is served.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchRequest'
example:
ips:
- 8.8.8.8
- 1.1.1.1
- 2606:4700:4700::1111
responses:
'200':
description: An object keyed by address. Per-address failures are reported inside the object and do not fail the call.
headers:
X-Lookup-Kind:
description: Which kind was billed.
schema:
type: string
enum:
- LITE
- MAX
X-Credit-Debit-MicroUsd:
description: µUSD this call cost, as a decimal string. Net of any reversal.
schema:
type: string
pattern: ^[0-9]+$
X-Credit-Balance-MicroUsd:
description: µUSD remaining after the debit, as a decimal string.
schema:
type: string
pattern: ^[0-9]+$
content:
application/json:
schema:
$ref: '#/components/schemas/BatchLiteResponse'
examples:
mixed:
summary: One resolved address, one bogon, and one per-address failure — the three entry shapes a caller has to handle.
value:
8.8.8.8:
ip: 8.8.8.8
location:
country: United States
countryCode: US
continent: North America
continentCode: NA
network:
asn: AS15169
organization: Google LLC
domain: google.com
lastUpdated: '2026-08-14T09:45:16.269Z'
datasetUpdatedAt: '2026-08-13T13:37:50.000Z'
10.0.0.1:
ip: 10.0.0.1
bogon: true
not-an-ip:
error: invalid_ip
'400':
description: '`invalid_request` — Malformed body, invalid context, bad batch array, or an unparseable ASN.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_request:
summary: Malformed body, invalid context, bad batch array, or an unparseable ASN.
value:
error:
code: invalid_request
message: Malformed body, invalid context, bad batch array, or an unparseable ASN.
'401':
description: '`unauthorized` — Missing, invalid, or revoked API key.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
unauthorized:
summary: Missing, invalid, or revoked API key.
value:
error:
code: unauthorized
message: Missing, invalid, or revoked API key.
'402':
description: '`insufficient_credit` — Balance too low to serve the call. Nothing was debited and nothing was served.'
content:
application/json:
schema:
$ref: '#/components/schemas/InsufficientCreditError'
examples:
insufficient_credit:
summary: Balance too low to serve the call. Nothing was debited and nothing was served.
value:
error:
code: insufficient_credit
message: Balance too low to serve the call. Nothing was debited and nothing was served.
credit:
balanceMicroUsd: '420'
needMicroUsd: '1300'
balanceCents: 0
needCents: 0
kind: MAX
'429':
description: '`rate_limited` — Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
rate_limited:
summary: Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.
value:
error:
code: rate_limited
message: Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.
'500':
description: '`internal_error` — Unhandled server fault. Any charge already taken is reversed.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
internal_error:
summary: Unhandled server fault. Any charge already taken is reversed.
value:
error:
code: internal_error
message: Unhandled server fault. Any charge already taken is reversed.
'503':
description: '`lite_db_unavailable` — LITE dataset still loading (cold start, under 30s). No credit spent. `service_busy` — The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
lite_db_unavailable:
summary: LITE dataset still loading (cold start, under 30s). No credit spent.
value:
error:
code: lite_db_unavailable
message: LITE dataset still loading (cold start, under 30s). No credit spent.
service_busy:
summary: The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.
value:
error:
code: service_busy
message: The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.
/v1/batch/max:
post:
tags:
- Batch
operationId: batchMax
summary: MAX Batch
description: 'Up to 100 addresses, same billing rule as the LITE batch. A per-address failure is reported as `{ "error": "upstream_error" }` inside the response object and its share of the charge is reversed.'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchRequest'
example:
ips:
- 8.8.8.8
- 1.1.1.1
- 2606:4700:4700::1111
responses:
'200':
description: An object keyed by address. Per-address failures are reported inside the object and do not fail the call.
headers:
X-Lookup-Kind:
description: Which kind was billed.
schema:
type: string
enum:
- LITE
- MAX
X-Credit-Debit-MicroUsd:
description: µUSD this call cost, as a decimal string. Net of any reversal.
schema:
type: string
pattern: ^[0-9]+$
X-Credit-Balance-MicroUsd:
description: µUSD remaining after the debit, as a decimal string.
schema:
type: string
pattern: ^[0-9]+$
content:
application/json:
schema:
$ref: '#/components/schemas/BatchMaxResponse'
examples:
mixed:
summary: One resolved address, one bogon, and one per-address failure — the three entry shapes a caller has to handle.
value:
8.8.8.8:
ip: 8.8.8.8
hostname: dns.google
location:
city: Mountain View
region: California
regionCode: CA
country: United States
countryCode: US
continent: North America
continentCode: NA
latitude: 37.4056
longitude: -122.0775
timezone: America/Los_Angeles
postalCode: '94043'
dmaCode: '807'
geonameId: '5375480'
accuracyRadiusKm: 50
geoUpdatedAt: '2026-01-04'
network:
asn: AS15169
organization: Google LLC
domain: google.com
type: hosting
asnUpdatedAt: '2021-05-01'
threats:
service: NordVPN
lastSeen: '2026-05-10'
recentActivityPct: 85
isProxy: false
isRelay: false
isTor: false
isVpn: false
isResidentialProxy: false
flags:
isAnonymous: false
isAnycast: true
isHosting: true
isMobile: false
isSatellite: false
isResidentialProxy: false
lastUpdated: '2026-08-14T09:45:16.269Z'
10.0.0.1:
ip: 10.0.0.1
bogon: true
1.1.1.1:
error: upstream_error
'400':
description: '`invalid_request` — Malformed body, invalid context, bad batch array, or an unparseable ASN.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_request:
summary: Malformed body, invalid context, bad batch array, or an unparseable ASN.
value:
error:
code: invalid_request
message: Malformed body, invalid context, bad batch array, or an unparseable ASN.
'401':
description: '`unauthorized` — Missing, invalid, or revoked API key.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
unauthorized:
summary: Missing, invalid, or revoked API key.
value:
error:
code: unauthorized
message: Missing, invalid, or revoked API key.
'402':
description: '`insufficient_credit` — Balance too low to serve the call. Nothing was debited and nothing was served. `insufficient_credit_for_max` — The balance cannot fund a MAX lookup: the signup grant is spendable on LITE only. Top up to use MAX. Nothing was debited and nothing was served.'
content:
application/json:
schema:
$ref: '#/components/schemas/InsufficientCreditError'
examples:
insufficient_credit:
summary: Balance too low to serve the call. Nothing was debited and nothing was served.
value:
error:
code: insufficient_credit
message: Balance too low to serve the call. Nothing was debited and nothing was served.
credit:
balanceMicroUsd: '420'
needMicroUsd: '1300'
balanceCents: 0
needCents: 0
kind: MAX
insufficient_credit_for_max:
summary: 'The balance cannot fund a MAX lookup: the signup grant is spendable on LITE only. Top up to use MAX. Nothing was debited and nothing was served.'
value:
error:
code: insufficient_credit_for_max
message: 'The balance cannot fund a MAX lookup: the signup grant is spendable on LITE only. Top up to use MAX. Nothing was debited and nothing was served.'
credit:
balanceMicroUsd: '5000000'
needMicroUsd: '1300'
balanceCents: 500
needCents: 0
eligibleMicroUsd: '0'
eligibleCents: 0
kind: MAX
'429':
description: '`rate_limited` — Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
rate_limited:
summary: Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.
value:
error:
code: rate_limited
message: Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.
'500':
description: '`internal_error` — Unhandled server fault. Any charge already taken is reversed.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
internal_error:
summary: Unhandled server fault. Any charge already taken is reversed.
value:
error:
code: internal_error
message: Unhandled server fault. Any charge already taken is reversed.
'503':
description: '`service_busy` — The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
service_busy:
summary: The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.
value:
error:
code: service_busy
message: The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.
/v1/batch/full:
post:
tags:
- Batch
operationId: batchFullAlias
summary: MAX Batch (Legacy Alias)
description: Legacy alias of `POST /v1/batch/max`. Use the explicit path instead.
deprecated: true
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchRequest'
example:
ips:
- 8.8.8.8
- 1.1.1.1
- 2606:4700:4700::1111
responses:
'200':
description: An object keyed by address. Per-address failures are reported inside the object and do not fail the call.
headers:
X-Lookup-Kind:
description: Which kind was billed.
schema:
type: string
enum:
- LITE
- MAX
X-Credit-Debit-MicroUsd:
description: µUSD this call cost, as a decimal string. Net of any reversal.
schema:
type: string
pattern: ^[0-9]+$
X-Credit-Balance-MicroUsd:
description: µUSD remaining after the debit, as a decimal string.
schema:
type: string
pattern: ^[0-9]+$
content:
application/json:
schema:
$ref: '#/components/schemas/BatchMaxResponse'
examples:
mixed:
summary: One resolved address, one bogon, and one per-address failure — the three entry shapes a caller has to handle.
value:
8.8.8.8:
ip: 8.8.8.8
hostname: dns.google
location:
city: Mountain View
region: California
regionCode: CA
country: United States
countryCode: US
continent: North America
continentCode: NA
latitude: 37.4056
longitude: -122.0775
timezone: America/Los_Angeles
postalCode: '94043'
dmaCode: '807'
geonameId: '5375480'
accuracyRadiusKm: 50
geoUpdatedAt: '2026-01-04'
network:
asn: AS15169
organization: Google LLC
domain: google.com
type: hosting
asnUpdatedAt: '2021-05-01'
threats:
service: NordVPN
lastSeen: '2026-05-10'
recentActivityPct: 85
isProxy: false
isRelay: false
isTor: false
isVpn: false
isResidentialProxy: false
flags:
isAnonymous: false
isAnycast: true
isHosting: true
isMobile: false
isSatellite: false
isResidentialProxy: false
lastUpdated: '2026-08-14T09:45:16.269Z'
10.0.0.1:
ip: 10.0.0.1
bogon: true
1.1.1.1:
error: upstream_error
'400':
description: '`invalid_request` — Malformed body, invalid context, bad batch array, or an unparseable ASN.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_request:
summary: Malformed body, invalid context, bad batch array, or an unparseable ASN.
value:
error:
code: invalid_request
message: Malformed body, invalid context, bad batch array, or an unparseable ASN.
'401':
description: '`unauthorized` — Missing, invalid, or revoked API key.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
unauthorized:
summary: Missing, invalid, or revoked API key.
value:
error:
code: unauthorized
message: Missing, invalid, or revoked API key.
'402':
description: '`insufficient_credit` — Balance too low to serve the call. Nothing was debited and nothing was served. `insufficient_credit_for_max` — The balance cannot fund a MAX lookup: the signup grant is spendable on LITE only. Top up to use MAX. Nothing was debited and nothing was served.'
content:
application/json:
schema:
$ref: '#/components/schemas/InsufficientCreditError'
examples:
insufficient_credit:
summary: Balance too low to serve the call. Nothing was debited and nothing was served.
value:
error:
code: insufficient_credit
message: Balance too low to serve the call. Nothing was debited and nothing was served.
credit:
balanceMicroUsd: '420'
needMicroUsd: '1300'
balanceCents: 0
needCents: 0
kind: MAX
insufficient_credit_for_max:
summary: 'The balance cannot fund a MAX lookup: the signup grant is spendable on LITE only. Top up to use MAX. Nothing was debited and nothing was served.'
value:
error:
code: insufficient_credit_for_max
message: 'The balance cannot fund a MAX lookup: the signup grant is spendable on LITE only. Top up to use MAX. Nothing was debited and nothing was served.'
credit:
balanceMicroUsd: '5000000'
needMicroUsd: '1300'
balanceCents: 500
needCents: 0
eligibleMicroUsd: '0'
eligibleCents: 0
kind: MAX
'429':
description: '`rate_limited` — Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
rate_limited:
summary: Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.
value:
error:
code: rate_limited
message: Per-key cap of 50 requests/second exceeded, or the upstream provider rate-limited a MAX lookup. No credit spent.
'500':
description: '`internal_error` — Unhandled server fault. Any charge already taken is reversed.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
internal_error:
summary: Unhandled server fault. Any charge already taken is reversed.
value:
error:
code: internal_error
message: Unhandled server fault. Any charge already taken is reversed.
'503':
description: '`service_busy` — The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
service_busy:
summary: The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.
value:
error:
code: service_busy
message: The database was briefly unable to start a transaction. Nothing was charged. Retry after a second.
/v1/batch:
post:
tags:
- Batch
operationId: batchBareAlias
summary: MAX Batch (Legacy Alias)
description: Legacy alias of `POST /v1/batch/max`. Use the explicit path instead.
deprecated: true
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchRequest'
example:
ips:
- 8.8.8.8
- 1.1.1.1
- 2606:4700:4700::1111
responses:
'200':
description: An object keyed by address. Per-address failures are reported inside the object and do not fail the call.
headers:
X-Lookup-Kind:
description: Which kind was billed.
schema:
type: string
enum:
- LITE
- MAX
X-Credit-Debit-MicroUsd:
description: µUSD this call cost, as a decimal string. Net of any reversal.
schema:
type: string
pattern: ^[0-9]+$
X-Credit-Balance-MicroUsd:
description: µUSD remaining after the debit, as a decimal string.
schema:
type: string
pattern: ^[0-9]+$
content:
application/json:
schema:
$ref: '#/components/schemas/BatchMaxResponse'
examples:
mixed:
summary: One resolved address, one bogon, and one per-address failure — the three entry shapes a caller has to handle.
value:
8.8.8.8:
ip: 8.8.8.8
hostname: dns.google
location:
city: Mountain View
region: California
regionCode: CA
country: United States
countryCode: US
continent: North America
continentCode: NA
latitude: 37.4056
longitude: -122.0775
timezone: America/Los_Angeles
postalCode: '94043'
dmaCode: '807'
geonameId: '5375480'
accuracyRadiusKm: 50
geoUpdatedAt: '2026-01-04'
network:
asn: AS15169
organization: Google LLC
domain: google.com
type: hosting
asnUpdatedAt: '2021-05-01'
threats:
service: NordVPN
lastSeen: '2026-05-10'
recentActivityPct: 85
isProxy: false
isRelay: false
isTor: false
isVpn: false
isResidentialProxy: false
flags:
isAnonymous: false
isAnycast: true
isHosting: true
isMobile: false
isSatellite: false
isResidentialProxy: false
lastUpdated: '2026-08-14T09:45:16.269Z'
10.0.0.1:
ip: 10.0.0.1
bogon: true
1.1.1.1:
error: upstream_error
'400':
description: '`invalid_request` — Malformed body, invalid context, bad batch array, or an unparseable ASN.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_request:
summary: Malformed body, invalid context, bad batch array, or an unparseable ASN.
value:
error:
code: invalid_request
message: Malformed body, invalid context, bad batch array, or an unparseable ASN.
'401':
description: '`unauthorized` — Missing, invalid, or revoked API key.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
unauthorized:
summary: Missing, invalid, or revoked API key.
value:
error:
code: unauthorized
message: Missing, invalid, or revoked API key.
'402':
description: '`insufficient_credit` — Balance too low to serve the call. Nothing was debited and nothing was served. `insufficient_credit_for_max` — The balance cannot fund a MAX lookup: the signup grant is spendable on LITE only. Top up to use MAX. Nothing was debited and nothing was served.'
content:
application/json:
schema:
$ref: '#/components/schemas/InsufficientCreditError'
examples:
insufficient_credit:
summary: Balance too low to serve the call. Nothing was debited and nothing was served.
value:
error:
code: insufficient_credit
message: Balance too low to serve the call. Nothing was debited and nothing was served.
credit:
bal
# --- truncated at 32 KB (46 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lookip/refs/heads/main/openapi/lookip-batch-api-openapi.yml