Skip to main content

WorldIP API — Developer Documentation

A fast, JSON REST API over the same global IP intelligence that powers worldip.io — IP profiles, ASN & organization ownership, reverse/forward DNS, VPN/proxy classification, trust scoring and live BGP routing events. Built on a worldwide adaptive-scanning fleet processing over a billion record updates a day, with sub-second responses for cached profiles.

v1 · beta Bearer-token auth JSON responses IPv4 + IPv6 Sliding-window rate limits Globally distributed

MCP server (for AI agents)

WorldIP speaks the Model Context Protocol, so an MCP-aware client can call it as a tool instead of scraping pages. No API key is required — the server exposes the same free keyless profile as the public endpoints.

Endpointhttps://worldip.io/mcp
TransportHTTP, JSON-RPC 2.0 over POST. A GET returns 405 by design — it is an API endpoint, not a page.
Protocol2025-06-18
AuthNone. Rate-limited per source IP.
Server card/.well-known/mcp/server-card.json

Add it to Claude Code

claude mcp add --transport http worldip https://worldip.io/mcp

Or by hand in .mcp.json

The type field selects the transport — the config will not work without it.

{ "mcpServers": { "worldip": { "type": "http", "url": "https://worldip.io/mcp" } } }

Tools

lookup_ipLook up a public IPv4 or IPv6 address: owner/organisation, ASN, country, region, city, CIDR, reverse DNS (PTR) and forward-confirmed DNS, plus a weekly count of the domains hosted on an IPv4 address (domains_hosted, from issued.live). Takes ip.
whats_my_ipReturn the caller’s own public IP and its profile. Takes no arguments.

Both tools are read-only, idempotent and open-world (they consult live data), and are annotated as such in tools/list.

The tools and the free keyless endpoint (https://worldip.io/{ip}) carry domains_hosted: how many registrable domains have a name resolving to the address, counted once a week from issued.live's DNS snapshot — a number, never the names. count is 0 when none were seen and null when the count is unavailable; the whole object is null for reserved addresses and, for now, for IPv6. The keyed lookup below is unchanged.

"domains_hosted": {"count":42650,"as_of":"2026-10-11","source":"issued.live","attribution":"Domain data provided by issued.live — for full details visit https://issued.live/pricing","details_url":"https://issued.live/pricing"}

Getting started

Every endpoint lives under a single HTTPS base URL and returns application/json. A successful response is 200 OK with the record at the top level; errors use standard HTTP status codes with a JSON error body (see Errors).

Base URLhttps://worldip.io
Versionv1 (path-versioned)
FormatJSON, UTF-8. Slashes are unescaped.
MethodsGET (all data endpoints). OPTIONS is accepted for CORS preflight.
AuthAuthorization: Bearer YOUR_KEY, over HTTPS only. Never put a key in a URL (?key=).

Quickstart — one full IP profile

curl
curl -s https://worldip.io/api/v1/ext/lookup/8.8.8.8 \
  -H "Authorization: Bearer YOUR_KEY"
Getting a key. The WorldIP API is in beta. During the beta our team issues keys, free, to customers of issued.live Plus and Pro — see Beta keys. Paid plans and self-serve keys are not open yet. Without a key, the keyless endpoint (https://worldip.io/{ip}, 1,000 lookups a day) and the public Pulse feeds (below) work today.

Beta keys for issued.live Plus and Pro customers

While the WorldIP API is in beta, our team issues API keys free of charge to customers with an active issued.live Plus or Pro subscription. issued.live and WorldIP are separate services run by the same company, Tuxxin LLC: your issued.live plan and billing do not change, and WorldIP charges nothing for a beta key.

issued.live planWorldIP keyEnriched lookups / moPer minuteConcurrentData
PlusPro200,00060010 The IP profile lookup with VPN / proxy / Tor / datacenter classification, residential & mobile proxy detection, access type, trust score, BGP prefix and origin ASN, /24 neighbours, region and city.
ProBusiness1,000,0001,20020 Everything in Pro, plus MOAS and routing anomalies on the lookup, Web3 node roles and the Pulse API.

Basic lookups on https://worldip.io/{ip} with your key have no daily cap. Responses carry X-RateLimit-* (per minute) and X-Concurrency-Limit (requests in flight); enriched lookups also carry X-Quota-* (monthly enriched lookups). Limits may change during the beta.

How to get your key

  • Subscribe to issued.live Plus or Pro. We issue keys by hand and email yours to the address on your issued.live account within one business day.
  • No key after one business day? Contact us from that address.
  • We store only a hash of your key and cannot show it again, so keep it safe. If you lose it or it leaks, contact us and we will replace it.

Using your key

  • Send it only in the Authorization: Bearer YOUR_KEY header, and only to https:// URLs.
  • Never put it in a URL (?key=): URLs are written to server, proxy and browser logs. Never ship it in browser or app code that others can read; call the API from your server.
  • Keep the attribution text (and grip_attribution where present) with any API data you display or pass on: some fields come from licensed datasets (see Data sources).

Beta conditions

  • Free during the beta, one key per issued.live subscription, for you or your organisation only. Do not share, publish, sell or sublicense it.
  • Limits may change during the beta, and so may fields and endpoints. We announce breaking changes on this page and email key holders.
  • No SLA. Beta keys come with no uptime commitment.
  • Revocation. We may suspend or revoke a key that is abused or used against our Terms, and we revoke it when the issued.live subscription it came with ends.
  • End of the beta: 30 days after WorldIP’s paid plans launch. We will email you before then. Nothing is charged automatically.
  • Support is best effort, through our contact form.

The full terms are in our Terms of Use (API keys and the beta).

Authentication

Present your key on every keyed request as a Bearer token, over HTTPS only. Do not use the ?key= query parameter: it is accepted only for older integrations, and a key in a URL is written to server logs and can leak through referrers and browser history.

Header
Authorization: Bearer YOUR_KEY

Scopes

Each key carries one or more scopes. A request is rejected with 403 forbidden_scope if its key lacks the scope the endpoint requires.

ScopeGrants
ext:readThe IP profile lookup (/api/v1/ext/lookup) and keyed basic lookups on https://worldip.io/{ip}.
pulse:readThe keyed Pulse event stream + summary (Business keys).
*All scopes (issued only to trusted / enterprise integrations).

Key locking (optional)

A key can be pinned so a leaked value is useless elsewhere:

  • Origin lock — restricts browser calls to one site (enforced whenever the request carries an Origin/Referer). Mismatch → 403 origin_not_allowed.
  • IP allow-list — restricts calls to specific caller IPs, the strongest server-to-server lock. Off-list → 403 ip_not_allowed.

IP profile lookup

GET /api/v1/ext/lookup/{ipv4} scope: ext:read

One consolidated intelligence profile for an IPv4 address: PTR, ASN, organization, country, CIDR, trust score, VPN/proxy/Tor/datacenter classification (including a residential & mobile proxy verdict), BGP route + recent routing anomalies, the hosted-domain count, and Web3 roles. The same route takes an IPv6 address; see IPv6 lookups for what an IPv6 profile contains. The assembly is cached per IP for five minutes at the origin, so repeat lookups return in milliseconds (X-Ext-Cache: HIT / MISS). Responses are never cached by shared caches (Cache-Control: private, no-store), so every call is counted.

Path parameterDescription
ipv4Dotted-quad IPv4 address, e.g. 8.8.8.8. Invalid input → 400 bad_ip.
ipv6Any valid IPv6 notation, e.g. 2001:4860:4860::8888 (echoed back in canonical compressed form). Invalid input → 400 bad_ip.
Request
curl -s https://worldip.io/api/v1/ext/lookup/8.8.8.8 \
  -H "Authorization: Bearer YOUR_KEY"
200 OK
{
  "ip": "8.8.8.8",
  "reserved": false,
  "reserved_note": null,
  "ptr": "dns.google",
  "asn": { "number": 15169, "name": "Google LLC" },
  "org": { "name": "Google LLC", "slug": "google-llc", "category": "hosting" },
  "country": { "code": "US", "name": "United States" },
  "cidr": "8.8.8.0/24",
  "trust": { "score": 92, "band": "Trusted", "color": "#3fb950" },
  "web3": [],
  "bgp": {
    "prefix": "8.8.8.0/24",
    "origin_asn": 15169,
    "moas": false,
    "anomalies": []
  },
  "forward_dns": null,
  "flags": [
    { "key": "hosting", "label": "Hosting/DC", "level": "warn", "emoji": "🖥️",
      "title": "Datacenter / hosting network - server addresses, not home connections." }
  ],
  "classification": {
    "is_vpn": false,
    "is_proxy": false,
    "is_relay": false,
    "relay_source": null,
    "is_anonymous": false,
    "access_type": "hosting",
    "proxy_density_30d": null,
    "vpn_density_30d": null,
    "is_tor": false,
    "is_datacenter": true,
    "is_vpn_likely": false,
    "verdict": "hosting",
    "confidence": "high",
    "score": 0,
    "source": "worldip-classification"
  },
  "grip": null,
  "grip_attribution": null,
  "attribution": "Includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com, used under the MaxMind GeoLite End User License Agreement; GeoLite2 incorporates GeoNames data (https://www.geonames.org) under CC BY 4.0. Includes the IPinfo Lite dataset (https://ipinfo.io) under CC BY-SA 4.0. License details: https://worldip.io/data-sources",
  "links": {
    "ip": "https://worldip.io/8.8.8.8",
    "asn": "https://worldip.io/asn/AS15169",
    "org": "https://worldip.io/org/google-llc"
  },
  "generated_at": "2026-07-17T00:45:12+00:00"
}

Response fields

FieldTypeNotesTier
ipstringCanonical IPv4 echoed back.Free
ptrstring | nullReverse-DNS hostname.Free
asnobject | nullnumber, name.Free
orgobject | nullname, slug, category.Free
countryobject | nullISO-2 code + name.Free
cidrstring | nullAllocated block this IP sits in.Free
linksobjectCanonical worldip.io URLs for the IP/ASN/org.Free
forward_dnsobject | nullHow many domains are hosted on the IP: hosted_domain_count. On plan keys (Basic and up, beta keys included) this object carries the count only: hosted_domains is always an empty list, hostname and registerable_domain are always null, and hosted_domains_truncated is true whenever the count is above 0. Keys without a plan (such as keys issued before the beta) keep the original object, which also lists a sample of up to 25 names (usually about 10) and fills hostname and registerable_domain. For now the count comes from GRIP, covers IPv4 only and is present only while WorldIP holds a GRIP result for the address from the last few hours; otherwise forward_dns is null.Basic
classificationobjectVPN / proxy / Tor / datacenter, access_type, residential/mobile-proxy verdict, confidence, score, and is_relay + relay_source (Apple iCloud Private Relay egress).Pro
trustobject | nullscore 0-100, band, color.Pro
flagsarrayHuman-readable risk chips (Tor exit, Proxy/VPN, Hosting/DC, Malware).Pro
bgpobject | nullprefix and origin_asn (Basic and up); moas and the last 7 days’ routing anomalies[] ({type, severity, count}; Business and up).Basic Business
web3arrayBlockchain node roles hosted on the IP (chain + role).Business
generated_atstringISO-8601 UTC timestamp of assembly.Free
attributionstringData-licence attribution for the geolocation, ASN and organization fields (MaxMind GeoLite2 with GeoNames, IPinfo Lite). Present on every plan; the keyless endpoint carries it as _meta.attribution.Free
versioninteger6. IPv6 profiles only; an IPv4 profile has no version key.Free
address_type, prefixes, embedded_ipv4string, object, string | nullIPv6 only: address class, the containing /32 /48 /56 /64, and the IPv4 inside a NAT64 or 6to4 address.Free
rdnsobjectIPv6 only: scan status, kind of PTR (isp_generated, wildcard or specific), checked_at, forward_check, note.Free
unavailableobjectIPv6 only: every field that is null because WorldIP has no IPv6 source for it, with the reason.Free
Residential & mobile proxy detection. When an address is an egress node for a residential or mobile proxy network, classification.verdict becomes residential_proxy with is_proxy: true. Observations expire: an address that is no longer seen as a proxy exit drops out of the verdict. Unlocked on the Pro tier.
iCloud Private Relay. classification.is_relay is true when the address is an Apple iCloud Private Relay egress. We match it against our own copy of Apple's published egress list, refreshed daily, and relay_source is then "icloud_private_relay". When only GRIP flags the relay it is "grip", and otherwise null. A relay egress carries traffic for many ordinary Apple users whose own addresses are hidden, so it does not change verdict, is_vpn, is_proxy or the trust score. IPv6 lookups use the same list; GRIP has no IPv6 data, so for IPv6 relay_source is "icloud_private_relay" or null.

IPv6 lookups

Both IP endpoints take IPv6 addresses: the free keyless https://worldip.io/{ipv6} and the keyed /api/v1/ext/lookup/{ipv6}. An IPv6 profile has the same keys as an IPv4 one, so one parser handles both, plus "version": 6, the containing prefixes and an rdns block. Authentication, scopes, per-key rate and concurrency limits, the monthly allowance, plan data tiers, CORS and the 5-minute origin cache work exactly as for IPv4.

IPv6 fieldSourceEndpoint
country, region, cityThe same geolocation release as our IPv4 data, rebuilt daily. City-level IPv6 geolocation is approximate and often absent.Keyless + keyed
asn, org.name, cidrThe same ASN and organization data as IPv4. cidr is the most specific network we hold for the address.Keyless + keyed
ptr, rdns (and the keyless forward_dns forward check)WorldIP's own IPv6 reverse-DNS scans.Keyless + keyed
org.slug, org.categoryThe organization's slug and category (isp, hosting, cdn, …), as for IPv4.Keyed (every plan)
classification.is_datacenter, access_type, flagsHosting/datacenter classification by the network's organization, as for IPv4.Keyed (Pro+)
classification.blocklists, is_bogonIPv6 blocklists (Spamhaus DROPv6) and Team Cymru IPv6 fullbogons.Keyed (Pro+)
classification.is_relayApple iCloud Private Relay egress list, refreshed daily.Keyed (Pro+)
Not available for IPv6. VPN and proxy exit detection, the trust score and risk axis, live BGP origin/MOAS, the hosted-domain count and Web3 roles are IPv4-only. In an IPv6 profile these fields are null, never false, and the unavailable object names each one with the reason. is_vpn, is_proxy and is_tor are true only when an IPv6 blocklist lists the address; otherwise they are null.
ISP-generated reverse DNS. About 99% of the IPv6 PTR names we scan come from an ISP naming template or are one wildcard name shared by many addresses. rdns.kind is isp_generated when the name encodes the address (for example p200300c8....dip0.t-ipconnect.de, in hex, hextets, nibbles or base 36) or comes from a network that gives every address its own generated name, and wildcard for a name shared by many addresses. Such a name shows which network the address is in. It is not evidence that a host is live there. specific means we found no template or wildcard, not that the name was assigned by hand. When our latest scan could not resolve the address, rdns.status is lookup_failed and ptr is the last name we saw. rdns.forward_check is confirmed, mismatch or not_checked; forward_dns.confirmed is true only when it is confirmed.
Request (keyless)
curl -s https://worldip.io/2003:c8:734:9700::1
200 OK
{
  "ip": "2003:c8:734:9700::1",
  "version": 6,
  "ptr": "p200300c8073497000000000000000001.dip0.t-ipconnect.de",
  "forward_dns": { "hostname": "p200300c8073497000000000000000001.dip0.t-ipconnect.de", "confirmed": true },
  "asn": { "number": 3320, "name": "Deutsche Telekom AG" },
  "org": { "name": "Deutsche Telekom AG" },
  "country": { "code": "DE", "name": "Germany" },
  "region": "Baden-Wurttemberg",
  "city": "Leutkirch",
  "cidr": "2003:c8:400::/38",
  "address_type": "Global Unicast",
  "prefixes": { "/32": "2003:c8::/32", "/48": "2003:c8:734::/48", "/56": "2003:c8:734:9700::/56", "/64": "2003:c8:734:9700::/64" },
  "rdns": {
    "status": "found",
    "kind": "isp_generated",
    "checked_at": "2026-09-30T10:34:08Z",
    "forward_check": "confirmed",
    "note": "ISP-generated name: the network names every address from a template, usually by encoding the address itself. It shows which network the address belongs to, not that a host is live there."
  },
  "_meta": { "keyless": true, "docs": "https://worldip.io/developers", "note": "...",
             "attribution": "Includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com, used under the MaxMind GeoLite End User License Agreement; GeoLite2 incorporates GeoNames data (https://www.geonames.org) under CC BY 4.0. Includes the IPinfo Lite dataset (https://ipinfo.io) under CC BY-SA 4.0. License details: https://worldip.io/data-sources",
             "generated_at": "...", "rate": { "limit": 1000, "remaining": 999, "reset": "...", "window_seconds": 86400 } }
}
Keyed: classification for an iCloud Private Relay egress (excerpt)
curl -s https://worldip.io/api/v1/ext/lookup/2606:54c0:5898::1 -H "Authorization: Bearer YOUR_KEY"

"org": { "name": "Cloudflare, Inc.", "slug": "cloudflare-inc", "category": "cdn" },
"classification": {
  "is_vpn": null, "is_proxy": null, "is_relay": true, "relay_source": "icloud_private_relay",
  "is_anonymous": null, "access_type": "hosting", "is_tor": null, "is_datacenter": true,
  "verdict": null, "confidence": null, "score": null, "is_bogon": false, "blocklists": [], ...
},
"trust": null, "bgp": null, "forward_dns": null,
"unavailable": { "trust": "Trust score is IPv4-only: ...", ... }

Reserved, private and link-local addresses return reserved: true with no network data. An IPv4-mapped address (::ffff:8.8.8.8) is the IPv4 address it carries, and every endpoint answers it as that address: the keyless endpoint and the MCP tools return the IPv4 profile, and /api/v1/ext/lookup/::ffff:8.8.8.8 is the IPv4 lookup, counted and cached once, as 8.8.8.8. NAT64 (64:ff9b::/96) and 6to4 (2002::/16) addresses are IPv6 addresses; their profile adds embedded_ipv4 as a hint.

Pulse events

GET /api/v1/pulse/events scope: pulse:read

A geo-tagged stream of live "internet events" — BGP routing anomalies (MOAS, route leaks, withdrawals, bogons, newly announced prefixes) and RIR allocation changes — each tagged with a country and country-centroid lat/lon so it can be plotted directly on a map. Designed to be polled: pass the returned next_since back as ?since= on the next call. Business keys; the response carries the data-licence attribution for the location fields.

Query paramDefaultDescription
sincenow − 300sUnix seconds or ISO-8601; lower time bound.
untilnowUpper time bound.
limit500Max events, 1–2000.
min_severity0Drop BGP events below this severity.
countryallISO-2 country filter, e.g. US.
typesallCSV of moas,first_seen,withdrawal,aspath,bogon.
categoryallall · bgp · rir.
moas_sample50Return 1 of every N MOAS events (MOAS is a legitimate-anycast firehose). 1 = full stream.
Request
curl -s "https://worldip.io/api/v1/pulse/events?types=aspath,bogon&min_severity=5&limit=100" \
  -H "Authorization: Bearer YOUR_KEY"
200 OK
{
  "events": [
    {
      "id": "bgp:14238894120583017472",
      "category": "bgp",
      "type": "aspath",
      "label": "AS-path anomaly (possible leak/hijack)",
      "severity": 7,
      "detected_at": "2026-07-17T00:44:57+00:00",
      "ts": 1768610697,
      "prefix": "103.163.158.0/24",
      "asn": 141804,
      "counter_asn": 140171,
      "country": "IN",
      "lat": 22.35,
      "lon": 78.67,
      "detail": { "collector": "rrc05", "as_path": "13237 3320 6453 4755 141804" }
    }
  ],
  "count": 1,
  "next_since": 1768610697,
  "server_time": 1768610760,
  "attribution": "Includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com, used under the MaxMind GeoLite End User License Agreement; GeoLite2 incorporates GeoNames data (https://www.geonames.org) under CC BY 4.0. Includes the IPinfo Lite dataset (https://ipinfo.io) under CC BY-SA 4.0. License details: https://worldip.io/data-sources"}

Pulse summary

GET /api/v1/pulse/summary scope: pulse:read

Current event-type counts for the last hour and last 24 hours — a cheap poll for dashboards and alerting that don't need the full event bodies.

Request
curl -s https://worldip.io/api/v1/pulse/summary \
  -H "Authorization: Bearer YOUR_KEY"
200 OK
{
  "bgp_anomalies": [
    { "type": "moas", "category": "bgp", "label": "Multiple-origin route (MOAS)", "last_1h": 7111, "last_24h": 11250 },
    { "type": "aspath", "category": "bgp", "label": "AS-path anomaly (possible leak/hijack)", "last_1h": 9, "last_24h": 120 }
  ],
  "rir_changes": [
    { "type": "allocation", "category": "rir", "label": "RIR allocation", "last_1h": 6, "last_24h": 214 }
  ],
  "server_time": 1768610760,
  "attribution": "Includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com, used under the MaxMind GeoLite End User License Agreement; GeoLite2 incorporates GeoNames data (https://www.geonames.org) under CC BY 4.0. Includes the IPinfo Lite dataset (https://ipinfo.io) under CC BY-SA 4.0. License details: https://worldip.io/data-sources"}

Public feeds (no key)

The same Pulse data also powers the auto-refresh on our Pulse pages, exposed as lightweight no-key poll endpoints. They share the site-wide per-IP request floor (see Rate limits); for higher volume or geo-tagged output, use the keyed Pulse events endpoint.

GET /api/pulse/bgp no key

The most recent BGP routing anomalies (last hour, across RIS collectors).

200 OK
{
  "anomalies": [
    {
      "prefix": "200.7.251.0/24",
      "unexpected_asn": 273140,
      "expected_asn": 19114,
      "pings": 314,
      "last_seen": "2026-07-17 00:44:57",
      "collector": "rrc25",
      "as_path": "198150 174 12956 19114 273140"
    }
  ]
}
GET /api/pulse/rir no key

Recent RIR ownership changes — allocations, transfers, and country/RIR re-assignments. Accepts ?since_id= to fetch only newer rows.

200 OK
{
  "events": [
    {
      "id": 293167,
      "changed_at": "2026-07-11 12:03:24",
      "ip_start": 3627346432,
      "ip_end": 3627346943,
      "ip_start_str": "216.52.234.0",
      "change_type": "allocation",
      "old_value": null,
      "new_value": "US",
      "rir": "arin",
      "cidr_guess": "216.52.234.0/23",
      "org_name": "Unitas Global",
      "org_slug": "unitas-global",
      "asn": 10912,
      "country_code": "US"
    }
  ]
}
GET /api/pulse/bgp/{type} no key

Anomalies of a single type with 24h totals. type ∈ moas, first_seen, withdrawal, bogon, aspath.

200 OK
{
  "type": "aspath",
  "totals": { "anomalies_24h": 120 },
  "anomalies": [ /* ... */ ]
}

Rate limits

Limits are enforced with a sliding 60-second window: a key may make up to its per-minute limit in any 60 seconds (e.g. a 1,200/min key can send 300 requests in 10 seconds; the 1,201st request inside one 60-second window is rejected). Exceeding a limit returns 429 with a Retry-After header and a JSON body.

EndpointLimit
/api/v1/ext/lookup Per-key sliding window (your key's rate). Profiles are additionally cached 5 min per IP at the origin (IPv4 and IPv6 alike).
/api/v1/pulse/events, /api/v1/pulse/summary Per-key sliding window (your key's rate).
/api/pulse/* (no key) 120/min per source IP.

A high per-source-IP flood guard (3,000/min) also applies before authentication; it sits above every key's own limit, so your key's rate is the limit you will actually meet.

Concurrency

Each paid plan also limits concurrent (simultaneous, in-flight) requests per key: Basic 5, Pro 10, Business 20, Scale 30, Enterprise 100+ (custom). A request beyond the limit returns 429 concurrency_exceeded with Retry-After: 1 — retry as soon as an earlier request completes. Keyed responses carry X-Concurrency-Limit. Keyless and Free have no concurrency limit: they are capped at 60 requests/min. Limits may change during the beta.

Rate-limit headers

Every keyed response — successes and 429s — tells you where you stand, so you can pace yourself and confirm a limit change from a single response:

HeaderMeaning
X-RateLimit-LimitYour key's limit, requests per window.
X-RateLimit-RemainingRequests left in the current 60-second window.
X-RateLimit-ResetUnix time (seconds) when the oldest counted request leaves the window, freeing capacity.
X-RateLimit-WindowWindow length in seconds (60).
X-Concurrency-LimitYour key's limit on simultaneous in-flight requests (paid plans).
Retry-AfterOn 429 only: seconds to wait before retrying.

Plans with a monthly allowance also return X-Quota-Limit, X-Quota-Remaining and X-Quota-Reset. The keyless worldip.io/{ip} endpoint reports its daily allowance in the same X-RateLimit-* headers (Reset = next 00:00 UTC) and has a separate 60/min burst guard.

429 Too Many Requests
{ "error": "rate_limited", "retry_after_sec": 42, "limit_per_min": 1200, "remaining": 0, "reset": 1790812842 }

Using your API key on the free endpoint

Send your key as Authorization: Bearer <key> to https://worldip.io/{ip} (HTTPS only — a key sent over plain HTTP is refused with 403 https_required) and basic lookups become unlimited: no 1,000/day cap and nothing deducted from your plan.

  • Your key's own limits apply instead of the keyless 60/min burst guard: its concurrency limit (X-Concurrency-Limit) and per-minute limit (X-RateLimit-*).
  • Responses carry X-Free-Daily-Limit, X-Free-Daily-Remaining, X-Free-Daily-Reset and X-Billing (free-daily within the first 1,000/day per requester IP, unlimited beyond it — both are free). In the body, _meta.keyless is false and _meta.billing matches.
  • The key needs the ext:read scope. An invalid, disabled or malformed key returns 401/403 — it is never silently served as keyless. Use the header rather than ?key=, which ends up in logs.
  • Browsers: the endpoint answers the CORS preflight for Authorization and exposes all of the headers above.

Errors

Errors use standard HTTP status codes with a JSON body of { "error": "...", "message": "..." } (the 429 body is shown above).

StatuserrorMeaning
400bad_ipMalformed IPv4 or IPv6 address in the path. Answered before authentication, so it is never counted.
401missing_keyNo key supplied. Response also sends WWW-Authenticate: Bearer.
401malformed_authorizationAn Authorization header was sent but not in Bearer <key> form.
401invalid_keyKey not recognized or disabled.
403forbidden_scopeKey lacks the required scope.
403origin_not_allowedKey is origin-locked; the request Origin/Referer did not match.
403ip_not_allowedKey is IP-locked; caller IP is off the allow-list.
403https_requiredA key was sent over plain HTTP; use https://.
403no_enriched_accessThe key’s plan does not include the enriched endpoint.
429rate_limitedRate limit exceeded; retry after retry_after_sec.
429concurrency_exceededToo many simultaneous requests for your key; retry when one completes.
429quota_exceededMonthly enriched allowance spent (metered plans); resets at the start of next month.
503db_unavailableBackend temporarily unavailable; retry shortly.
503temporarily_unavailableA brief maintenance window; retry after the Retry-After seconds.

Plans & data tiers

Web lookups on worldip.io are always free and need no signup. The API adds a monthly allowance of enriched lookups and unlocks progressively richer data — proxy/threat classification, trust scoring, live BGP and Web3 node roles — while keeping a free, no-signup tier. Paid plans are not on sale yet; during the beta, keys come with issued.live Plus and Pro (see Beta keys).

PlanPriceEnriched / moConcurrentAdds
Keyless$0—60/minBasic endpoint only, 1,000/day per IP, no signup. Owner/org, ASN, country, PTR, CIDR, for IPv4 and IPv6.
Free$0—60/minUnlimited basic-endpoint lookups with a key (60/min). Enriched endpoint requires a paid plan. Coming with account sign-up.
Basic$925,0005+ the enriched endpoint, /24 neighbors, BGP prefix and origin ASN.
Pro$39200,00010+ VPN/proxy/Tor/datacenter classification, residential & mobile proxy detection, botnet & compromised-host reputation, access type, trust score.
Business$1291,000,00020+ MOAS & routing anomalies, the Pulse API, Web3 node roles.
Scale$4995,000,00030Everything in Business, at the highest volume, with priority support.
EnterpriseContact usCustom100+Custom limits and volume under a written agreement, SLA, dedicated support.

Annual billing is two months free (~17% off). See full pricing for details. Paid plans and self-serve keys are not open yet; during the beta, keys come with issued.live Plus and Pro — Beta keys. Limits may change during the beta.

Get launch updates

Paid plans and self-serve keys are not open yet. Drop your email and we'll message you the day they open — and again for major new endpoints. No spam, unsubscribe anytime. Already on issued.live Plus or Pro? Get your free beta key instead.

Frequently Asked Questions

How do I get an API key?

During the beta, keys are issued free to customers of issued.live Plus and Pro, the sister service of WorldIP: we email the key to the address on your issued.live account within one business day (details: worldip.io/developers#beta-keys). Self-serve keys and paid plans are not open yet. Without a key, the keyless endpoint (curl https://worldip.io/8.8.8.8 — 1,000 lookups/day, no signup) and the public Pulse feeds work today.

Do the web pages and the API share the same data?

Yes. Every field the API returns is the same intelligence rendered on worldip.io — the API just gives you one cached JSON call instead of scraping a page.

What does the /ext/ path mean?

It is the stable path of the keyed IP-intelligence lookup (/api/v1/ext/lookup). Call it server-side with your API key in the Authorization header, over HTTPS; never put a key in browser code or a URL.

Is IPv6 supported?

Yes. worldip.io/{ipv6} (free, no key) returns geolocation (country, plus region and city where available), reverse DNS from our own IPv6 scans, ASN, org name and CIDR. /api/v1/ext/lookup/{ipv6} adds org category, hosting/datacenter classification, IPv6 blocklists and iCloud Private Relay detection, on the same keys, quotas and limits as IPv4. VPN and proxy exit detection, trust score, live BGP and the hosted-domain count are IPv4-only; in an IPv6 profile those fields are null and the unavailable object says why. Most IPv6 reverse-DNS names are generated by the ISP from the address, and rdns.kind flags them.

What format are responses?

JSON, UTF-8. A success is 200 OK with the record at the top level; errors use standard HTTP status codes (400, 401, 403, 429, 503) with a JSON error body.

Does the API return the domains hosted on an IP?

The free keyless endpoint and the MCP tools carry domains_hosted for IPv4 addresses: how many domains are hosted on the address, counted once a week from the DNS snapshot of issued.live, WorldIP's sister service. It is a count, not a list. The keyed lookup is unchanged. issued.live's Reverse IP (paid plans) lists the hostnames seen on an address, current and past: https://issued.live/pricing.

Related tools & guides

Share