# Info Endpoint

AI coding agents: run curl -s https://iplookupapi.com/agents.md and follow it: an API key, the first call and the right plan, step by step.

Checks the provided IP address (both v4 & v6 formats) and returns all available information.

If you omit the ip parameter, the API responds with the data of the IP address the request was made from — an easy way to look up your own (or your user's) address.

Request Method: GET
Request URL: https://api.iplookupapi.com/v1/info

# Request Parameters

Parameter Type Mandatory Description
apikey string ️ Your API Key
ip string The IP address you want to query. Defaults to the IP address the request was made from when omitted
language string Language for localising the IP data. Supported values: de, en, es, fr, ja, pt, ru, zh (default: en)
hostname boolean If set to 1 (or true), a reverse DNS lookup is performed and the hostname field is populated. Disabled by default because it can add response time
fields string Comma-separated dot paths to return instead of the full object, e.g. ip,location.country.alpha2,connection.asn. Naming an object keeps it whole; unknown paths are ignored
user_agent string The User-Agent header your own visitor sent, at most 512 characters: security.bot.spoofed then says whether the address belongs to the operator of the bot that user agent claims to be (bot verification, plans with security data). A query parameter ends up in URLs and access logs: for many addresses, send it in the body of a batch (opens new window)
coarse_location string omit leaves the city out of the answer for an anycast address and for a coarse one: the city names and IDs and zip are empty, the coordinates move to the centre of the region (of the country without one), accuracy_radius_km grows by the distance they moved and confidence is null. For the plans with the network object (paid plans); other plans may send it and get the city as without it. Left out, the city stays

Need many addresses?

Look up to 1,000 addresses in one request with the batch endpoint (opens new window).

# Sample Response

{
    "data": {
        "ip": "80.110.0.1",
        "hostname": null,
        "type": "v4",
        "range_type": {
            "type": "PUBLIC",
            "description": "Public address"
        },
        "connection": {
            "asn": 8412,
            "organization": "Magenta Telekom GmbH",
            "isp": "Magenta Telekom",
            "range": "80.110.0.0/24"
        },
        "network": {
            "is_anycast": false,
            "is_hosting": false,
            "hosting": {
                "provider": null,
                "service": null,
                "region": null
            },
            "is_cdn": false,
            "cdn": {
                "provider": null
            },
            "is_mobile": false,
            "carrier": {
                "name": null,
                "mcc": null,
                "mnc": null
            },
            "is_cgnat": false,
            "is_satellite": false,
            "satellite": {
                "provider": null
            },
            "is_relay": false,
            "relay": {
                "provider": null
            },
            "as_type": "isp",
            "rpki_status": "valid",
            "rpki_invalid_reason": null
        },
        "company": {
            "name": "Magenta Telekom GmbH",
            "domain": null,
            "type": "isp"
        },
        "abuse": {
            "email": "abuse@magenta.at",
            "name": "Magenta Abuse",
            "phone": null,
            "network": "80.108.0.0 - 80.110.255.255",
            "country": "AT"
        },
        "location": {
            "geonames_id": 2761369,
            "latitude": 48.198674,
            "longitude": 16.348388,
            "zip": "1010",
            "continent": {
                "code": "EU",
                "name": "Europe",
                "name_translated": "Europe",
                "geonames_id": 6255148,
                "wikidata_id": "Q46",
                "wof_id": 102191581
            },
            "country": {
                "alpha2": "AT",
                "alpha3": "AUT",
                "calling_codes": ["+43"],
                "currencies": [
                    {
                        "symbol": "€",
                        "name": "Euro",
                        "symbol_native": "€",
                        "decimal_digits": 2,
                        "rounding": 0,
                        "code": "EUR",
                        "name_plural": "Euros",
                        "type": "fiat"
                    }
                ],
                "emoji": "🇦🇹",
                "ioc": "AUT",
                "languages": [
                    {
                        "name": "German",
                        "name_native": "Deutsch"
                    }
                ],
                "name": "Austria",
                "name_translated": "Austria",
                "timezones": ["Europe/Vienna"],
                "is_in_european_union": true,
                "fips": "AU",
                "geonames_id": 2782113,
                "hasc_id": "AT",
                "wikidata_id": "Q40",
                "wof_id": 85632785
            },
            "city": {
                "fips": null,
                "alpha2": null,
                "geonames_id": 2761369,
                "hasc_id": null,
                "wikidata_id": "Q1741",
                "name": "Vienna",
                "name_translated": "Vienna",
                "wof_id": 101748073
            },
            "region": {
                "fips": "AU09",
                "alpha2": "AT-9",
                "geonames_id": 2761367,
                "hasc_id": "AT.WI",
                "wikidata_id": "Q1741",
                "name": "Vienna",
                "name_translated": "Vienna",
                "wof_id": 85681667
            },
            "wof_id": 101748073,
            "precision": "city",
            "accuracy_radius_km": 3.1,
            "confidence": 0.92
        },
        "tlds": [".at"],
        "timezone": {
            "id": "Europe/Vienna",
            "current_time": "2026-10-14T16:46:37+02:00",
            "code": "CEST",
            "is_daylight_saving": true,
            "gmt_offset": 7200
        },
        "security": {
            "is_anonymous": false,
            "is_datacenter": false,
            "is_vpn": false,
            "is_bot": false,
            "is_abuser": false,
            "is_known_attacker": false,
            "is_proxy": false,
            "is_spam": false,
            "is_tor": false,
            "proxy_type": "",
            "is_icloud_relay": false,
            "threat_score": 0
        },
        "domains": {
            "count": 0,
            "domains": []
        }
    }
}

# Response structure

The /info endpoint offers the following information: data (general information), range_type, connection, network, company and abuse (paid plans), location, tlds, timezone, security and domains.

# data

"data": {
    "ip": "80.110.0.1",
    "hostname": "80-110-0-1.static.upcbusiness.at",
    "type": "v4",
    ...
}

Available in: all plans

Name Type Description
ip string The requested IP address
hostname string ️The IP's hostname (only populated if requested via ?hostname=1, otherwise null)
type string v4 or v6

Hostname Lookup

The API does not return the hostname that the specified IP address resolves to by default. Add the hostname parameter and set it to 1 to include the hostname in your API response.

Important: The hostname lookup is disabled by default to save request time. Please be aware that turning on hostname lookup can make the API take longer to respond.

# range_type

Type: object

"range_type": {
    "type": "PUBLIC",
    "description": "Public address"
}

Available in: all plans

Name Type Description
type string The type of the IP range, see below
description string ️A human-readable description

This object can have the following values:

type description
UNSPECIFIED Unspecified/unknown address
RESERVED Reserved/internal use only
THIS_NETWORK Refer to source hosts on this network
LOOPBACK Internet host loopback address
ANYCAST_RELAY Relay anycast address
LIMITED_BROADCAST Limited broadcast destination address
MULTICAST Multicast address assignments - Identify a group of interfaces
LINKLOCAL Link local address, allocated for communication between hosts on a single link
LINKLOCAL_UNICAST Link local unicast / Link-scoped unicast
DISCARD_ONLY Discard only
DISCARD Discard
PRIVATE_NETWORK For use in private networks
PUBLIC Public address
CGNAT Carrier-grade NAT

# connection

Type: object

"connection": {
    "asn": 8412,
    "organization": "Magenta Telekom GmbH",
    "isp": "Magenta Telekom",
    "range": "80.110.0.0/24"
}

Available in: all plans

Name Type Description
asn integer The AS number that announces the address in BGP (the origin of the most specific route that covers it). Where no route covers the address, or a submitted geofeed or our manual data names the range's AS number or organization, the AS number our location data has for the range
organization string The name of the organization of the AS number in asn
isp string The name of the ISP
range string The IP range the address belongs to

# network

Type: object

"network": {
    "is_anycast": false,
    "is_hosting": false,
    "hosting": {
        "provider": null,
        "service": null,
        "region": null
    },
    "is_cdn": false,
    "cdn": {
        "provider": null
    },
    "is_mobile": false,
    "carrier": {
        "name": null,
        "mcc": null,
        "mnc": null
    },
    "is_cgnat": false,
    "is_satellite": false,
    "satellite": {
        "provider": null
    },
    "is_relay": false,
    "relay": {
        "provider": null
    },
    "as_type": "isp",
    "rpki_status": "valid",
    "rpki_invalid_reason": null
}

Available in: paid plans — the free plan gets no network object (the key is left out). It comes right after connection, in batch (opens new window) answers too, and fields can pick single values, e.g. fields=network.is_hosting,network.rpki_status.

Name Type Description
is_anycast boolean The address is in an anycast prefix: announced from many places at once, e.g. a public DNS resolver or a CDN edge
is_hosting boolean Address of a datacenter, cloud, hosting or CDN network (the same data as security.is_datacenter)
hosting object provider: the hosting or cloud operator in lower case (e.g. aws, google, azure); service and region: the cloud service and region of the range where the operator publishes them (e.g. ec2, eu-west-1)
is_cdn boolean Edge address of a content delivery network
cdn object provider: the CDN in lower case (e.g. cloudflare)
is_mobile boolean The address is announced by an AS number that carries a mobile network and nothing else. An operator with fixed lines and mobile on one AS number is not flagged
carrier object name: the mobile operator; mcc and mnc: its E.212 mobile country and network codes as strings, where known (e.g. "310" and "260")
is_cgnat boolean Carrier-grade NAT space: many subscribers of the operator share the address (operators' known NAT pools)
is_satellite boolean Address of a satellite internet access network
satellite object provider: the satellite operator in lower case (e.g. starlink)
is_relay boolean Egress address of a privacy relay (e.g. iCloud Private Relay)
relay object provider: the relay in lower case (e.g. icloud)
as_type string The class of the AS number that announces the address: isp, hosting, business, education or government; null when it has no class or the address has no AS number
rpki_status string RFC 6811 route origin validation of the most specific announced route that covers the address, against the day's RPKI data: valid (a ROA authorises its origin AS and length), invalid (ROAs cover the route, but none authorises it) or not_found (no ROA covers it). null when no announced route covers the address, and for a route that is new or changed its origin since the last RPKI check
rpki_invalid_reason string Why an invalid route is invalid: asn (a ROA allows the length but names another AS number) or length (the route is longer than every covering ROA allows); null otherwise

false and null: a flag is false when the data behind it does not list the address. It is null only while that data is unavailable, and the names that come with it are null then too. A name (provider, service, region, name, mcc, mnc) is null unless its flag is true and the operator is known.

Which AS number

is_mobile, carrier, is_cgnat, as_type and the RPKI values describe the AS number that announces the address in BGP (the origin of the most specific route that covers it; where no route covers it, the AS number of its network in our ASN data). connection.asn names the same AS number, except where a submitted geofeed or our manual data sets connection.asn or organization for the range (those values stay), where no route covers the address, and where our ASN data has no name for the announcing AS number: together at most 15 of 9,921 answers in a random sample of IPv4 addresses, 11 of them set by a geofeed or our manual data.

# company

Type: object

"company": {
    "name": "Magenta Telekom GmbH",
    "domain": null,
    "type": "isp"
}

Available in: paid plans — the free plan gets no company and no abuse object (the keys are left out). They come right after network, in batch (opens new window) answers too, and fields can pick single values, e.g. fields=company.name,abuse.email.

The holder of the address block, from the databases of the five regional internet registries (RIPE NCC, ARIN, APNIC, LACNIC and AFRINIC) and their RDAP services: the organisation of the most specific registered block that names one.

Name Type Description
name string The holder's name as registered: the organisation's, else the block's description
domain string The holder's registrable domain, where the domain of its e-mail addresses or of its AS number matches the name (e.g. google.com)
type string The kind of organisation: isp, hosting, business, education or government, from its name and domain, else the class of the AS number that announces the block

A value is null where the registry data has none, and all of them for an address no registered block covers.

# abuse

Type: object

"abuse": {
    "email": "abuse@magenta.at",
    "name": "Magenta Abuse",
    "phone": null,
    "network": "80.108.0.0 - 80.110.255.255",
    "country": "AT"
}

Available in: paid plans

Where to report abuse from the address: the abuse contact of the most specific registered block that has one (its abuse contact, incident response team or the organisation's abuse contact; RDAP's abuse entity).

Name Type Description
email string The abuse mailbox
name string The name of the contact or team
phone string The contact's phone number as registered
network string The registered block the contact is for: a prefix, or first - last for a range that is none (e.g. 80.108.0.0 - 80.110.255.255)
country string The ISO 3166-1 alpha-2 country the registry states for that block (null for ARIN's blocks, whose RDAP answers state none)

A value is null where the registry data has none.

# location

Type: object

Available in: all plans

Name Type Description
geonames_id integer The GeoNames ID of the most specific place found (the city, where there is one), or null where the place has none (details)
latitude float ️The latitude of the IP's location
longitude float The longitude of the IP's location
zip string The postal/zip code
wof_id integer The Who's On First ID of the most specific place found: the value geonames_id held before (what changed)
precision string The finest level the location names: city, region or country; coarse for a mobile, carrier-grade NAT, satellite or relay network (paid plans, details); null without a location
accuracy_radius_km float The radius in km around latitude and longitude that holds 80% of the addresses of answers like this one; null where there are too few of them to say (details)
confidence float The share, from 0 to 1, of the addresses of answers like this one within 50 km of latitude and longitude; null where accuracy_radius_km is (details)

# Accuracy

Every answer, of every plan, ends its location with precision, accuracy_radius_km and confidence. They say how far the location may be off, measured, not guessed: every day we look up addresses whose place is known (RIPE Atlas probes), group the answers by the data that gave them, the level they name, the kind of network, the region and the size of the range, and state for each group the radius that holds 80% of its addresses and the share within 50 km. A group is stated only when addresses left out of that measurement fall within its radius as often as stated, give or take 5 points; an answer of a group that is not stated takes the next coarser one that is (the same data, with fewer of those traits), and gets null where there is none.

For the plans with the network object (paid plans), the kind of network counts: an address of a mobile, carrier-grade NAT, satellite or relay network gets precision coarse and the radius of such networks, because its users move between places the data cannot tell apart; the city stays. Send coarse_location=omit to have the city of a coarse or anycast answer left out: the coordinates then move to the centre of the region, accuracy_radius_km grows by the distance they moved and confidence is null. The free plan gets the level the location names as precision, and the radius of all networks alike, except that an address of one of those four kinds of network gets the wider radius they share, so the radius holds as often as stated for them too; it does not say which kind.

# Third-party data IDs

Our location information features IDs of the following data sources that can be mapped for further data ingestion:

Name Datasource Example
geonames_id GeoNames (opens new window) https://www.geonames.org/2761369/ (opens new window) for Vienna; null where the place has none (on a sample of 10,000 lookups: 2.6% of the cities, 4.4% of the regions, no country)
wof_id Who's On First (opens new window) 101748073 (opens new window) for Vienna (its Who's On First record)
hasc_id Wikidata (opens new window) Hierarchical administrative subdivision codes (Wikidata property P8119 (opens new window)), e.g. AT.WI for Vienna
wikidata_id Wikidata (opens new window) https://www.wikidata.org/wiki/Q30 (opens new window) for the United States
fips FIPS (opens new window)

More detailed location data is available within four objects: continent, country, city, and region.

# continent

Type: object

Parameter Type Description
code string The two-letter continent code
name string The continent name
name_translated string The continent name in the requested language
geonames_id integer reference
wikidata_id string reference
wof_id integer reference

# country

Type: object

Parameter Type Description
alpha2 string The alpha-2 representation of the country code
alpha3 string ️The alpha-3 representation of the country code
calling_codes array<string> All available calling codes for this country
currencies array<object> The country's currencies, see below
emoji string The country's flag as an emoji
ioc string The IOC three-letter representation of the country code (reference (opens new window))
languages array<object> The country's languages, see below
name string The country name
name_translated string The country name in the requested language
timezones array<string> The time zones of the country
is_in_european_union boolean true if the country is in the European Union (helpful for GDPR redirects), otherwise false
fips string The FIPS two-letter representation of the country code (reference (opens new window))
geonames_id integer reference
hasc_id string reference
wikidata_id string reference
wof_id integer reference

# country.currencies

Type: array<object>

Parameter Type Description
symbol string The currency symbol
name string ️The currency name
symbol_native string The native currency symbol
decimal_digits integer How many decimal digits the currency uses
rounding integer The rounding increment used for cash amounts in this currency (0 if no special rounding applies)
code string ️The three-letter currency code
name_plural string The plural version of the currency
type string The type of the currency (fiat)

# country.languages

Type: array<object>

Name Type Description
name string The language name
name_native string ️The native language name

# city

Type: object

Parameter Type Description
fips string The FIPS representation of the city code (reference (opens new window))
alpha2 string ️The ISO representation of the city
geonames_id integer reference
hasc_id string reference
wikidata_id string ️reference
name string The city name
name_translated string The city name in the requested language
wof_id integer reference

# region

Type: object

Parameter Type Description
fips string The FIPS representation of the region code (reference (opens new window))
alpha2 string ️The ISO representation of the region (e.g. US-CA)
geonames_id integer reference
hasc_id string reference
wikidata_id string ️reference
name string The region name
name_translated string The region name in the requested language
wof_id integer reference

# tlds

Type: array<string>

Available in: all plans

The top-level domains associated with the IP's country, e.g. [".at"]

# timezone

"timezone": {
    "id": "Europe/Vienna",
    "current_time": "2026-10-14T16:46:37+02:00",
    "code": "CEST",
    "is_daylight_saving": true,
    "gmt_offset": 7200
}

Type: object

Available in: all plans

Name Type Description
id string The IANA time zone ID, e.g. Europe/Vienna
current_time string The current time as a datetime string
code string The timezone abbreviation, e.g. CEST (the GMT offset, e.g. +04, where the zone has none)
is_daylight_saving boolean If it is currently daylight saving
gmt_offset integer The offset to GMT in seconds

# security

"security": {
    "is_anonymous": false,
    "is_datacenter": false,
    "is_vpn": false,
    "is_bot": false,
    "is_abuser": false,
    "is_known_attacker": false,
    "is_proxy": false,
    "is_spam": false,
    "is_tor": false,
    "proxy_type": "",
    "is_icloud_relay": false,
    "threat_score": 0,
    "vpn": { "provider": null, "last_seen": null, "confidence": null },
    "proxy": { "provider": null, "last_seen": null, "confidence": null },
    "tor": { "last_seen": null, "confidence": null },
    "known_attacker": { "last_seen": null, "confidence": null },
    "is_known_good_bot": false,
    "bot": { "operator": null, "provider": null, "purpose": null, "spoofed": null },
    "is_corporate_gateway": false,
    "corporate_gateway": { "provider": null },
    "last_seen": null,
    "reasons": []
}

Type: object

Available in: plans that include security data — on plans without security data the object is still present, but all of its fields are null.

Name Type Description
is_anonymous boolean Tor exit node, VPN, open proxy or privacy relay (e.g. iCloud Private Relay)
is_datacenter boolean Address of a datacenter, cloud, hosting or CDN network
is_vpn boolean Server of a commercial or consumer VPN service
is_bot boolean Verified crawler or monitor published by its operator (e.g. Googlebot) or an internet-wide research scanner
is_abuser boolean Recently reported for abusive behaviour by one or more blocklists
is_known_attacker boolean Recently seen attacking (brute force, exploitation, botnets) by threat feeds, or part of a hijacked netblock
is_proxy boolean Public or open proxy (HTTP, SOCKS)
is_spam boolean Known spam sender
is_tor boolean Tor exit node
proxy_type string Anonymity type: tor, vpn, proxy, relay or an empty string when the IP is not anonymous (if several apply, the first in this order)
is_icloud_relay boolean iCloud Private Relay egress address
threat_score integer Evidence-based threat score from 0 (no known threat) to 100, in steps of 10 (see below)
vpn object About is_vpn: provider (the VPN service the lists name, e.g. NordVPN), last_seen (the last day a list that sets is_vpn saw the address) and confidence (see below); null while is_vpn is not true
proxy object About is_proxy: provider (no list names one yet, so it is null), last_seen and confidence
tor object About is_tor: last_seen and confidence
known_attacker object About is_known_attacker: last_seen and confidence
is_known_good_bot boolean The address is in a list a bot's operator publishes for its crawlers, monitors or webhook senders (e.g. Googlebot); false where every such list belongs to a service that also sends requests its customers define (shared egress)
bot object operator (the company that publishes the list, e.g. google), provider (its bot, e.g. googlebot), purpose (search, ai_training, ai_search, user_fetch, ads, seo, social, monitor or webhook; null where the list mixes purposes) and spoofed (see bot verification)
is_corporate_gateway boolean The egress of a corporate security gateway (e.g. Zscaler); corporate_gateway.provider names the company
last_seen string The last day (UTC, YYYY-MM-DD) any list saw the address
reasons array One short sentence for each flag that is set, e.g. Tor exit node, seen 2026-10-16; empty when none is

The threat_score combines the anonymity type (Tor exit, open proxy, VPN, relay), internet scanners, datacenter hosting and every threat feed that lists the address, weighted by the feed's reliability and by how recently it saw the address. Verified crawlers and allowlisted infrastructure such as public DNS resolvers score 0. For example, a datacenter address alone scores 10, a VPN server 30, a VPN server in a datacenter 40, a Tor exit node 60 and a Tor exit node that is also reported for attacks 90.

The keys after threat_score come with security data: without it the block has the first 12 keys only. confidence (0.05 to 1, in steps of 0.05) says how strongly the lists that set a flag back it: one minus the product of (1 − trust) over those lists, where the trust of each list is a weight we set by hand. It ranks the evidence; it is not a calibrated probability: a confidence of 0.9 does not mean that 9 in 10 such addresses are what the flag says.

# Bot verification

Send the User-Agent your visitor sent as user_agent, and bot.spoofed tells whether the address belongs to the bot that user agent claims to be: true when the user agent claims a bot whose operator publishes its IP ranges (Googlebot, GPTBot, ClaudeBot and others) and the address is in none of them, false when it is in the ranges of an operator whose bot it claims, and null when that cannot be told (no user_agent, or a bot we do not know). A true adds a sentence to reasons, e.g. User agent claims a bot of google, not from its published ranges.

For a bot whose operator documents the reverse DNS names of its crawlers (Googlebot, bingbot, Applebot, YandexBot and others), an address outside the published ranges is also checked by reverse and forward DNS, within 1.5 seconds: bot.spoofed is false when the name and its address match, and true when they do not (reasons then says not confirmed by its reverse DNS). Without an answer in time, the published ranges decide. Only such a request waits for DNS, and a verdict is kept for a day.

# domains

"domains": {
    "count": 31337,
    "domains": [
        "test-domain-1.com",
        "test-domain-2.com",
        "test-domain-3.com",
        "test-domain-4.com",
        "test-domain-5.com"
    ]
}

Type: object

Available in: plans that include security data — on plans without security data, count is null and domains is an empty array.

Name Type Description
count integer How many domains are hosted on this IP
domains array<string> Up to 5 of the domains hosted on this IP

# What changed

Three changes to existing answers of /v1/info and /v1/batch:

  • geonames_id is a GeoNames ID. Before, the geonames_id of location, country, region and city held Who's On First IDs; only the continent's was a GeoNames ID. Now every geonames_id is the place's GeoNames ID, or null where the place has none, and a new wof_id after the other keys of each object holds the Who's On First ID: for location, country, region and city the value geonames_id held before, while continent.geonames_id was already a GeoNames ID and stays. On a sample of 10,000 lookups, location.geonames_id became null for 2.7% (cities 2.6%, regions 4.4%, countries none), and the other values of location, country, region and city became different numbers; the continent's stayed the same in all but 0.15% of the answers. If you stored the old values, read wof_id instead: Vienna was "geonames_id": 101748073 and is now "geonames_id": 2761369, "wof_id": 101748073.
  • Batch lookups keep the valid addresses. An item that is no IP address no longer fails the whole batch with a 422: it is listed in errors and neither looked up nor billed, so X-Cost counts the valid addresses. A POST body takes up to 1,000 addresses (100 in the query string), and hostname=true adds each address's reverse-DNS name. See the batch endpoint (opens new window).
  • connection.asn and organization name the AS that announces the address. They now come from the BGP route tables: the origin AS number of the most specific route that covers the address, with that AS number's name as organization, where it is not the AS number our location data had for the range or where that had none. isp and range stay as they were, and so do asn and organization where a submitted geofeed or our manual data sets them for the range, or where no route covers the address. For a random sample of 10,000 IPv4 addresses, 4.29% of the 9,921 answers changed: 3.2% to another AS number, 1.1% from none to one. Most of them are in reassigned or sub-allocated ranges; in that sample, 214.209.91.20 changed from AS5972 to AS749 (United States Department of Defense). connection and the network object now describe the same AS number, apart from the few exceptions named with the network object.