IP geolocation and lookup API overview
How the host.sh IP lookup API works: endpoints, API tokens, the Bearer header or token= parameter, and free tokenless lookups of your own IP.
The host.sh API answers with JSON about any IPv4 or IPv6 address: approximate location, time zone, ISP, ASN, connection type and flags such as VPN, proxy and Tor. It runs at https://api.host.sh (HTTPS only; plain HTTP is redirected) and allows cross-origin requests, so it works from a browser too.
Endpoints
| Endpoint | What it does | Token |
|---|---|---|
GET /v2/lookup/ | Your own IP, or any IP with ip= | Not for your own IP |
GET /v2/lookup/{ip} | One address in the path, e.g. /v2/lookup/8.8.8.8 | Yes |
POST /v2/lookup/ | Same as GET, parameters in a JSON or form body | Not for your own IP |
POST /v2/lookup/batch/ | Up to 100 addresses in one request | Yes |
GET /v2/ip/ | Just your IP address, as text or {"ip": ...} | No |
GET /v2/openapi.yaml | The OpenAPI spec | No |
https://ipv4.host.sh serves the same API over IPv4 only, to learn the IPv4 address of a dual-stack client.
- Lookup: one address, its parameters and code examples
- Batch: many addresses in one request
- Response fields: what every field in the answer means
- Errors: every error code and reason the API returns
- Rate limits: what is limited and how to retry
- OpenAPI reference: the spec on one page
Authentication
A token is a secret string that identifies your account. Tokens are invite only for now. With a token you can look up any address and send batch lookups; which sections of the answer you get depends on your token's plan. Send it in one of three ways:
| Where | Example | Works on |
|---|---|---|
Authorization: Bearer header | -H "Authorization: Bearer YOUR_TOKEN" | Every endpoint |
token query parameter | ?token=YOUR_TOKEN | Every endpoint |
token field of a JSON body | {"token": "YOUR_TOKEN", "ip": "8.8.8.8"} | POST /v2/lookup/ |
Prefer the Bearer header. A token in the URL ends up in browser history, proxy logs and shell history, and anyone who has it can use your plan. If a request carries more than one, a JSON body token wins over ?token=, and ?token= wins over the header. A form body field named token is not read as a token.
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.host.sh/v2/lookup/8.8.8.8
An unknown or disabled token, or one without permission for the endpoint, gets 403 with reason TOKEN_INVALID. The batch endpoint without a token gets 401 with reason TOKEN_MISSING. See Errors.
No token: your own IP
Without a token the API looks up the address the request comes from, for free and with no sign-up:
curl https://api.host.sh/v2/lookup/
This tokenless mode has limits:
- It only looks up your own IP. Asking for another one, with
ip=, the path form/v2/lookup/8.8.8.8, orua=andal=, gets403with reasonTOKEN_REQUIRED. - Batch lookups always need a token.
- It allows 10 requests a minute per IP address, with short bursts of up to 10. Over that the API answers
429with aRetry-Afterheader; see Rate limits. - The answer has the location, ISP, connection and anonymity sections, and the parsed
User-AgentandAccept-Languageheaders of the request itself. It has noconnection.usagesection.
All the options work in tokenless mode: fields, format=text, lang, hostname=1, pretty=1 and callback.
From a terminal there is also curl host.sh, which needs no key either: it prints your IP details as flat JSON, and curl host.sh/ip or curl host.sh/city print one value. curl host.sh/help lists the fields.
Response format
Every answer is UTF-8 JSON (application/json; charset=utf-8) unless you ask for format=text or JSONP. Values the API doesn't know are null rather than left out, so the shape of the answer stays the same from one address to the next. Errors come as an errors array with a numeric code, a message, a machine-readable reason and a detail sentence:
{"errors":[{"code":403,"message":"Forbidden","reason":"TOKEN_REQUIRED","detail":"Looking up anything but your own IP needs a token"}]}
This page as Markdown: /docs/index.md