{
  "openapi": "3.1.0",
  "info": {
    "title": "ipapi.is",
    "version": "1",
    "description": "IP address API and the account API behind it. A person creates the account at https://ipapi.is/app/signup: sign-up is protected by bot detection and refused from datacenter, VPN, proxy and Tor addresses. After that the API key does everything below, with no browser: lookups, plan and usage, subscriptions, invoices, database downloads, data corrections, cancelling and a new key. A free account includes 1,000 lookups per day. Every change made with the key is mailed to the account. Paying and accepting new Terms of Service stay in the dashboard.",
    "contact": {
      "email": "info@ipapi.is",
      "url": "https://ipapi.is/developers.html"
    },
    "termsOfService": "https://ipapi.is/terms.html"
  },
  "externalDocs": {
    "url": "https://ipapi.is/developers.html"
  },
  "servers": [
    {
      "url": "https://api.ipapi.is",
      "description": "Lookups, served by the nearest server of the fleet"
    }
  ],
  "security": [
    {
      "key": []
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "lookup",
        "summary": "Look up one IP address or AS number",
        "description": "Without q, the address the request comes from. Without a key: 30 lookups per IP address per UTC day and the FreeTierResponse; AS numbers need a key.",
        "security": [
          {
            "key": []
          },
          {}
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "IPv4 or IPv6 address, or an AS number such as AS15169",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Output format",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "html",
                "toon",
                "csv",
                "text"
              ],
              "default": "json"
            }
          },
          {
            "name": "geoloc_meta",
            "in": "query",
            "required": false,
            "description": "1 adds location.geofeed, the RFC 8805 geofeeds used to locate the address",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          },
          {
            "name": "all_companies",
            "in": "query",
            "required": false,
            "description": "1 returns every WHOIS record covering the address: company becomes an array",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/IpResponse"
                    },
                    {
                      "$ref": "#/components/schemas/AsnResponse"
                    },
                    {
                      "$ref": "#/components/schemas/FreeTierResponse"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid query",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid key, or a key is required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Quota used up; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "lookupBulk",
        "summary": "Look up to 100 IP addresses and AS numbers at once",
        "description": "The response is an object keyed by the entries sent, each value what a single lookup returns, plus total_elapsed_ms. Every entry counts as one request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key",
                  "ips"
                ],
                "properties": {
                  "key": {
                    "type": "string",
                    "description": "Your API key"
                  },
                  "ips": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "string"
                    },
                    "description": "IPv4, IPv6 and AS numbers, mixed"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "total_elapsed_ms": {
                      "type": "number"
                    }
                  },
                  "additionalProperties": {
                    "anyOf": [
                      {
                        "$ref": "#/components/schemas/IpResponse"
                      },
                      {
                        "$ref": "#/components/schemas/AsnResponse"
                      },
                      {
                        "$ref": "#/components/schemas/FreeTierResponse"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Quota used up; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/account": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "getAccount",
        "summary": "Plan, daily limit, usage today and for 30 days, credits, downloadable databases",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/subscriptions": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "listSubscriptions",
        "summary": "Every subscription billed through Stripe or PayPal: price, renewal date, scheduled end",
        "description": "Read from Stripe and PayPal and kept for five minutes.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Subscription"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Stripe or PayPal did not answer",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/subscriptions/cancel": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "post": {
        "operationId": "cancelSubscription",
        "summary": "Cancel a subscription at the end of the period that is paid for",
        "description": "Mailed to the account. A plan billed through PayPal is cancelled in the PayPal account (409).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key",
                  "id"
                ],
                "properties": {
                  "key": {
                    "type": "string",
                    "description": "Your API key"
                  },
                  "id": {
                    "type": "string",
                    "description": "The id from listSubscriptions"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "cancelled": {
                      "type": "boolean"
                    },
                    "endsAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The account is suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such subscription on the account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Billed through PayPal: cancel it there",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/key/rotate": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "post": {
        "operationId": "rotateKey",
        "summary": "Replace the API key; the old one stops working at once",
        "description": "Returns the new key, which is also on the dashboard. Mailed to the account. Once a minute.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key"
                ],
                "properties": {
                  "key": {
                    "type": "string",
                    "description": "Your API key"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The account is suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Replaced less than a minute ago; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/invoices": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "listInvoices",
        "summary": "Every invoice, oldest first, with a PDF url (add key to fetch it)",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Invoice"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/invoices/{fileName}": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "getInvoice",
        "summary": "One invoice as PDF",
        "parameters": [
          {
            "name": "fileName",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The invoice",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such invoice on the account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/invoices.zip": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "getInvoicesZip",
        "summary": "All invoices as one ZIP archive",
        "responses": {
          "200": {
            "description": "The invoices",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api/databases": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "listDatabaseFiles",
        "summary": "Every database file the account can download now, with its release date and download url",
        "description": "A file name changes with every release, so compare it with the last download before fetching again.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DatabaseFile"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/getData": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "downloadDatabase",
        "summary": "Download the latest release of a database the account subscribes to",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": true,
            "description": "A database from listDatabaseFiles, such as ipToVpn",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": true,
            "description": "csv or mmdb; ipToASN also json, reverseDNS only rdnsz",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "mmdb",
                "json",
                "rdnsz"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The release",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Not subscribed to this database"
          },
          "429": {
            "description": "Downloaded too often in 24 hours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/get": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "get": {
        "operationId": "downloadBusinessFile",
        "summary": "Business subscription: the full dumps, the self-hosted API server and its .ipdb database",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": true,
            "description": "database, databaseMmdb, server or ipdb",
            "schema": {
              "type": "string",
              "enum": [
                "database",
                "databaseMmdb",
                "server",
                "ipdb"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The release",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Not a Business subscription"
          },
          "429": {
            "description": "Downloaded too often in 24 hours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/app/api-corrections": {
      "servers": [
        {
          "url": "https://ipapi.is"
        }
      ],
      "post": {
        "operationId": "submitCorrection",
        "summary": "Report wrong data: a geofeed, or corrections of one field for a list of addresses",
        "externalDocs": {
          "url": "https://ipapi.is/corrections-via-api.html"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key",
                  "type",
                  "data"
                ],
                "properties": {
                  "key": {
                    "type": "string",
                    "description": "Your API key"
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "general",
                      "geofeed"
                    ]
                  },
                  "data": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid correction or key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "key": {
        "type": "apiKey",
        "in": "query",
        "name": "key",
        "description": "Your API key, from https://ipapi.is/app/home. POST requests also take it as key in the JSON body."
      }
    },
    "schemas": {
      "IpResponse": {
        "type": "object",
        "properties": {
          "ip": {
            "description": "The field ip contains the IP address that was queried. You may query any IPv4 or IPv6 address by specifying the q= parameter: https://api.ipapi.is/?q=199.59.148.0 If no IP address was specified (Example: https://api.ipapi.is ), the client's own IP address is looked up and ip is set to the client's public IP address. If the API is used in that way, it acts in the same way as for example https://icanhazip.com , just with more meta data.",
            "type": "string"
          },
          "rir": {
            "description": "The field rir specifies the Regional Internet Registry (RIR) that is authoritative for the queried IP address. There are five major RIRs for different areas of the world: ARIN (American Registry for Internet Numbers) RIPE NCC (Réseaux IP Européens Network Coordination Centre) APNIC (Asia-Pacific Network Information Centre) AFRINIC (African Network Information Centre) LACNIC (Latin American and Caribbean Internet Addresses Registry) Less-Known RIRs: TWNIC (Taiwan Network Information Center) CNNIC (China Internet Network Information Center) KRNIC (Korea Network Information Center) JPNIC (Japan Network Information Center)",
            "type": [
              "string",
              "null"
            ]
          },
          "is_bogon": {
            "description": "The field is_bogon determines if the queried IP address is bogon. Bogon IP addresses are not routable and thus not a part of the public Internet. Bogon IP addresses are not assigned / allocated to IANA or any other Regional Internet Registry. For example, the following IP addresses are bogon: 192.0.2.1 198.51.100.254 203.0.113.15 In general, there is no good reason to query bogon IP addresses, since they have no purpose in the public Internet. Nobody owns a bogon address and it is nowhere, so when is_bogon is true every ownership and geolocation field of the response is null .",
            "type": "boolean"
          },
          "is_mobile": {
            "description": "The field is_mobile determines if the queried IP address belongs to a mobile Internet Service Provider such as AT&T Wireless or T-Mobile. For security purposes, it is often beneficial to know whether an IP address belongs to a mobile ISP or not. For example, Carrier-grade NATs are often used in mobile networks. As a consequence, many mobile devices can have the same public IP address. This means that rate limiting or banning mobile IP addresses is not a good idea, since it will also block legitimate clients that share the same mobile, public IP address.",
            "type": "boolean"
          },
          "is_satellite": {
            "description": "The field is_satellite determines if the queried IP address belongs to a satellite Internet Service Provider such as Starlink, Viasat or OneWeb. There are many reasons why it is beneficial to know whether an IP address belongs to a satellite ISP or not: Satellite ISPs are often used by governments and military organizations for remote areas. Satellite IP addresses don't have a fixed Geolocation and can be anywhere in the world. Furthermore, satellite IP addresses are often used by multiple users sharing the same IP address. For example, the following IP addresses belongs to Starlink: 170.203.212.0",
            "type": "boolean"
          },
          "is_anycast": {
            "description": "The field is_anycast determines if the queried IP address is anycast: announced from many sites at once, so that every client reaches the nearest one, as with 1.1.1.1 or 8.8.8.8. An anycast address has no single location, so its geolocation accuracy is always VERY_LOW .",
            "type": "boolean"
          },
          "is_crawler": {
            "description": "The field is_crawler determines if the IP address is associated with a crawler (Good Bot). In case the IP is used by a crawler, the field is_crawler contains the name of the crawler as string such as \"GoogleBot\" or \"BingBot\" . Otherwise, the field's value is false . Some examples for IP addresses used by crawlers: TwitterBot - 199.59.148.0 GoogleBot - 66.249.70.224 BingBot - 40.77.190.180 DuckduckgoBot - 40.76.173.151 AppleBot - 17.22.253.152 YandexBot - 213.180.203.183",
            "type": [
              "boolean",
              "string"
            ]
          },
          "is_datacenter": {
            "description": "The field is_datacenter specifies whether the IP address belongs to a datacenter (hosting provider) or not. The definition of what constitutes a datacenter (hosting provider) is quite lenient and includes all of the following examples: Normal hosting providers such as Hetzner.de or Leaseweb.com Large cloud providers such as Amazon AWS or Microsoft Azure Content Delivery Networks such as Cloudflare , Fastly or edg.io Anti-DDOS services such as qrator.net or ddos-guard.net IP leasing organizations such as ipxo.com or interlir.com Other SaaS, IaaS, or PaaS organizations such as fly.io or Heroku Put differently: Every organization that allows third parties to quickly and anonymously obtain hosting resources (or control over IP addresses) is considered to be a hosting provider. If the field is_datacenter is true , there will be a datacenter object in the API output.",
            "type": "boolean"
          },
          "is_tor": {
            "description": "If the field is_tor is true , the IP address is a TOR exit node. TOR exit node detection is very accurate, so the value of the is_tor field can be relied upon. If the is_tor field is true , it is recommended to either challenge the client with a CAPTCHA or to block the client from accessing critical resources. The TOR network is often used by cyber criminals for malicious actions and if you are running a critical service, you might want to prohibit TOR clients from accessing it.",
            "type": "boolean"
          },
          "is_proxy": {
            "description": "The field is_proxy determines whether the IP address is a proxy server. In general, the field is_proxy only covers a subset of all proxies in the Internet. Put differently, ipapi.is cannot reliably detect residential and mobile proxies in all cases.",
            "type": "boolean"
          },
          "is_vpn": {
            "description": "The field is_vpn determines whether the IP address is a VPN Exit Node and has datatype boolean . If the VPN service can be detected, the is_vpn field is set to true . Otherwise, it is set to false . In some cases, the API provides more information about the detected VPN service in the vpn object. boolean (false) - 67.170.172.12 is not associated with an VPN, therefore the field is_vpn is set to false boolean (true) - 185.254.75.23 belongs to the VPN service Mullvad, therefore the field is_vpn is set to the value true and the vpn object contains data such as: The field is_vpn covers a constantly growing subset of all VPNs on the Internet. Due to our Systematic VPN Detection Approach , the VPN coverage of the API is constantly growing and becoming more accurate on a daily basis. See VPN Exit Nodes",
            "type": "boolean"
          },
          "is_abuser": {
            "description": "The field is_abuser is true , if the IP address committed abusive actions. Various open source IP blocklists and threat intelligence feeds are used to populate the is_abuser field. Additionally, a proprietary network of honeypots of more than 10 servers is used to compile a list of offending IP addresses. There is no further differentiation of the abusive action, the offending IP could have been a virus, bot, crawler, scraper or worm or some other malicious entity.",
            "type": "boolean"
          },
          "datacenter": {
            "description": "The datacenter object is only present if the queried IP address belongs to a hosting provider. The datacenter object contains meta information of the hosting provider / datacenter. The format of the datacenter object is free. Depending on the hosting provider, the contents of the datacenter object changes. Providers that publish their own address ranges (AWS, Azure, Google Cloud, Oracle, DigitalOcean and others) contribute richer members such as region , service or city ; for providers that publish nothing, only the operator name and the network are known.",
            "type": "object",
            "properties": {
              "datacenter": {
                "description": "The name of the hosting provider / datacenter operator that announces this network. Examples: \"Amazon AWS\" , \"Hetzner\" , \"DigitalOcean\" .",
                "type": "string"
              },
              "code": {
                "description": "The provider's short code for this location, e.g. an airport-style site code.",
                "type": "string"
              },
              "city": {
                "description": "The city of the datacenter, as published by the hosting provider. This comes from the provider rather than from our geolocation database, so it can differ from location.city .",
                "type": "string"
              },
              "state": {
                "description": "The state / administrative area of the datacenter, as published by the hosting provider.",
                "type": "string"
              },
              "country": {
                "description": "The country of the datacenter, as published by the hosting provider. This comes from the provider rather than from our geolocation database, so it can differ from location.country .",
                "type": "string"
              },
              "network": {
                "description": "The network in CIDR format that the hosting provider published for this address. It is the provider's own declaration of the range, which is usually more precise than the WHOIS company.network .",
                "type": "string"
              },
              "domain": {
                "description": "The website of the hosting provider.",
                "type": "string"
              },
              "service": {
                "description": "The provider's product this range is allocated to &mdash; \"EC2\" , \"CLOUDFRONT\" , \"S3\" , \"AzureFrontDoor.Frontend\" . Useful for telling a customer VM apart from the provider's own CDN or managed service, which behave very differently in a traffic filter.",
                "type": "string"
              },
              "scope": {
                "description": "How widely the provider applies this range, e.g. a single region versus a global anycast pool.",
                "type": "string"
              },
              "region": {
                "description": "The provider's region for this network, in the provider's own naming. Examples: \"us-east-1\" (AWS), \"westeurope\" (Azure), \"nyc3\" (DigitalOcean).",
                "type": "string"
              },
              "network_border_group": {
                "description": "An AWS-specific grouping: the set of availability zones or Local Zones from which AWS advertises this range. Addresses in a Local Zone carry a different border group from the parent region, which is why the datacenter location can differ from the region name.",
                "type": "string"
              },
              "name": {
                "description": "The name of the datacenter facility or of the provider's site, as published by the provider.",
                "type": "string"
              },
              "regionId": {
                "description": "The provider's numeric identifier for the region, published alongside the region name.",
                "type": "integer"
              },
              "platform": {
                "description": "The cloud platform this range belongs to, as the provider names it, e.g. \"AzureCloud\" .",
                "type": "string"
              },
              "systemService": {
                "description": "The provider's internal name for the managed service that owns the range, e.g. \"AzureFrontDoor.Frontend\" or \"AzureContainerRegistry\" . Like service , it separates the provider's own infrastructure from ranges rented out to customers.",
                "type": "string"
              },
              "postal": {
                "description": "The postal code of the datacenter, as published by the hosting provider.",
                "type": "string"
              }
            }
          },
          "company": {
            "description": "The company object contains meta information about the organization that owns the queried IP address. Most IP addresses can be associated with an organization or company. The API uses WHOIS information to infer which organization is the administrative owner of the queried IP address. The owner of an IP address is stored in the databases of the five Regional Internet Registies (RIR'rs). For example, IP address ownership in RIPE NCC is handled with inetnum (IPv4) and inet6num (IPv6) objects. In ARIN , IP address ownership can be inferred from NetRange objects. One IP address can be owned by more than one organization. In order to lookup all organizations associated with a specific IP address, use the all_companies=1 parameter as follows: https://api.ipapi.is/?q=83.208.108.91&all_companies=1",
            "type": "object",
            "properties": {
              "name": {
                "description": "The name of the organization (company). The name is obtained from the corresponding WHOIS record. The company name does not have to match the org field of the asn object.",
                "type": "string"
              },
              "abuser_score": {
                "description": "The field abuser_score represents the quota of abusive IP addresses of the network belonging to the organization (company). The higher this number is, the more abusive the whole network is. abuser_score = Number of Abusive IPs / Number of Total IPs in the Network The following score classifications are made: Very High - More than 20% of all IPs of the network are abusive High - Between 3% to 20% of all IPs of the network are abusive Elevated - Between 0.85% to 3% of all IPs of the network are abusive Low - Between 0.85% to 0.05% of all IPs of the network are abusive Very Low - Less than 0.05% of all IPs of the network are abusive",
                "type": "string"
              },
              "domain": {
                "description": "The domain name of the organization (company). This domain name does not necessarily have to match the organization's website.",
                "type": "string"
              },
              "type": {
                "description": "The type for this organization (company). The type field can be very useful to classify traffic. For instance, traffic type hosting is often associated with VPN or Proxy traffic or automated threats. The following types exist: hosting , education , government , banking , isp and business . hosting - a hosting provider (Example: 37.148.167.137 ) education - a university or other kind of educational institution (Example: 128.146.65.112 ) government - a governmental institution (Example: 192.91.184.0 ) banking - a banking / financial institution (Example: 199.67.175.0 ) isp - an Internet Service Provider (Example: 108.15.237.36 ) business - the generic type, used when none of the above apply (Example: 17.133.85.230 )",
                "type": "string"
              },
              "network": {
                "description": "The network for which the organization (company) has ownership. The queried IP address is always part of the IP range in the network field.",
                "type": "string"
              },
              "netname": {
                "description": "The network name as registered in the WHOIS record &mdash; the NetName field for ARIN records and the netname field for RIPE / APNIC / AFRINIC records. Examples: CC-17 , AMAZO-4 , TDC-BREDBAANDSADSL-PROF-NET , HINET-NET . Unlike company.name , the netname is a per-network identifier. Two networks belonging to the same organization can therefore have different netname values, which makes it useful for distinguishing customer sub-allocations within a single org. Returned as null for LACNIC-administered space (which has no equivalent field) and for any record that did not expose a netname.",
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "abuse": {
            "description": "The abuse object contains abuse information about the organization that owns the queried IP address. Most IP addresses can be associated with an organization or company. The API uses WHOIS information to infer which organization is the administrative owner of the queried IP address. The data provided in the abuse object helps to get in touch by phone or email with the organization responsible for a certain IP network. The abuse data always refers to the same network that is specified in the company.network field.",
            "type": "object",
            "properties": {
              "name": {
                "description": "The abuse contact name, the name of the identity that receives abuse complains about the network provided in company.network . The abuse contact name is mostly the same name as in company.name .",
                "type": "string"
              },
              "address": {
                "description": "The abuse contact address. This is the physical address of abuse contact of the entity that owns the network specified in company.network .",
                "type": "string"
              },
              "email": {
                "description": "The abuse contact email. This email address takes abuse complains about incidents associated with the network specified in company.network .",
                "type": "string"
              },
              "phone": {
                "description": "The abuse contact phone number. This phone number takes abuse complains about incidents associated with the network specified in company.network .",
                "type": "string"
              }
            }
          },
          "asn": {
            "description": "Most IP addresses can be associated with an Autonomous System (AS). An Autonomous System is a set of IP networks and routers under the control of a single organization that presents a consistent view of the Internet to other networks. Similar to the company object, the core data to populate the asn object originates from WHOIS data.",
            "type": "object",
            "properties": {
              "asn": {
                "description": "The ASN number. An ASN (Autonomous System Number) is a unique identifier assigned to an Autonomous System (AS) on the Internet. There are two types of ASNs: 2-byte ASNs: These are 16-bit ASNs, ranging from 1 to 65,535. 4-byte ASNs: These are 32-bit ASNs, ranging from 65,536 to 4,294,967,295. They were introduced to accommodate the growing number of Autonomous Systems on the Internet.",
                "type": "integer"
              },
              "abuser_score": {
                "description": "The field abuser_score represents the quota of abusive IP addresses in all routes of the ASN. The higher this number is, the more abusive the whole ASN is. abuser_score = Number of Abusive IPs / Number of Total IPs in all routes of the ASN The following score classifications are made: Very High - More than 20% of all IPs of the ASN are abusive High - Between 3% to 20% of all IPs of the ASN are abusive Elevated - Between 0.85% to 3% of all IPs of the ASN are abusive Low - Between 0.85% to 0.05% of all IPs of the ASN are abusive Very Low - Less than 0.05% of all IPs of the ASN are abusive",
                "type": "string"
              },
              "route": {
                "description": "The IP route (prefix) in CIDR network format for the queried IP address. The queried IP address is always contained in the network of the route field. If this is not the case, the asn object is not present.",
                "type": "string"
              },
              "descr": {
                "description": "An informational description for the AS.",
                "type": "string"
              },
              "country": {
                "description": "The origin country of the AS (administratively) as taken from the WHOIS record. The queried IP address does not necessarily have to be in the same country as this field suggests.",
                "type": "string"
              },
              "active": {
                "description": "Whether the AS is active. Active means that there is at least one route administered by the AS. The Internet consists of roughly ~85,000 active ASN's and ~300,000 inactive ASN's.",
                "type": "boolean"
              },
              "org": {
                "description": "The organization (Based on WHOIS data) responsible for this AS. The org field from the asn object does not necessarily have to match the org field from the company object.",
                "type": "string"
              },
              "domain": {
                "description": "The domain of the organization to which this AS belongs.",
                "type": "string"
              },
              "abuse": {
                "description": "The email address to which abuse complaints for this organization should be sent (Based on WHOIS data)",
                "type": "string"
              },
              "type": {
                "description": "The type for this ASN. The following types exist: hosting , education , government , banking , isp and business . hosting - a hosting provider (Example: 37.148.167.137 ) education - a university or other kind of educational institution (Example: 128.146.65.112 ) government - a governmental institution (Example: 192.91.184.0 ) banking - a banking / financial institution (Example: 199.67.175.0 ) isp - an Internet Service Provider (Example: 108.15.237.36 ) business - the generic type, used when none of the above apply (Example: 17.133.85.230 )",
                "type": "string"
              },
              "created": {
                "description": "When the ASN was first created (Based on WHOIS data). The format for this field is YYYY-MM-DD. Example: 2002-09-10 .",
                "type": "string"
              },
              "updated": {
                "description": "The last time the ASN was updated (Based on WHOIS data). The format for this field is YYYY-MM-DD. Example: 2023-10-30 .",
                "type": "string"
              },
              "rir": {
                "description": "To which Regional Internet Registry (RIR) the ASN belongs administratively.",
                "type": "string"
              }
            }
          },
          "location": {
            "description": "The API provides geolocation information for the queried IP address in the location object. A proprietary geolocation database was built from scratch in order to source the location object. IP Geolocation is not always accurate . Country level accuracy is good, city level accuracy is not always fulfilled.",
            "type": "object",
            "properties": {
              "is_eu_member": {
                "description": "The field is_eu_member is a boolean value that indicates whether the queried IP address is located in an EU member country. For example, the field will be true for the IP address 146.241.45.176 (Italy) and false for the IP address 208.2.79.98 (United States).",
                "type": "boolean"
              },
              "calling_code": {
                "description": "The field calling_code contains the calling code for the country of the queried IP address. For example, the calling code for the United States is 1 .",
                "type": "string"
              },
              "currency_code": {
                "description": "The field currency_code contains the currency code for the country of the queried IP address. For example, the currency code for the United States is USD .",
                "type": "string"
              },
              "continent": {
                "description": "The continent as two letter code such as NA for North America or EU for Europe.",
                "type": "string"
              },
              "country": {
                "description": "The full name of the country in which the queried IP address is located. Country level accuracy for IP geolocation is in more than 90% of the cases correct. IP Geolocation accuracy is constantly improved.",
                "type": "string"
              },
              "country_code": {
                "description": "The ISO 3166-1 alpha-2 country code to which the IP address belongs. This is the country specific geolocation of the IP address.",
                "type": "string"
              },
              "state": {
                "description": "The state / administrative area of the queried IP address. The free (keyless) response returns the same value under the name region .",
                "type": "string"
              },
              "city": {
                "description": "The city to which the IP address belongs geographically. City level IP geolocation is accurate in roughly 70% of the cases. IP Geolocation accuracy is constantly improved.",
                "type": "string"
              },
              "latitude": {
                "description": "The geographical latitude for the queried IP address. The latitude gives a rough estimate where the IP is located and it's value should not be interpreted as an accurate location.",
                "type": "number"
              },
              "longitude": {
                "description": "The geographical longitude for the queried IP address. The longitude gives a rough estimate where the IP is located and it's value should not be interpreted as an accurate location.",
                "type": "number"
              },
              "zip": {
                "description": "The zip code for the queried IP address.",
                "type": "string"
              },
              "timezone": {
                "description": "The timezone of the queried IP address. The timezone is derived from latitude and longitude.",
                "type": "string"
              },
              "utcoffset": {
                "description": "The current UTC offset for the queried IP address's timezone in ISO-8601 ±HH:MM format. Examples: \"+02:00\" , \"-05:00\" , \"+05:30\" . The offset is DST-aware &mdash; it already reflects daylight saving time when applicable, so it matches the offset embedded in local_time .",
                "type": "string"
              },
              "accuracy": {
                "description": "An estimate of how accurate the geolocation is for the queried IP address. One of: VERY_HIGH , HIGH , MEDIUM , LOW , VERY_LOW . VERY_HIGH typically means the location was sourced from an authoritative signal such as an ISP-published RFC 8805 geofeed , or that several independent geolocation providers agree. Lower values indicate that less authoritative sources were used or that providers disagree. Pass ?geoloc_meta=1 on your API request to additionally get the actual geofeed URL(s) that contributed to the geolocation in a geofeed array on the location object.",
                "type": "string"
              }
            }
          },
          "egress_service": {
            "description": "The egress_service object is present when the address is an egress point of a large privacy or enterprise network service rather than an ordinary end-user or server address &mdash; Apple iCloud Private Relay, Cloudflare WARP, corporate secure web gateways and the like. These addresses look like datacenter addresses but carry real end-user traffic, so blocking them blocks customers. Treat them differently from generic hosting ranges.",
            "type": "object",
            "properties": {
              "type": {
                "description": "What kind of egress service the address belongs to, e.g. \"privacy_relay\" or \"secure_web_gateway\" .",
                "type": "string"
              },
              "provider": {
                "description": "The company operating the egress service, e.g. \"Apple\" , \"Cloudflare\" or \"Google\" .",
                "type": "string"
              }
            }
          },
          "vpn": {
            "description": "The vpn object is only present if the queried IP address belongs to a VPN exit node. The vpn object contains meta information of the VPN exit node. The format of the vpn object is as follows (Example IP: 185.254.75.34 ): is_vpn - boolean - Whether the IP address is a VPN exit node. This is the same as the is_vpn field. region - string - The region of the VPN exit node. It is in free format. last_seen - number - The unix timestamp in milliseconds of the last time the VPN exit node was enumerated. type - string - The type of the VPN exit node. This is either \"exit_node\" or \"vpn_server\" . The value \"exit_node\" is most common and means that the IP address is a VPN exit node that was detected by our VPN enumeration system. The value \"vpn_server\" is less common and means that the IP address is a VPN server known to belong to the VPN service. service - string - The name of the VPN service. url - string - The url of the VPN service.",
            "type": "object",
            "properties": {
              "ip": {
                "description": "The exit node's own IP address, i.e. the address this vpn record was enumerated for. It matches the queried address.",
                "type": "string"
              },
              "service": {
                "description": "The service field of the vpn object contains the name of the VPN service. Example: MullvadVPN",
                "type": "string"
              },
              "url": {
                "description": "The url field of the vpn object contains the url of the VPN service. Example: https://mullvad.net",
                "type": "string"
              },
              "type": {
                "description": "The type field of the vpn object contains the type of the VPN exit node. This is either \"exit_node\" or \"vpn_server\" . The value \"exit_node\" is most common and means that the IP address is a VPN exit node that was detected by our VPN enumeration system. The value \"vpn_server\" is less common and means that the IP address is a VPN server known to belong to the VPN service.",
                "type": "string"
              },
              "last_seen": {
                "description": "The last_seen field of the vpn object contains the unix timestamp in milliseconds of the last time the VPN exit node was enumerated.",
                "type": "number"
              },
              "last_seen_str": {
                "description": "The last_seen_str field of the vpn object contains the last seen date in human readable format. Example: \"2025-02-16T18:47:16.907Z\"",
                "type": "string"
              },
              "exit_node_region": {
                "description": "The exit_node_region field of the vpn object contains the region of the VPN exit node. It is in free format.",
                "type": "string"
              },
              "hostname": {
                "description": "The hostname field of the vpn object contains the hostname associated with the IP address. Example: us-nyc-ovpn-603",
                "type": "string"
              },
              "country_code": {
                "description": "The country_code field of the vpn object contains the ISO 3166-1 alpha-2 two-letter country code where the VPN exit node is located. Example: us",
                "type": "string"
              },
              "city_name": {
                "description": "The city_name field of the vpn object contains the name of the city where the VPN exit node is located. Example: New York",
                "type": "string"
              },
              "latitude": {
                "description": "The latitude field of the vpn object contains the latitude of the VPN exit node's location. Example: 40.71427",
                "type": [
                  "number",
                  "null"
                ]
              },
              "longitude": {
                "description": "The longitude field of the vpn object contains the longitude of the VPN exit node's location. Example: -74.00597",
                "type": [
                  "number",
                  "null"
                ]
              },
              "is_vpn": {
                "description": "The field is_vpn is part of the vpn object and is true , if the IP address belongs to a VPN exit node.",
                "type": "boolean"
              }
            }
          },
          "elapsed_ms": {
            "description": "The field elapsed_ms provides the amount of time in milliseconds (ms) the API took to process the API query. It measures database lookups plus post-processing on the server and is independent of network / round-trip latency. On average, IP lookups on ipapi.is take around 1.2ms of processing time. This fast lookup time is achieved by storing the full IP address database in memory and optimizing lookups by using a fast proprietary lookup algorithm.",
            "type": "number"
          }
        }
      },
      "AsnResponse": {
        "type": "object",
        "properties": {
          "asn": {
            "description": "An ASN (Autonomous System Number) is a unique identifier assigned to an Autonomous System on the Internet: a set of IP networks and routers under the control of a single organization. As of 2024, over 81,000 ASNs were actively announcing routes. In the free (keyless) response , asn is one string holding the number and its operator, the way an ASN is written by hand: \"AS12322 Free SAS\" . It degrades to \"AS12322\" when no operator name is known, and is null when the address announces no route. Requests with an API key get an asn object instead, which splits that string into asn and org and adds the announced route , the registry metadata and an abuser_score . Querying an ASN directly ( ?q=AS15169 ) also requires a key, and returns asn as the bare number. There are two types of ASNs: 2-byte ASNs: 16-bit, ranging from 1 to 65,535. 4-byte ASNs: 32-bit, ranging from 65,536 to 4,294,967,295. They were introduced to accommodate the growing number of Autonomous Systems on the Internet.",
            "type": "integer"
          },
          "abuser_score": {
            "description": "The field abuser_score represents the quota of abusive IP addresses in all routes of the ASN. The higher this number is, the more abusive the whole ASN is. abuser_score = Number of Abusive IPs / Number of Total IPs in all routes of the ASN The following score classifications are made: Very High - More than 20% of all IPs of the ASN are abusive High - Between 3% to 20% of all IPs of the ASN are abusive Elevated - Between 0.85% to 3% of all IPs of the ASN are abusive Low - Between 0.85% to 0.05% of all IPs of the ASN are abusive Very Low - Less than 0.05% of all IPs of the ASN are abusive",
            "type": "string"
          },
          "descr": {
            "description": "The field descr is a short description / name of the autonomous system (AS) in free format.",
            "type": "string"
          },
          "country": {
            "description": "In the free (keyless) response , country is the full name of the country the IP address is located in &mdash; \"France\" , \"United States\" . That is the same value the keyed response returns as location.country , which also carries the ISO 3166-1 alpha-2 country_code , the continent and EU membership. Country level accuracy for IP geolocation is correct in more than 90% of cases. In an ASN query response ( ?q=AS15169 , which needs an API key) the top-level country means something different: the ISO 3166-1 alpha-2 country code the AS belongs to administratively . Routes announced by an AS do not have to originate from the country it is registered in.",
            "type": "string"
          },
          "active": {
            "description": "The field active determines if the ASN is active or inactive. Active means that at least one route is assigned to the ASN. Put differently, this means that there is at least one entry in the prefixes or prefixesIPv6 array. The Internet consists of roughly ~85,000 active ASN's and ~300,000 inactive ASN's.",
            "type": "boolean"
          },
          "org": {
            "description": "The field org contains the organization that owns the ASN. It is crucial to understand that not every IP address assigned to an AS must belong to this organization. Put differently: IP addresses assigned via routes/prefixes to an ASN might be owned by a different organization than the one from the autonomous system (AS).",
            "type": "string"
          },
          "domain": {
            "description": "The field domain contains the domain of the organization's website that owns the ASN.",
            "type": "string"
          },
          "abuse": {
            "description": "The field abuse contains the email address used to direct abuse complains to the owner of this ASN.",
            "type": "string"
          },
          "type": {
            "description": "The field type contains the type of the ASN. The following types exist: hosting , education , government , banking , isp and business . hosting - a hosting provider (Example: 37.148.167.137 ) education - a university or other kind of educational institution (Example: 128.146.65.112 ) government - a governmental institution (Example: 192.91.184.0 ) banking - a banking / financial institution (Example: 199.67.175.0 ) isp - an Internet Service Provider (Example: 108.15.237.36 ) business - the generic type, used when none of the above apply (Example: 17.133.85.230 )",
            "type": "string"
          },
          "created": {
            "description": "The field created specifies the date the Autonomous System was first registered. The format is YYYY-MM-DD. Example: 2002-09-10 .",
            "type": "string"
          },
          "updated": {
            "description": "The field updated specifies the date the Autonomous System was last updated. The format is YYYY-MM-DD. Example: 2023-10-30 .",
            "type": "string"
          },
          "rir": {
            "description": "The field rir specifies the Regional Internet Registry (RIR) that is authoritative for the queried IP address. There are five major RIRs for different areas of the world: ARIN (American Registry for Internet Numbers) RIPE NCC (Réseaux IP Européens Network Coordination Centre) APNIC (Asia-Pacific Network Information Centre) AFRINIC (African Network Information Centre) LACNIC (Latin American and Caribbean Internet Addresses Registry) Less-Known RIRs: TWNIC (Taiwan Network Information Center) CNNIC (China Internet Network Information Center) KRNIC (Korea Network Information Center) JPNIC (Japan Network Information Center)",
            "type": "string"
          },
          "prefixes": {
            "description": "The array prefixes contains all the IPv4 networks assigned to this ASN. This is an array of IPv4 networks in CIDR format.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "prefixesIPv6": {
            "description": "The array prefixesIPv6 contains all the IPv6 networks assigned to this ASN. This is an array of IPv6 networks in CIDR format.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "FreeTierResponse": {
        "type": "object",
        "description": "What a request without a key gets: ownership and location only, every field present and null when unknown. https://ipapi.is/free-tier.html",
        "properties": {
          "ip": {
            "description": "The field ip contains the IP address that was queried. You may query any IPv4 or IPv6 address by specifying the q= parameter: https://api.ipapi.is/?q=199.59.148.0 If no IP address was specified (Example: https://api.ipapi.is ), the client's own IP address is looked up and ip is set to the client's public IP address. If the API is used in that way, it acts in the same way as for example https://icanhazip.com , just with more meta data.",
            "type": [
              "string",
              "null"
            ]
          },
          "is_bogon": {
            "description": "The field is_bogon determines if the queried IP address is bogon. Bogon IP addresses are not routable and thus not a part of the public Internet. Bogon IP addresses are not assigned / allocated to IANA or any other Regional Internet Registry. For example, the following IP addresses are bogon: 192.0.2.1 198.51.100.254 203.0.113.15 In general, there is no good reason to query bogon IP addresses, since they have no purpose in the public Internet. Nobody owns a bogon address and it is nowhere, so when is_bogon is true every ownership and geolocation field of the response is null .",
            "type": [
              "boolean",
              "null"
            ]
          },
          "company": {
            "description": "In the free (keyless) response , company is a plain string: the name of the organisation that owns the queried IP address, taken from its WHOIS record. Example: \"Proxad / Free SAS\" . Requests that carry an API key get an object instead, with the organisation's name , domain , type (hosting / isp / education / government / banking / business), the exact network it owns, the WHOIS netname and an abuser_score for that network. An address can be covered by more than one WHOIS record. The keyless response always reports the most specific one; with a key you can ask for all of them with all_companies=1 . null when the address is bogon or has no WHOIS record.",
            "type": [
              "string",
              "null"
            ]
          },
          "asn": {
            "description": "An ASN (Autonomous System Number) is a unique identifier assigned to an Autonomous System on the Internet: a set of IP networks and routers under the control of a single organization. As of 2024, over 81,000 ASNs were actively announcing routes. In the free (keyless) response , asn is one string holding the number and its operator, the way an ASN is written by hand: \"AS12322 Free SAS\" . It degrades to \"AS12322\" when no operator name is known, and is null when the address announces no route. Requests with an API key get an asn object instead, which splits that string into asn and org and adds the announced route , the registry metadata and an abuser_score . Querying an ASN directly ( ?q=AS15169 ) also requires a key, and returns asn as the bare number. There are two types of ASNs: 2-byte ASNs: 16-bit, ranging from 1 to 65,535. 4-byte ASNs: 32-bit, ranging from 65,536 to 4,294,967,295. They were introduced to accommodate the growing number of Autonomous Systems on the Internet.",
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "description": "The city the queried IP address is located in. Identical to location.city in the keyed response. City level IP geolocation is accurate in roughly 70% of the cases and is not a precise location . Accuracy is constantly improved. This field is part of the free (keyless) response . Requests that carry an API key get the full response instead, where this value lives in the location object alongside the postal code, continent, calling code, currency, DST state and an accuracy estimate.",
            "type": [
              "string",
              "null"
            ]
          },
          "region": {
            "description": "The state or administrative area the queried IP address is located in &mdash; \"Brittany\" , \"California\" , \"Bavaria\" . The keyed response calls the same value location.state . It is named region here because that is what the rest of the industry calls it in a flat geolocation body. This field is part of the free (keyless) response . Requests that carry an API key get the full response instead, where this value lives in the location object alongside the postal code, continent, calling code, currency, DST state and an accuracy estimate.",
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "description": "In the free (keyless) response , country is the full name of the country the IP address is located in &mdash; \"France\" , \"United States\" . That is the same value the keyed response returns as location.country , which also carries the ISO 3166-1 alpha-2 country_code , the continent and EU membership. Country level accuracy for IP geolocation is correct in more than 90% of cases. In an ASN query response ( ?q=AS15169 , which needs an API key) the top-level country means something different: the ISO 3166-1 alpha-2 country code the AS belongs to administratively . Routes announced by an AS do not have to originate from the country it is registered in.",
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "description": "The geographical latitude of the queried IP address. Identical to location.latitude in the keyed response. Latitude and longitude are a rough estimate of where the address is and should not be read as a precise position. They usually point at the centre of the city or region, not at a street address, and no IP geolocation database can do better than that. This field is part of the free (keyless) response . Requests that carry an API key get the full response instead, where this value lives in the location object alongside the postal code, continent, calling code, currency, DST state and an accuracy estimate.",
            "type": [
              "number",
              "null"
            ]
          },
          "lon": {
            "description": "The geographical longitude of the queried IP address. Identical to location.longitude in the keyed response. Latitude and longitude are a rough estimate of where the address is and should not be read as a precise position. They usually point at the centre of the city or region, not at a street address, and no IP geolocation database can do better than that. This field is part of the free (keyless) response . Requests that carry an API key get the full response instead, where this value lives in the location object alongside the postal code, continent, calling code, currency, DST state and an accuracy estimate.",
            "type": [
              "number",
              "null"
            ]
          },
          "timezone": {
            "description": "The IANA time zone of the queried IP address, derived from its latitude and longitude. Example: \"Europe/Paris\" . Only the zone identifier is returned here. The keyed response additionally resolves it into location.local_time , location.local_time_unix , location.utcoffset and location.is_dst . This field is part of the free (keyless) response . Requests that carry an API key get the full response instead, where this value lives in the location object alongside the postal code, continent, calling code, currency, DST state and an accuracy estimate.",
            "type": [
              "string",
              "null"
            ]
          },
          "docs": {
            "description": "A link to the free-tier documentation . It is present whenever a request carried no API key, and it is the only field in that response that is not data. It is there because the keyless response is about a fifth the size of the documented one, with no other indication that anything was withheld. The shape alone cannot tell you whether a field is missing because we have no data for that address or because the request had no key &mdash; opposite conclusions, and only one of them is something you can fix. Detection flags ( is_datacenter , is_vpn , is_proxy , is_tor , is_abuser ), the nested company , asn , location and abuse objects, bulk lookups and ASN queries all require a key.",
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "error_code": {
            "type": "string",
            "description": "Stable; branch on it, not on the message"
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "suspended": {
            "type": "boolean"
          },
          "plan": {
            "type": "string",
            "description": "free, or the plan key such as 20"
          },
          "planName": {
            "type": [
              "string",
              "null"
            ]
          },
          "dailyLimit": {
            "type": "integer"
          },
          "usedToday": {
            "type": "integer",
            "description": "Resets at 00:00 UTC"
          },
          "credits": {
            "type": "integer"
          },
          "creditsUsed": {
            "type": "integer"
          },
          "databases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "dailyUsage": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "day": {
                  "type": "string",
                  "format": "date"
                },
                "requests": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "provider": {
            "type": "string",
            "enum": [
              "stripe",
              "paypal"
            ]
          },
          "product": {
            "type": "string",
            "description": "The plan key (such as 20) or the database (such as ipToVpn)"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "amount": {
            "type": "number",
            "description": "Price per interval, before tax"
          },
          "currency": {
            "type": "string"
          },
          "interval": {
            "type": "string",
            "enum": [
              "month",
              "year"
            ]
          },
          "renewsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "endsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Set once cancelled: access ends then"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "invoiceNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "amount": {
            "type": "number"
          },
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "refund": {
            "type": "boolean"
          },
          "url": {
            "type": "string",
            "description": "Add ?key= to download the PDF"
          }
        }
      },
      "DatabaseFile": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "The type parameter of the download"
          },
          "format": {
            "type": "string",
            "description": "Missing for the Business downloads"
          },
          "name": {
            "type": "string"
          },
          "file": {
            "type": "string"
          },
          "released": {
            "type": "string",
            "format": "date"
          },
          "bytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "url": {
            "type": "string",
            "description": "Add &key= to download"
          }
        }
      }
    }
  }
}