The OpenAPI 3.1 spec on one page
Every endpoint, parameter, response and schema of the host.sh IP lookup API, rendered from its OpenAPI 3.1 spec into one static page.
This page is generated from the OpenAPI spec (OpenAPI 3.1.0, API version 2). Use the YAML file itself for code generators and API clients; the guides are in the docs.
host.sh IP lookup API
Geolocation, network and connection details for IPv4 and IPv6 addresses.
Without a token you can look up your own address (10 requests a minute per IP). Looking up any other address, and batch lookups, need a token. Send it as ?token=, as a token field in a JSON body, or as an Authorization: Bearer header.
Which sections a response has depends on the token's plan.
Servers
https://api.host.shhttps://ipv4.host.sh: IPv4 only, to learn a dual-stack client's IPv4 address
Authentication
Each endpoint takes one of these, or none where the endpoint allows it:
bearer: HTTPAuthorization: Bearer <token>headerquery: API key in the query parametertoken
Endpoints
GET /v2/lookup/
Look up an address (your own without a token).
Auth: none, bearer, query. Operation id: lookup.
| Parameter | In | Type | Description |
|---|---|---|---|
ip | query | string | IPv4 or IPv6 address to look up (needs a token). Without it you get your own address. Example: 8.8.8.8. |
ua | query | string | User-Agent string to parse (needs the user agent permission) |
al | query | string | Accept-Language header value to parse |
fields | query | string | Comma-separated dotted paths to keep, e.g. geo.country.code,connection.ip. Unknown paths are left out. |
lang | query | string, one of en, de, es, fr, ja, pt-BR, ru, zh-CN, default en | Language of continent, country, region and city names. Falls back to English where a name is missing. |
hostname | query | boolean, default false | Add connection.hostname, the reverse DNS (PTR) name. Adds up to a second. |
format | query | string, one of json, text, default json | text returns one field as plain text; it needs fields with exactly one single-value path. |
pretty | query | boolean, default false | Indent the JSON and sort its keys |
callback | query | string | JSONP callback name (letters, digits, _, $ and .) |
| Status | Meaning | Content |
|---|---|---|
| 200 | Lookup result | application/json (Lookup), text/plain |
| 400 | Error | application/json (Errors) |
| 401 | Error | application/json (Errors) |
| 403 | Error | application/json (Errors) |
| 429 | More than 10 tokenless requests a minute from one address | application/json (Errors), header Retry-After |
POST /v2/lookup/
Same as GET, with the parameters in a JSON or form body.
Auth: none, bearer, query. Operation id: lookupPost.
Request body:
application/json: object withtoken,ip,ua,al,fields,lang
| Status | Meaning | Content |
|---|---|---|
| 200 | Lookup result | application/json (Lookup), text/plain |
| 400 | Error | application/json (Errors) |
| 401 | Error | application/json (Errors) |
| 403 | Error | application/json (Errors) |
GET /v2/lookup/{address}
Look up one address given in the path (token required). The trailing slash is optional, /v2/lookup/8.8.8.8/ works too.
Auth: bearer, query (a token is required; the spec also lists none). Operation id: lookupAddress.
| Parameter | In | Type | Description |
|---|---|---|---|
address | path, required | string | Example: 8.8.8.8. |
fields | query | string | Comma-separated dotted paths to keep, e.g. geo.country.code,connection.ip. Unknown paths are left out. |
lang | query | string, one of en, de, es, fr, ja, pt-BR, ru, zh-CN, default en | Language of continent, country, region and city names. Falls back to English where a name is missing. |
hostname | query | boolean, default false | Add connection.hostname, the reverse DNS (PTR) name. Adds up to a second. |
format | query | string, one of json, text, default json | text returns one field as plain text; it needs fields with exactly one single-value path. |
pretty | query | boolean, default false | Indent the JSON and sort its keys |
callback | query | string | JSONP callback name (letters, digits, _, $ and .) |
| Status | Meaning | Content |
|---|---|---|
| 200 | Lookup result | application/json (Lookup), text/plain |
| 400 | Error | application/json (Errors) |
| 403 | Error | application/json (Errors) |
POST /v2/lookup/batch/
Look up up to 100 addresses at once (token required). The body is a JSON array of addresses, {"ips": [...]}, or plain text with addresses separated by commas, spaces or new lines. Results come back in the same order. An invalid address gets an errors item instead of failing the whole request. Every address counts as one lookup.
Auth: bearer, query (a token is required; the spec also lists none). Operation id: lookupBatch.
| Parameter | In | Type | Description |
|---|---|---|---|
fields | query | string | Comma-separated dotted paths to keep, e.g. geo.country.code,connection.ip. Unknown paths are left out. |
lang | query | string, one of en, de, es, fr, ja, pt-BR, ru, zh-CN, default en | Language of continent, country, region and city names. Falls back to English where a name is missing. |
pretty | query | boolean, default false | Indent the JSON and sort its keys |
Request body (required):
application/json: an array of string (at most 100), or an object withips(array of string (at most 100)). Example:["8.8.8.8","1.1.1.1"]text/plain: string. Example:"8.8.8.8\n1.1.1.1"
| Status | Meaning | Content |
|---|---|---|
| 200 | One result per address, in request order | application/json |
| 400 | Error | application/json (Errors) |
| 401 | Error | application/json (Errors) |
| 403 | Error | application/json (Errors) |
GET /v2/ip/
Your IP address and nothing else. Plain text by default. Use ipv4.host.sh to get your IPv4 address on a dual-stack connection.
Auth: none. Operation id: myIp.
| Parameter | In | Type | Description |
|---|---|---|---|
format | query | string, one of text, json |
| Status | Meaning | Content |
|---|---|---|
| 200 | The caller's address | text/plain, application/json |
Schemas
Name
| Field | Type | Description |
|---|---|---|
id | integer or null | |
code | string or null | |
name | string or null |
Lookup
| Field | Type | Description |
|---|---|---|
geo | object | |
geo.continent | object | |
geo.continent.id | integer or null | |
geo.continent.code | string or null | |
geo.continent.name | string or null | |
geo.country | object | |
geo.country.is_eu | boolean | |
geo.country.flag | string or null | |
geo.country.calling_code | string or null | |
geo.country.capital | string or null | |
geo.country.tld | string or null | |
geo.country.currency | object or null | |
geo.country.currency.code | string | |
geo.country.currency.name | string | |
geo.country.currency.symbol | string or null | |
geo.country.id | integer or null | |
geo.country.code | string or null | |
geo.country.name | string or null | |
geo.subdivision | object | |
geo.subdivision.id | integer or null | |
geo.subdivision.code | string or null | |
geo.subdivision.name | string or null | |
geo.city | object | |
geo.city.id | integer or null | |
geo.city.name | string or null | |
geo.postal_code | string or null | |
geo.latitude | number or null | |
geo.longitude | number or null | |
geo.radius | integer or null | Accuracy radius in km |
geo.timezone | object | |
geo.timezone.name | string or null | |
geo.timezone.offset | integer or null | Minutes behind UTC, like JavaScript getTimezoneOffset() (UTC-5 is 300) |
geo.timezone.utc_offset | string or null | |
geo.timezone.is_dst | boolean or null | |
geo.timezone.current_time | string or null | |
connection | object | |
connection.ip | string | |
connection.version | integer, one of 4, 6 | |
connection.bogon | boolean | Private, reserved or otherwise not routable |
connection.hostname | string or null | Only with hostname=1 |
connection.type | string or null | |
connection.isp | object | |
connection.isp.asn | integer or null | |
connection.isp.aso | string or null | AS organization |
connection.isp.name | string or null | |
connection.isp.organization | string or null | |
connection.isp.mcc | string or null | Mobile country code (mobile carriers) |
connection.isp.mnc | string or null | Mobile network code (mobile carriers) |
connection.anonymity | object | Whether the address is in a known network of each kind. Every score is from 0 to 1 in steps of 1/16: 0 means the address is not listed, and any score above 0 is a hit. A higher score means more, or more certain, evidence for that kind; it is not a probability. On api.host.sh the tor, vpn, proxy, dch, cdn and bot lists are updated every 6 hours. |
connection.anonymity.tor | object | Tor exit nodes (1 for a listed exit). |
connection.anonymity.tor.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.anonymity.vpn | object | Servers of commercial VPN services, as their operators publish them, and ranges known to be VPN exits. Cloudflare WARP (and Zero Trust) egress scores 0.5, because it also carries ordinary users of a privacy app and companies' traffic. Apple iCloud Private Relay is not VPN and scores 0. |
connection.anonymity.vpn.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.anonymity.proxy | object | Public open proxies, from lists that test them every hour or so (a listed proxy scores 0.75 or more). About half of them are compromised home or mobile devices, so treat a hit as a signal, not proof, and don't block home users on it alone. |
connection.anonymity.proxy.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.anonymity.dch | object | Hosting and data center ranges: cloud, VPS and dedicated server providers. name and url name the provider where it is known. Coverage of IPv6 hosting space is lower than of IPv4. |
connection.anonymity.dch.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.anonymity.dch.name | string or null | Name of the network, organization, provider or crawler where known |
connection.anonymity.dch.url | string or null | Its website, where known |
connection.anonymity.cdn | object | CDN edge ranges. name and url name the CDN. |
connection.anonymity.cdn.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.anonymity.cdn.name | string or null | Name of the network, organization, provider or crawler where known |
connection.anonymity.cdn.url | string or null | Its website, where known |
connection.anonymity.bot | object | Ranges that search engines, AI crawlers and monitoring services publish for their crawlers. name and url name the crawler, useragent the token in its User-Agent. A hit means the address belongs to that crawler; check the User-Agent too, a browser from the same range is not the crawler. |
connection.anonymity.bot.useragent | string or null | |
connection.anonymity.bot.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.anonymity.bot.name | string or null | Name of the network, organization, provider or crawler where known |
connection.anonymity.bot.url | string or null | Its website, where known |
connection.anonymity.scraper | object | Legacy data that is not maintained; currently empty, so 0 for every address. |
connection.anonymity.scraper.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.anonymity.ddos | object | Legacy data that is not maintained; currently empty, so 0 for every address. |
connection.anonymity.ddos.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage | object | Scores (0 to 1, as for anonymity) for com, org, edu, lib, gov, mil, isp and mob networks, with name and url where known. Legacy data that has not been updated since 2023: gov, lib, mil and org may be outdated, and com, edu, isp and mob are currently empty (0 for every address). |
connection.usage.com | object | Commercial networks |
connection.usage.com.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.com.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.com.url | string or null | Its website, where known |
connection.usage.org | object | Non-profit organizations |
connection.usage.org.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.org.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.org.url | string or null | Its website, where known |
connection.usage.edu | object | Educational institutions |
connection.usage.edu.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.edu.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.edu.url | string or null | Its website, where known |
connection.usage.lib | object | Libraries |
connection.usage.lib.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.lib.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.lib.url | string or null | Its website, where known |
connection.usage.gov | object | Government |
connection.usage.gov.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.gov.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.gov.url | string or null | Its website, where known |
connection.usage.mil | object | Military |
connection.usage.mil.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.mil.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.mil.url | string or null | Its website, where known |
connection.usage.isp | object | Internet service providers |
connection.usage.isp.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.isp.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.isp.url | string or null | Its website, where known |
connection.usage.mob | object | Mobile networks |
connection.usage.mob.score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
connection.usage.mob.name | string or null | Name of the network, organization, provider or crawler where known |
connection.usage.mob.url | string or null | Its website, where known |
user_agent | string | |
client | object | |
os | object | |
device | object |
Score
| Field | Type | Description |
|---|---|---|
score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
NamedScore
| Field | Type | Description |
|---|---|---|
score | number, 0 to 1 in steps of 0.0625 | 0 is not listed; any score above 0 is a hit |
name | string or null | Name of the network, organization, provider or crawler where known |
url | string or null | Its website, where known |
Errors
| Field | Type | Description |
|---|---|---|
errors | array of object | |
errors[].code | integer | |
errors[].message | string | |
errors[].reason | string | |
errors[].detail | string |
This page as Markdown: /docs/openapi/index.md