{
  "openapi": "3.1.0",
  "info": {
    "title": "CheckIP.me Simple API",
    "version": "1.0.1",
    "summary": "What is my IP, plus IP geolocation and proxy/VPN/Tor detection as flat JSON or plain text.",
    "description": "Get your public IP, or look up any public IPv4/IPv6 address, as flat JSON with fixed field names or as a single plain-text field. Made for terminals, scripts and lightweight integrations.\n\nNo sign-up and no API key. Looking up your own IP is unlimited; lookups of other IPs are limited to 120 per hour per client (shared with api.checkip.me). Recently looked-up IPs are served from cache, do not count against the limit, and can be up to 30 days old.\n\nRequests that send `Accept: text/html` (web browsers navigating to the page) get the website instead of JSON; API clients should send `Accept: application/json` or `*/*`. Paths that are neither an IP address nor a known field return the website's HTML 404 page.\n\nFor every available field (VPN operator details, attack history, detection history, device estimates) as nested JSON, see the Full API at https://api.checkip.me/openapi.json.",
    "termsOfService": "https://checkip.me/api",
    "contact": {
      "name": "CheckIP.me",
      "url": "https://checkip.me"
    }
  },
  "externalDocs": {
    "description": "Documentation and code examples",
    "url": "https://checkip.me/api"
  },
  "security": [],
  "servers": [
    {
      "url": "https://checkip.me"
    }
  ],
  "tags": [
    {
      "name": "My IP",
      "description": "The caller's own IP address"
    },
    {
      "name": "Lookup",
      "description": "Any IP address"
    }
  ],
  "paths": {
    "/ip": {
      "get": {
        "tags": ["My IP"],
        "operationId": "getMyIp",
        "summary": "Get the caller's public IP as plain text",
        "description": "Returns only the caller's public IP address. Not rate limited. `curl checkip.me` returns the same in a terminal.",
        "responses": {
          "200": {
            "description": "The caller's IP address.",
            "content": {
              "text/plain": {
                "schema": { "type": "string" },
                "example": "203.0.113.42"
              }
            }
          }
        }
      }
    },
    "/json": {
      "get": {
        "tags": ["My IP"],
        "operationId": "getMyIpDetails",
        "summary": "Get details for the caller's public IP",
        "description": "Returns location, network and risk signals for the caller's own IP. Not rate limited.",
        "responses": {
          "200": {
            "description": "Details for the caller's IP.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/IPInfo" }
              }
            }
          },
          "502": { "$ref": "#/components/responses/UpstreamError" }
        }
      }
    },
    "/{ip}": {
      "get": {
        "tags": ["Lookup"],
        "operationId": "lookupIp",
        "summary": "Look up any IP address",
        "description": "Returns location, network owner, connection type and proxy/VPN/Tor/hosting detection for a public IPv4 or IPv6 address, as flat JSON.",
        "parameters": [
          { "$ref": "#/components/parameters/Ip" }
        ],
        "responses": {
          "200": {
            "description": "Details for the IP.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/IPInfo" },
                "example": {
                  "ip": "8.8.8.8",
                  "hostname": "dns.google",
                  "asn": "AS15169",
                  "isp": "Google LLC",
                  "organisation": "Level 3",
                  "type": "Business",
                  "range": "8.8.8.0/24",
                  "continent": "North America",
                  "country": "United States",
                  "country_code": "US",
                  "region": "California",
                  "region_code": "CA",
                  "city": "Mountain View",
                  "postal_code": "94043",
                  "latitude": 37.422,
                  "longitude": -122.085,
                  "timezone": "America/Los_Angeles",
                  "currency": "USD",
                  "proxy": false,
                  "vpn": false,
                  "tor": false,
                  "hosting": false,
                  "compromised": false,
                  "scraper": false,
                  "anonymous": true,
                  "risk": 100,
                  "operator": null,
                  "docs": "https://checkip.me/api"
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/InvalidIp" },
          "422": { "$ref": "#/components/responses/PrivateIp" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/UpstreamError" }
        }
      }
    },
    "/{ip}/{field}": {
      "get": {
        "tags": ["Lookup"],
        "operationId": "lookupIpField",
        "summary": "Get one field for any IP as plain text",
        "description": "Returns a single field as plain text, for example `true`/`false` for vpn, or `United States` for country. Handy in shell scripts. The same field names also work for the caller's own IP, for example checkip.me/country.",
        "parameters": [
          { "$ref": "#/components/parameters/Ip" },
          {
            "name": "field",
            "in": "path",
            "required": true,
            "description": "Name of the field to return.",
            "schema": { "$ref": "#/components/schemas/FieldName" },
            "example": "vpn"
          }
        ],
        "responses": {
          "200": {
            "description": "The field value. Booleans are `true` or `false`; unknown values are empty.",
            "content": {
              "text/plain": {
                "schema": { "type": "string" },
                "example": "false"
              }
            }
          },
          "404": { "$ref": "#/components/responses/InvalidIpOrField" },
          "422": { "$ref": "#/components/responses/PrivateIpText" },
          "429": { "$ref": "#/components/responses/RateLimitedText" },
          "502": { "$ref": "#/components/responses/UpstreamErrorText" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "Ip": {
        "name": "ip",
        "in": "path",
        "required": true,
        "description": "A public IPv4 or IPv6 address.",
        "schema": {
          "type": "string",
          "examples": ["8.8.8.8", "2001:4860:4860::8888"]
        },
        "example": "8.8.8.8"
      }
    },
    "responses": {
      "InvalidIp": {
        "description": "The value is not a valid IPv4 or IPv6 address.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": {
              "ip": "999.1.1.1",
              "error": "That is not a valid IPv4 or IPv6 address."
            }
          }
        }
      },
      "InvalidIpOrField": {
        "description": "The IP address is not valid, or the field name is unknown.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "examples": {
              "invalid-ip": {
                "summary": "Invalid IP address",
                "value": {
                  "ip": "999.1.1.1",
                  "error": "That is not a valid IPv4 or IPv6 address."
                }
              },
              "unknown-field": {
                "summary": "Unknown field",
                "value": {
                  "ip": "8.8.8.8",
                  "error": "Unknown field. See https://checkip.me/help for the list of fields."
                }
              }
            }
          }
        }
      },
      "PrivateIpText": {
        "description": "The address is private or reserved, so no public data exists for it. Plain-text error.",
        "content": {
          "text/plain": {
            "schema": { "$ref": "#/components/schemas/TextError" },
            "example": "Error: This is a private or reserved IP address. No public data is available for it."
          }
        }
      },
      "RateLimitedText": {
        "description": "Too many lookups of other IPs (limit: 120 per hour per client). Wait for the number of seconds in Retry-After. Plain-text error.",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before retrying.",
            "schema": { "type": "integer", "minimum": 0 }
          }
        },
        "content": {
          "text/plain": {
            "schema": { "$ref": "#/components/schemas/TextError" }
          }
        }
      },
      "UpstreamErrorText": {
        "description": "The data source did not respond. Try again later. Plain-text error.",
        "content": {
          "text/plain": {
            "schema": { "$ref": "#/components/schemas/TextError" }
          }
        }
      },
      "PrivateIp": {
        "description": "The address is private or reserved (for example 10.x, 192.168.x, 127.x, ::1), so no public data exists for it.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": {
              "ip": "10.0.0.1",
              "error": "This is a private or reserved IP address. No public data is available for it."
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many lookups of other IPs (limit: 120 per hour per client). Wait for the number of seconds in Retry-After.",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before retrying.",
            "schema": { "type": "integer", "minimum": 0 }
          }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "UpstreamError": {
        "description": "The data source did not respond. Try again later.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      }
    },
    "schemas": {
      "IPInfo": {
        "type": "object",
        "description": "Details for one IP address. Unknown values are null.",
        "required": ["ip"],
        "properties": {
          "ip": { "type": "string", "description": "The IP address." },
          "hostname": { "type": ["string", "null"], "description": "Reverse DNS name." },
          "asn": { "type": ["string", "null"], "description": "Autonomous system number.", "examples": ["AS15169"] },
          "isp": { "type": ["string", "null"], "description": "Internet service provider." },
          "organisation": { "type": ["string", "null"], "description": "Organisation the range is registered to." },
          "type": {
            "type": ["string", "null"],
            "description": "Connection type.",
            "examples": ["Residential", "Business", "Wireless", "Hosting"]
          },
          "range": { "type": ["string", "null"], "description": "Network range in CIDR notation." },
          "continent": { "type": ["string", "null"] },
          "country": { "type": ["string", "null"] },
          "country_code": { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2 code.", "examples": ["US"] },
          "region": { "type": ["string", "null"] },
          "region_code": { "type": ["string", "null"] },
          "city": { "type": ["string", "null"] },
          "postal_code": { "type": ["string", "null"] },
          "latitude": { "type": ["number", "null"] },
          "longitude": { "type": ["number", "null"] },
          "timezone": { "type": ["string", "null"], "description": "IANA time zone." },
          "currency": { "type": ["string", "null"], "description": "ISO 4217 code.", "examples": ["USD"] },
          "proxy": { "type": "boolean", "description": "Open or commercial proxy." },
          "vpn": { "type": "boolean", "description": "VPN exit." },
          "tor": { "type": "boolean", "description": "Tor exit node." },
          "hosting": { "type": "boolean", "description": "Data center or cloud IP." },
          "compromised": { "type": "boolean", "description": "Host appears to be compromised." },
          "scraper": { "type": "boolean", "description": "Seen scraping websites." },
          "anonymous": { "type": "boolean", "description": "The IP hides the real user in some way." },
          "risk": {
            "type": ["integer", "null"],
            "minimum": 0,
            "maximum": 100,
            "description": "Risk score from 0 (clean) to 100 (very risky)."
          },
          "operator": { "type": ["string", "null"], "description": "VPN or proxy provider, when known." },
          "docs": { "type": "string", "format": "uri", "description": "Link to the documentation." }
        }
      },
      "FieldName": {
        "type": "string",
        "enum": [
          "hostname", "asn", "isp", "organisation", "type", "range",
          "continent", "country", "country_code", "region", "region_code", "city", "postal_code",
          "latitude", "longitude", "timezone", "currency",
          "proxy", "vpn", "tor", "hosting", "compromised", "scraper", "anonymous", "risk", "operator"
        ]
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "ip": { "type": "string", "description": "The value that was looked up." },
          "error": { "type": "string", "description": "Human-readable error message." }
        }
      },
      "TextError": {
        "type": "string",
        "description": "Plain-text error message starting with \"Error: \".",
        "pattern": "^Error: "
      }
    }
  }
}
