ipdex API
The open index of the IP world, as an API. Free tier: no API keys, no signup, CORS * — usable from a browser tab, a cron job, or a dotfile. Machine-readable spec: openapi.json · openapi.yaml.
Getting started
curl https://api.ipdex.io/v1/lookup/8.8.8.8
That's the whole onboarding. The Free tier is rate-limited to 60 requests/minute/IP, enforced at the edge; every response carries informational RateLimit-Limit / RateLimit-Policy headers. If you are hitting the limits with a real use case, we want to hear about it — open an issue on GitHub.
The shell shortcuts also exist on the site root: curl ipdex.io returns your bare IP; curl ipdex.io/json returns your compact connection snapshot. Neither is ever stored.
Data & versioning
Sources: IPinfo Lite, PeeringDB, the five RIRs' delegated statistics, and BGP tables — rebuilt and gate-validated nightly; a failed validation never publishes (the dataset is either yesterday's good build or today's good build, never a partial). Every response carries x-data-version, the content hash of the dataset that produced it; the changelog lists every published version. History tables (daily, monthly, allocation events) are append-only: rows are real observed snapshots, never interpolated, and missing periods are honestly absent rather than filled.
Endpoints
GET /v1/me
Full self-lookup from the edge (request.cf). Never stored.
200 Visitor snapshot + data version
curl https://api.ipdex.io/v1/me
{
"ip": "203.0.113.10",
"ipVersion": 4,
"asn": 13335,
"asOrganization": "Example Networks",
"country": "US",
"city": "…",
"region": "…",
"timezone": "America/New_York",
"colo": "EWR",
"httpProtocol": "HTTP/3",
"tlsVersion": "TLSv1.3",
"clientTcpRtt": 12,
"isTor": false,
"dataVersion": "551c9b9a385b"
} GET /v1/me/ip
Bare client IP as text/plain.
200 The IP address
curl https://api.ipdex.io/v1/me/ip
203.0.113.10
GET /v1/lookup/{ip}
Resolve an IP to ASN, org and country from the index.
| Param | In | Type | Notes |
|---|---|---|---|
| ip* | path | string | e.g. 8.8.8.8 |
200 Lookup result (asn/org/country null when unrouted/unknown) · 400 Invalid IP
curl https://api.ipdex.io/v1/lookup/8.8.8.8
{
"ip": "8.8.8.8",
"version": 4,
"asn": 15169,
"asnType": "content",
"org": "Google LLC",
"orgSlug": "google-asia-pacific-pte-ltd",
"country": "US",
"source": "derived",
"lastUpdated": "2026-06-12T19:43:43.885Z"
} GET /v1/asn/{asn}
ASN summary.
| Param | In | Type | Notes |
|---|---|---|---|
| asn* | path | string | e.g. AS15169 |
200 ASN record · 400 Invalid ASN · 404 Unknown ASN
curl https://api.ipdex.io/v1/asn/AS8452
{
"asn": 8452,
"org": "TE-AS",
"orgSlug": "eg-ix-route-servers",
"country": "EG",
"type": "isp",
"domain": "te.eg",
"allocatedDate": "1997-09-01",
"prefixCountV4": 1703,
"prefixCountV6": 9,
"source": "derived",
"lastUpdated": "2026-06-14T19:28:22.818Z",
"rpki": { "valid": 1704, "invalid": 0, "total": 1719 }
} GET /v1/prefix/{cidr}
A stored prefix's announcing origin(s) + RPKI status.
| Param | In | Type | Notes |
|---|---|---|---|
| cidr* | path | string | CIDR; the slash is part of the path. |
200 Prefix record · 400 Invalid CIDR · 404 Prefix not in our data
curl https://api.ipdex.io/v1/prefix/8.8.8.0/24
{
"prefix": "8.8.8.0/24",
"version": 4,
"origins": [
{
"asn": 15169,
"org": "Google LLC",
"rpki": "valid"
}
],
"source": "derived",
"lastUpdated": "2026-06-16T00:00:00.000Z"
} GET /v1/org/{slug}
An organization + a capped list of its ASNs.
| Param | In | Type | Notes |
|---|---|---|---|
| slug* | path | string | e.g. google-llc |
200 Org record · 400 Invalid slug · 404 Unknown org
curl https://api.ipdex.io/v1/org/cloudflare-sydney-llc
{
"slug": "cloudflare-sydney-llc",
"name": "Cloudflare Sydney, LLC",
"country": "US",
"type": "unknown",
"asnCount": 8,
"asns": [
{
"asn": 14789,
"type": "unknown",
"country": "PK"
},
{
"asn": 132892,
"type": "unknown",
"country": "US"
}
],
"source": "derived",
"lastUpdated": "2026-06-12T19:43:43.885Z"
} GET /v1/country/{cc}
Country overview (complements /v1/country/{cc}/history).
| Param | In | Type | Notes |
|---|---|---|---|
| cc* | path | string | e.g. EG |
200 Country record · 400 Invalid country code · 404 Unknown country
curl https://api.ipdex.io/v1/country/EG
{
"cc": "EG",
"name": "Egypt",
"rir": "afrinic",
"totalV4": 24151552,
"totalV6Prefixes": 21,
"asnCount": 95,
"source": "derived",
"lastUpdated": "2026-06-12T19:43:43.885Z"
} GET /v1/ix/{id}
An Internet Exchange (source: PeeringDB).
| Param | In | Type | Notes |
|---|---|---|---|
| id* | path | integer | e.g. 31 |
200 IX record · 400 Invalid IX id · 404 Unknown IX
curl https://api.ipdex.io/v1/ix/1
{
"ixId": 1,
"name": "Equinix Ashburn",
"city": "Ashburn",
"country": "US",
"memberCount": 345,
"source": "peeringdb",
"lastUpdated": "2026-06-14T19:28:22.818Z"
} GET /v1/facility/{id}
A colocation facility (source: PeeringDB).
| Param | In | Type | Notes |
|---|---|---|---|
| id* | path | integer | e.g. 1 |
200 Facility record · 400 Invalid facility id · 404 Unknown facility
curl https://api.ipdex.io/v1/facility/1
{
"facId": 1,
"name": "Equinix DC1-DC15,DC21-DC22 - Ashburn",
"city": "Ashburn",
"country": "US",
"source": "peeringdb",
"lastUpdated": "2026-06-14T19:28:22.818Z"
} GET /v1/search
Grouped entity search: countries, networks (ASNs) and organizations.
Prefix matches rank above contains; an "AS" prefix on a numeric query is stripped (AS8452 ≡ 8452). Results are grouped with a per-group limit. Cached by the query string (never by the caller).
| Param | In | Type | Notes |
|---|---|---|---|
| q* | query | string | e.g. vodafone |
| limit | query | integer | Per-group result cap |
200 Grouped results · 400 Empty or over-long q
curl 'https://api.ipdex.io/v1/search?q=vodafone'
{
"q": "vodafone",
"dataVersion": "551c9b9a385b",
"countries": [],
"asns": [
{
"asn": 24835,
"org": "Vodafone Data",
"orgSlug": "vodafone-data",
"cc": "EG"
},
{
"asn": 38266,
"org": "Vodafone Idea Ltd",
"orgSlug": "vodafone-idea-ltd-3",
"cc": "IN"
},
{
"asn": 45271,
"org": "Vodafone Idea Ltd",
"orgSlug": "vodafone-idea-ltd",
"cc": "IN"
},
{
"asn": 55410,
"org": "Vodafone Idea Ltd",
"orgSlug": "vodafone-idea-ltd-2",
"cc": "IN"
},
{
"asn": 36935,
"org": "Vodafone Data",
"orgSlug": "vodafone-international-services-l-l-c",
"cc": "EG"
}
],
"orgs": [
{
"slug": "vodafone-international-services-l-l-c",
"name": "Vodafone International Services L.L.C",
"cc": "EG",
"type": "unknown"
… GET /v1/country/{cc}/history
Country history: monthly RIR allocation events + the daily stats series.
Both arrays ascending, numbers as numbers. `alloc` derives from the RIR delegated files’ per-record allocation dates (sparse — only months with events; sentinels bucket under XX). `daily` is our own gate-validated snapshot, accumulating since 2026-06. `monthly` is REGISTRY STATE per archived monthly snapshot, parsed from the RIRs’ historical delegated files (archives reach 2001–2005 depending on registry) — sparse: months whose snapshot is missing or failed its reconciliation gate simply do not exist (never interpolated). When the requested daily window exceeds 400 points the series is RANGE-REDUCED — every Nth REAL stored point is returned (never averaged or interpolated) and `reduced` is true. `?granularity=monthly` keeps the LAST real row of each month. Sentinel codes (XX, T1) are served like any cc.
| Param | In | Type | Notes |
|---|---|---|---|
| cc* | path | string | e.g. EG |
| from | query | string | ISO prefix lower bound: YYYY, YYYY-MM or YYYY-MM-DD |
| to | query | string | ISO prefix upper bound (inclusive of the whole prefix) |
| granularity | query | string: daily | monthly | Granularity of the `daily` series (`alloc` is inherently monthly) |
200 History series · 400 Invalid cc / range / granularity · 404 Unknown country
curl 'https://api.ipdex.io/v1/country/EG/history?from=2000&granularity=monthly'
{
"cc": "EG",
"dataVersion": "551c9b9a385b",
"alloc": [
{
"ym": "2024-02",
"rir": "afrinic",
"v4_addrs": 256,
"v6_blocks": 0,
"asn_count": 1
},
{
"ym": "2024-05",
"rir": "afrinic",
"v4_addrs": 1024,
"v6_blocks": 0,
"asn_count": 1
},
{
"ym": "2024-08",
"rir": "afrinic",
"v4_addrs": 0,
"v6_blocks": 1,
"asn_count": 0
},
{
"ym": "2024-09",
"rir": "afrinic",
"v4_addrs": 1024,
"v6_blocks": 0,
"asn_count": 0
},
{
"ym": "2024-11",
"rir": "afrinic",
"v4_addrs": 1024,
"v6_blocks": 1,
"asn_count": 1
},
{
"ym": "2025-04",
"rir": "afrinic",
"v4_addrs": 1024,
"v6_blocks": 0,
"asn_count": 0
},
{
"ym": "2025-06",
"rir": "afrinic",
"
… GET /v1/asn/{asn}/history
ASN daily stats history (sparse, write-on-change).
Rows are returned AS STORED — SPARSE: an (asn, day) row exists only when a value changed that day. READ CONVENTION (forward-fill): the absence of a row for a day means “unchanged since the latest row with day ≤ that day” — clients carry the last value forward; `sparse: true` marks this. Day-1 of the series (2026-06) is a full population. Same `from`/`to`/`granularity` and 400-point range-reduction semantics as the country endpoint — reduction drops real points, never averages.
| Param | In | Type | Notes |
|---|---|---|---|
| asn* | path | string | e.g. AS8452 |
| from | query | string | ISO prefix lower bound |
| to | query | string | ISO prefix upper bound (inclusive of the whole prefix) |
| granularity | query | string: daily | monthly |
200 Sparse history series · 400 Invalid ASN / range / granularity · 404 Unknown ASN
curl https://api.ipdex.io/v1/asn/AS8452/history
{
"asn": 8452,
"dataVersion": "551c9b9a385b",
"sparse": true,
"daily": [
{
"day": "2026-06-12",
"prefix_count": 1718,
"v4_addrs": 7586304,
"v6_ranges": 3
},
{
"day": "2026-06-13",
"prefix_count": 1718,
"v4_addrs": 7586304,
"v6_ranges": 3
}
],
"reduced": false,
"…": "…more"
}