# iplookupapi documentation > iplookupapi resolves IP addresses to geolocation, network, timezone and security data over a simple JSON REST API. Authenticate every request with your API key via the `apikey` query parameter or request header. Base URL: https://api.iplookupapi.com OpenAPI specification: https://iplookupapi.com/docs/openapi.yaml --- Source: https://iplookupapi.com/docs # iplookupapi Documentation iplookupapi resolves IP addresses (both IPv4 & IPv6) to geolocation, network, timezone and security data over a simple JSON REST API. Building with an AI assistant? The full API is available as a machine-readable [OpenAPI 3.1 specification](https://iplookupapi.com/docs/openapi.yaml), and the documentation is published as [llms.txt](https://iplookupapi.com/docs/llms.txt) / [llms-full.txt](https://iplookupapi.com/docs/llms-full.txt). There is also a hosted [MCP server](https://iplookupapi.com/docs/mcp) at `https://api.iplookupapi.com/mcp` that AI agents can connect to directly. ## Your first request 1. Register at our [developer portal](https://app.iplookupapi.com/register) to get your free API key. 2. Query the [`/v1/info` endpoint](/docs/info) with your key: ```bash # your own IP curl "https://api.iplookupapi.com/v1/info?apikey=YOUR-APIKEY" # query a specific IP curl "https://api.iplookupapi.com/v1/info?ip=1.1.1.1&apikey=YOUR-APIKEY" ``` 3. That's it — the JSON response contains the geolocation, network, timezone and security data of the IP address. See the [Info Endpoint](/docs/info) for every response field. ## Official libraries | Language | Code | Repository | |-----------------------|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------| | R | [https://github.com/everapihq/iplookupapi-r](https://github.com/everapihq/iplookupapi-r) | [https://cran.r-project.org/web/packages/iplookupapi/index.html](https://cran.r-project.org/web/packages/iplookupapi/index.html) | | JavaScript ES6 module | [https://github.com/everapihq/iplookupapi-js](https://github.com/everapihq/iplookupapi-js) | [https://www.npmjs.com/package/@everapi/iplookupapi-js](https://www.npmjs.com/package/@everapi/iplookupapi-js) | | PHP | [https://github.com/everapihq/iplookupapi-php](https://github.com/everapihq/iplookupapi-php) | [https://packagist.org/packages/everapi/iplookupapi-php](https://packagist.org/packages/everapi/iplookupapi-php) | | Go | [https://github.com/everapihq/iplookupapi-go](https://github.com/everapihq/iplookupapi-go) | [https://pkg.go.dev/github.com/everapihq/iplookupapi-go](https://pkg.go.dev/github.com/everapihq/iplookupapi-go) | | Rust | [https://github.com/everapihq/iplookupapi-rs](https://github.com/everapihq/iplookupapi-rs) | [https://crates.io/crates/iplookupapi-rs](https://crates.io/crates/iplookupapi-rs) | | Ruby | [https://github.com/everapihq/iplookupapi-ruby](https://github.com/everapihq/iplookupapi-ruby) | [https://rubygems.org/gems/iplookupapi](https://rubygems.org/gems/iplookupapi) | | C# | [https://github.com/everapihq/iplookupapi-dotnet](https://github.com/everapihq/iplookupapi-dotnet) | [https://www.nuget.org/packages/iplookupapi/](https://www.nuget.org/packages/iplookupapi/) | | Python | [https://github.com/everapihq/iplookupapi-python](https://github.com/everapihq/iplookupapi-python) | [https://pypi.org/project/iplookupapi/0.1/](https://pypi.org/project/iplookupapi/0.1/) | ## Authentication & API Key Information iplookupapi.com uses API keys to allow access to the API. You can register a new API key at our [developer portal](https://app.iplookupapi.com/register). While our free plan only allows one API key at a time, our paid plans offer multiple API keys. By using separate keys for different use cases you can track individual usage and make key rotations affect only certain parts of your application. ## Authentication methods To authorize, you can use the following ways: ### GET query parameter You can pass your API key along with every request by adding it as a query parameter `apikey` This method could expose your API key in access logs and such. Sending the API key via a header parameter as specified below circumvents this problem. ```bash curl "https://api.iplookupapi.com/v1/info?ip=1.1.1.1&apikey=YOUR-APIKEY" ``` ```javascript var oReq = new XMLHttpRequest(); oReq.addEventListener("load", function () { console.log(this.responseText); }); oReq.open("GET", "https://api.iplookupapi.com/v1/info?ip=1.1.1.1&apikey=YOUR-APIKEY"); oReq.send(); ``` ```php $url = "https://api.iplookupapi.com/v1/info?ip=1.1.1.1&apikey=YOUR-APIKEY"; $curl = curl_init($url); $resp = curl_exec($curl); var_dump($resp); ```` ```python import requests from requests.structures import CaseInsensitiveDict url = "https://api.iplookupapi.com/v1/info?ip=1.1.1.1&apikey=YOUR-APIKEY" resp = requests.get(url) print(resp.status_code) ```` ### HTTP Header You can set a request header with the name `apikey` ```bash curl "https://api.iplookupapi.com/v1/info?ip=1.1.1.1" \ -H "apikey: YOUR-APIKEY" ``` ```javascript var oReq = new XMLHttpRequest(); oReq.addEventListener("load", function () { console.log(this.responseText); }); oReq.open("GET", "https://api.iplookupapi.com/v1/info?ip=1.1.1.1"); oReq.setRequestHeader("apikey", "YOUR-APIKEY"); oReq.send(); ``` ```php $url = "https://api.iplookupapi.com/v1/info?ip=1.1.1.1"; $curl = curl_init($url); $headers = array( "apikey: YOUR-APIKEY", ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $resp = curl_exec($curl); var_dump($resp); ```` ```python import requests from requests.structures import CaseInsensitiveDict url = "https://api.iplookupapi.com/v1/info?ip=1.1.1.1" headers = CaseInsensitiveDict() headers["apikey"] = "YOUR-APIKEY" resp = requests.get(url, headers=headers) print(resp.status_code) ```` ## Rate limit and quotas You can use a certain number of requests per month, defined by your plan. Once you go over this quota, the API returns a `429` HTTP status code, and you either need to upgrade your plan or wait until the end of the month. We enforce a minute rate limit for specific plans. If you exceed this, the API returns a `429` HTTP status code. You then have to wait until the end of the minute to make more requests. Only successful calls count against your quota. Any error on our side or validation errors (e.g., wrong parameter) will NOT count against your quota or rate limit. ### Response Headers We attach specific headers to tell you your current monthly/minute quota and how much you have remaining in the period. ```HTTP X-RateLimit-Limit-Quota-Minute: 10 X-RateLimit-Limit-Quota-Month: 300 X-RateLimit-Remaining-Quota-Minute: 5 X-RateLimit-Remaining-Quota-Month: 199 X-Cost: 1 ``` - The `*-Quota-Month` headers show your monthly quota and how much of it is remaining. - The `*-Quota-Minute` headers are only present on plans with a minute rate limit. - `X-Cost` tells you how many requests the call counted against your quota (`0` for sandbox requests). While your account is consuming grace quota (e.g. while a payment is still pending), the monthly quota headers are replaced by `x-ratelimit-limit-grace-month` / `x-ratelimit-remaining-grace-month`. If overages are enabled for your account and you exceed your monthly quota, the additional overage usage is reported via `x-ratelimit-limit-overage-month` / `x-ratelimit-remaining-overage-month`. --- Source: https://iplookupapi.com/docs/info # Info Endpoint 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?ip=[[ ip ]]` ## 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`, a reverse DNS lookup is performed and the `hostname` field is populated. Disabled by default because it can add response time | ## Sample Response ```json { "data": { "ip": "1.1.1.1", "hostname": null, "type": "v4", "range_type": { "type": "PUBLIC", "description": "Public address" }, "connection": { "asn": 13335, "organization": "Cloudflare, Inc.", "isp": "Cloudflare, Inc", "range": "1.1.1.0/24" }, "location": { "geonames_id": 5392171, "latitude": 37.33938980102539, "longitude": -121.89495849609375, "zip": "95101", "continent": { "code": "NA", "name": "North America", "name_translated": "North America", "geonames_id": 6255149, "wikidata_id": "Q49" }, "country": { "alpha2": "US", "alpha3": "USA", "calling_codes": ["+1"], "currencies": [ { "symbol": "$", "name": "US Dollar", "symbol_native": "$", "decimal_digits": 2, "rounding": 0, "code": "USD", "name_plural": "US dollars" } ], "emoji": "🇺🇸", "ioc": "USA", "languages": [ { "name": "English", "name_native": "English" } ], "name": "United States", "name_translated": "United States", "timezones": [ "America/New_York", "America/Detroit", "America/Kentucky/Louisville", "America/Kentucky/Monticello", "America/Indiana/Indianapolis", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Vevay", "America/Chicago", "America/Indiana/Tell_City", "America/Indiana/Knox", "America/Menominee", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/North_Dakota/Beulah", "America/Denver", "America/Boise", "America/Phoenix", "America/Los_Angeles", "America/Anchorage", "America/Juneau", "America/Sitka", "America/Metlakatla", "America/Yakutat", "America/Nome", "America/Adak", "Pacific/Honolulu" ], "is_in_european_union": false, "fips": "US", "geonames_id": 6252001, "hasc_id": "US", "wikidata_id": "Q30" }, "city": { "fips": "0668000", "alpha2": null, "geonames_id": 5392171, "hasc_id": null, "wikidata_id": "Q16553", "name": "San Jose", "name_translated": "San Jose" }, "region": { "fips": "US06", "alpha2": "US-CA", "geonames_id": 5332921, "hasc_id": "US.CA", "wikidata_id": "Q99", "name": "California", "name_translated": "California" } }, "tlds": [".us"], "timezone": { "id": "America/Los_Angeles", "current_time": "2024-07-19T03:22:18-07:00", "code": "PDT", "is_daylight_saving": true, "gmt_offset": -25200 }, "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, "is_icloud_relay": false, "threat_score": 0 }, "domains": { "count": 31337, "domains": [ "test-domain-1.com", "test-domain-2.com", "test-domain-3.com", "test-domain-4.com", "test-domain-5.com" ] } } } ``` ## Response structure The `/info` endpoint offers the following information: `data` (general information), `range_type`, `connection`, `location`, `tlds`, `timezone`, `security` and `domains`. ## data ```json "data": { "ip": "1.1.1.1", "hostname": "one.one.one.one", "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` | 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_ ```json "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 / Linked-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_ ```json "connection": { "asn": 13335, "organization": "Cloudflare, Inc.", "isp": "APNIC Research and Development", "range": "1.1.1.1/32" } ``` **Available in: all plans** | Name | Type | Description | | -------------- | --------- | ---------------------------------- | | `asn` | _integer_ | The ASN number | | `organization` | _string_ | ️The ASN organization | | `isp` | _string_ | The name of the ISP | | `range` | _string_ | The IP range the address belongs to | ## location Type: _object_ **Available in: all plans** | Name | Type | Description | | ------------- | --------- | ------------------------------------------------------- | | `geonames_id` | _integer_ | The Geonames ID of the most specific known location | | `latitude` | _float_ | ️The latitude of the IP's location | | `longitude` | _float_ | The longitude of the IP's location | | `zip` | _string_ | The postal/zip code | ### 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](https://www.geonames.org) | [https://www.geonames.org/5332921/](https://www.geonames.org/5332921/) for California | | _hasc_id_ | [Wikidata](https://www.wikidata.org/) | [https://www.wikidata.org/wiki/Property:P8119](https://www.wikidata.org/wiki/Property:P8119) represents country subdivions within | | _wikidata_id_ | [Wikidata](https://www.wikidata.org/) | [https://www.wikidata.org/wiki/Q30](https://www.wikidata.org/wiki/Q30) for the United States | | _fips_ | [FIPS](https://www.census.gov/library/reference/code-lists/ansi.html) | | 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](#third-party-data-ids) | | `wikidata_id` | _string_ | [reference](#third-party-data-ids) | ### `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\_ | All available calling codes for this country | | `currencies` | _array\_ | The country's currencies, see below | | `emoji` | _string_ | The country's flag as an emoji | | `ioc` | _string_ | The IOC's three-letter representation of the country code ([reference](https://en.wikipedia.org/wiki/List_of_IOC_country_codes)) | | `languages` | _array\_ | The country's languages, see below | | `name` | _string_ | The country name | | `name_translated` | _string_ | The country name in the requested `language` | | `timezones` | _array\_ | All of the available timezones within 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](https://en.wikipedia.org/wiki/List_of_FIPS_country_codes)) | | `geonames_id` | _integer_ | [reference](#third-party-data-ids) | | `hasc_id` | _string_ | [reference](#third-party-data-ids) | | `wikidata_id` | _string_ | [reference](#third-party-data-ids) | #### `country`.`currencies` Type: _array\_ | 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_ | | | `code` | _string_ | ️The three-letter currency code | | `name_plural` | _string_ | The plural version of the currency | #### `country`.`languages` Type: _array\_ | 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](https://www.census.gov/library/reference/code-lists/ansi.html)) | | `alpha2` | _string_ | ️The ISO representation of the city | | `geonames_id` | _integer_ | [reference](#third-party-data-ids) | | `hasc_id` | _string_ | [reference](#third-party-data-ids) | | `wikidata_id` | _string_ | ️[reference](#third-party-data-ids) | | `name` | _string_ | The city name | | `name_translated` | _string_ | The city name in the requested `language` | ### `region` Type: _object_ | Parameter | Type | Description | | ----------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------- | | `fips` | _string_ | The FIPS representation of the region code ([reference](https://www.census.gov/library/reference/code-lists/ansi.html)) | | `alpha2` | _string_ | ️The ISO representation of the region (e.g. `US-CA`) | | `geonames_id` | _integer_ | [reference](#third-party-data-ids) | | `hasc_id` | _string_ | [reference](#third-party-data-ids) | | `wikidata_id` | _string_ | ️[reference](#third-party-data-ids) | | `name` | _string_ | The region name | | `name_translated` | _string_ | The region name in the requested `language` | ## tlds Type: _array\_ **Available in: all plans** The top-level domains associated with the IP's country, e.g. `[".us"]` ## timezone ```json "timezone": { "id": "America/Los_Angeles", "current_time": "2024-07-19T03:22:18-07:00", "code": "PDT", "is_daylight_saving": true, "gmt_offset": -25200 } ``` Type: _object_ **Available in: all plans** | Name | Type | Description | | -------------------- | --------- | -------------------------------------- | | `id` | _string_ | The timezone | | `current_time` | _string_ | The current time as a datetime string | | `code` | _string_ | The three-letter code for the timezone | | `is_daylight_saving` | _boolean_ | If it is currently daylight saving | | `gmt_offset` | _integer_ | The offset to GMT in seconds | ## security ```json "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, "is_icloud_relay": false, "threat_score": 0 } ``` 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_ | If the IP is anonymous | | `is_datacenter` | _boolean_ | ️If the IP is an address used in a datacenter | | `is_vpn` | _boolean_ | ️If the IP is a known VPN | | `is_bot` | _boolean_ | ️If the IP is a known bot | | `is_abuser` | _boolean_ | ️If the IP is a known abuser | | `is_known_attacker` | _boolean_ | If the IP is a known attacker | | `is_proxy` | _boolean_ | If the IP is a known proxy | | `is_spam` | _boolean_ | If the IP is a known spammer | | `is_tor` | _boolean_ | If the IP is a known Tor endpoint | | `is_icloud_relay` | _boolean_ | If the IP is a known iCloud relay IP | | `threat_score` | _integer_ | A threat score on a scale from 0 to 100, with 0 representing no threat and 100 the highest threat level | ## domains ```json "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\_ | ️A list of domains hosted on this IP | --- Source: https://iplookupapi.com/docs/mcp # MCP Server iplookupapi ships a hosted [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server, so AI agents and assistants can call the API as native tools — no SDK or glue code required. ``` https://api.iplookupapi.com/mcp ``` The endpoint speaks the streamable HTTP transport. Listing the available tools works without authentication; executing a tool requires your API key, sent as the `apikey` header. You can [get a free API key here](https://app.iplookupapi.com/register). ## Connect Using Claude Code: ```bash claude mcp add --transport http iplookupapi https://api.iplookupapi.com/mcp --header "apikey: YOUR_API_KEY" ``` Or add the server to any MCP-capable client (Claude Desktop, Cursor, VS Code, ...): ```json { "mcpServers": { "iplookupapi": { "url": "https://api.iplookupapi.com/mcp", "headers": { "apikey": "YOUR_API_KEY" } } } } ``` ## Available tools The tools are generated from the same [OpenAPI specification](https://iplookupapi.com/docs/openapi.yaml) that describes the REST API, so they always match the documented endpoints, parameters and responses. | Tool | Endpoint | Description | |---|---|---| | `getInfo` | `GET /v1/info` | Look up an IP address | | `getStatus` | `GET /v1/status` | Account quota status | ## Quotas and errors Tool calls are metered exactly like REST requests: they consume your plan quota and return the same status codes and error responses (`401`, `422`, `429`, ...). If a call fails, the tool result contains the API's error message including hints on how to proceed. --- Source: https://iplookupapi.com/docs/status # Status Endpoint Returns your current quota Requests to this endpoint do not count against your quota or rate limit **Request Method:** `GET` **Request URL:** `https://api.iplookupapi.com/v1/status` ## Request Parameters | Parameter | Type | Mandatory | Description | | --------- | -------- | ---------- | ------------ | | `apikey` | _string_ | ️ | Your API Key | ## Sample Response ```json { "account_id": 313373133731337, "quotas": { "month": { "total": 300, "used": 71, "remaining": 229 }, "grace": { "total": 0, "used": 0, "remaining": 0 } } } ``` | Field | Description | | ----------------- | -------------------------------------------------------------------------------------------- | | `account_id` | The ID of your account | | `quotas`.`month` | Your monthly request quota: the plan's total, how much you used and how much is remaining | | `quotas`.`grace` | Your grace quota, see below | The grace quota is a temporary allowance we grant while a payment is still pending (for example after a failed renewal), so your integration keeps working without interruption. In normal operation all of its values are `0`. While you are consuming grace quota, the monthly quota response headers are replaced by `x-ratelimit-limit-grace-month` / `x-ratelimit-remaining-grace-month`. --- Source: https://iplookupapi.com/docs/status-codes # Request Status Codes For all requests, we will return an HTTP status code that indicates a success or the problem that has led to the failure. A successful request will be returned with status code `200` ## API Error Codes ### 401 Invalid authentication credentials ### 403 You are not allowed to use this endpoint, please [upgrade your plan](https://app.iplookupapi.com/subscription). ### 404 A requested endpoint does not exist, or no data is available for the requested IP address. The response message tells you which case you hit: - `No route found` — the requested endpoint does not exist, please check your request URL - `No data found for this IP` — your request was valid, but we have no data for the requested IP address ### 422 Validation error, please check the list of validation errors: [here](#validation-errors) ### 429 You have hit your rate limit or your monthly limit. For more requests please [upgrade your plan](https://app.iplookupapi.com/subscription). ### 500 Internal Server Error - let us know: support@iplookupapi.com ## Error response body Errors are returned as JSON. Every error carries a human-readable `message`, and where available an `info` field links back to this page. Responses with status `401`, `403`, `404` and `429` additionally carry a machine-readable error envelope, so scripts and AI agents always get a next step. `422` validation errors and `500` errors do not carry the envelope — they only include `message` (plus `errors` and `info` for validation errors): ```json { "message": "You used all your monthly requests. Please upgrade your plan at https://app.iplookupapi.com/subscription", "error": { "code": "quota_exceeded", "message": "You used all your monthly requests. Please upgrade your plan at https://app.iplookupapi.com/subscription" }, "quota": { "limit": 300, "used": 300, "remaining": 0, "resets_at": "2026-09-01T00:00:00+00:00" }, "actions": { "upgrade": "https://app.iplookupapi.com/subscription?utm_source=api_error&utm_campaign=quota_exceeded", "docs": "https://iplookupapi.com/docs/openapi.yaml" } } ``` | Field | Description | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `error.code` | A stable, machine-readable error code, e.g. `invalid_api_key`, `quota_exceeded`, `rate_limit_exceeded`, `not_found` or `forbidden` | | `error.message` | The same human-readable message as the top-level `message` | | `quota` | Only present on quota errors: the `limit`, `used` and `remaining` requests of the exhausted quota, plus `resets_at` (ISO 8601 timestamp of the next reset, or `null`) | | `actions` | URLs for the most useful next steps, e.g. `upgrade` (change your plan) on quota errors, or `sign_up` and `docs` on authentication errors | The envelope fields are additive — the existing `message` and `info` fields are unchanged, so treat `error`, `quota` and `actions` as optional when parsing error responses. ## Validation errors #### Invalid Ip The `ip` field must be a valid IP address #### Invalid language The selected `language` is invalid Supported values: `de`, `en`, `es`, `fr`, `ja`, `pt`, `ru`, `zh` #### Invalid hostname The `hostname` field must be `true` or `false` --- Source: https://iplookupapi.com/docs/testing # Testing ***Available in plans >= medium*** This page includes all needed information to make sure your test environment works before deploying to production. ### Sandbox API Keys An API request sent with a sandbox API key is automatically identified as a request in sandbox mode. All requests with sandbox keys will respond with dummy data. Requests done with sandbox keys do not count against your quota ### Response All API endpoints will respond with the data for the IP `1.1.1.1` and the ASN `AS13335`