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-lookup-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 Lookup 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: Lookup
description: Single-address lookups.
paths:
/v1/lookup/lite/{ip}:
get:
tags:
- Lookup
operationId: lookupLite
summary: LITE Lookup
description: 'Geolocation and ASN from our local dataset. Reserved and non-routable addresses answer `{ ip, bogon: true }` free of charge and set no credit headers.'
parameters:
- name: ip
in: path
required: true
description: IPv4 or IPv6 address.
schema:
type: string
example: 8.8.8.8
responses:
'200':
description: A LITE record, or a bogon record.
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/LiteRecord'
examples:
record:
summary: A LITE record.
value:
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'
bogon:
summary: A reserved or non-routable address. Free, and no credit headers are set.
value:
ip: 10.0.0.1
bogon: true
'400':
description: '`invalid_ip` — The supplied address is not a valid IPv4 or IPv6.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_ip:
summary: The supplied address is not a valid IPv4 or IPv6.
value:
error:
code: invalid_ip
message: The supplied address is not a valid IPv4 or IPv6.
'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/lookup/lite:
post:
tags:
- Lookup
operationId: lookupLitePost
summary: LITE Lookup With Context
description: Same answer as the GET form, with an optional `context` object.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LookupRequest'
example:
ip: 8.8.8.8
context:
note: 'checkout #4821'
tags:
- signup
responses:
'200':
description: A LITE record, or a bogon record.
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/LiteRecord'
examples:
record:
summary: A LITE record.
value:
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'
bogon:
summary: A reserved or non-routable address. Free, and no credit headers are set.
value:
ip: 10.0.0.1
bogon: true
'400':
description: '`invalid_ip` — The supplied address is not a valid IPv4 or IPv6. `invalid_request` — Malformed body, invalid context, bad batch array, or an unparseable ASN.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_ip:
summary: The supplied address is not a valid IPv4 or IPv6.
value:
error:
code: invalid_ip
message: The supplied address is not a valid IPv4 or IPv6.
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/lookup/max/{ip}:
get:
tags:
- Lookup
operationId: lookupMax
summary: MAX Lookup
description: 'Full enrichment. Reserved and non-routable addresses answer `{ ip, bogon: true }` free of charge and set no credit headers.'
parameters:
- name: ip
in: path
required: true
description: IPv4 or IPv6 address.
schema:
type: string
example: 8.8.8.8
responses:
'200':
description: A MAX record, or a bogon record.
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/IpRecord'
examples:
record:
summary: A MAX record. `threats.service`, `threats.lastSeen` and `threats.recentActivityPct` are shown populated so the shape is visible; they are present only when the address is a detected anonymiser.
value:
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'
bogon:
summary: A reserved or non-routable address. Free, and no credit headers are set.
value:
ip: 10.0.0.1
bogon: true
'400':
description: '`invalid_ip` — The supplied address is not a valid IPv4 or IPv6.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_ip:
summary: The supplied address is not a valid IPv4 or IPv6.
value:
error:
code: invalid_ip
message: The supplied address is not a valid IPv4 or IPv6.
'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
'404':
description: '`not_found` — No such ASN on the ASN endpoints. On a MAX lookup it also means the upstream provider holds no record for the address; the charge is reversed.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
not_found:
summary: No such ASN on the ASN endpoints. On a MAX lookup it also means the upstream provider holds no record for the address; the charge is reversed.
value:
error:
code: not_found
message: No such ASN on the ASN endpoints. On a MAX lookup it also means the upstream provider holds no record for the address; the charge is reversed.
'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.
'502':
description: '`upstream_error` — MAX enrichment failed. The status mirrors the upstream response when it sent one, so any 4xx or 5xx is possible here. The charge is reversed automatically. `auth_failed` — MAX enrichment could not authenticate to our upstream data provider. This is our credential, not yours — your key is fine and must not be discarded. Nothing is charged. Back off and retry.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
upstream_error:
summary: MAX enrichment failed. The status mirrors the upstream response when it sent one, so any 4xx or 5xx is possible here. The charge is reversed automatically.
value:
error:
code: upstream_error
message: MAX enrichment failed. The status mirrors the upstream response when it sent one, so any 4xx or 5xx is possible here. The charge is reversed automatically.
auth_failed:
summary: MAX enrichment could not authenticate to our upstream data provider. This is our credential, not yours — your key is fine and must not be discarded. Nothing is charged. Back off and retry.
value:
error:
code: auth_failed
message: MAX enrichment could not authenticate to our upstream data provider. This is our credential, not yours — your key is fine and must not be discarded. Nothing is charged. Back off and retry.
'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.
default:
description: '`upstream_error` — MAX enrichment failed. The status mirrors the upstream response when it sent one, so any 4xx or 5xx is possible here. The charge is reversed automatically.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
upstream_error:
summary: MAX enrichment failed. The status mirrors the upstream response when it sent one, so any 4xx or 5xx is possible here. The charge is reversed automatically.
value:
error:
code: upstream_error
message: MAX enrichment failed. The status mirrors the upstream response when it sent one, so any 4xx or 5xx is possible here. The charge is reversed automatically.
/v1/lookup/max:
post:
tags:
- Lookup
operationId: lookupMaxPost
summary: MAX Lookup With Context
description: Same answer as the GET form, with an optional `context` object.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LookupRequest'
example:
ip: 8.8.8.8
context:
note: 'checkout #4821'
tags:
- signup
responses:
'200':
description: A MAX record, or a bogon record.
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/IpRecord'
examples:
record:
summary: A MAX record. `threats.service`, `threats.lastSeen` and `threats.recentActivityPct` are shown populated so the shape is visible; they are present only when the address is a detected anonymiser.
value:
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'
bogon:
summary: A reserved or non-routable address. Free, and no credit headers are set.
value:
ip: 10.0.0.1
bogon: true
'400':
description: '`invalid_ip` — The supplied address is not a valid IPv4 or IPv6. `invalid_request` — Malformed body, invalid context, bad batch array, or an unparseable ASN.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_ip:
summary: The supplied address is not a valid IPv4 or IPv6.
value:
error:
code: invalid_ip
message: The supplied address is not a valid IPv4 or IPv6.
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:
un
# --- truncated at 32 KB (110 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lookip/refs/heads/main/openapi/lookip-lookup-api-openapi.yml