{
  "openapi": "3.1.0",
  "info": {
    "title": "IP-Info API",
    "description": "Use the IP-Info API to turn IP addresses into practical location and network intelligence for fraud checks, regional routing, analytics enrichment, and account protection.\n\nThe public API includes IP lookup, API key management, and usage reporting. IP lookup requests authenticate with an `x-api-key` header. Account and key-management requests authenticate with an `x-jwt-token` header from your IP-Info account session.\n\nResponses include customer-facing error messages and stable error codes. Credits are consumed according to your IP-Info plan; credits never expire.\n\nSupport: support@ip-info.app • Full product documentation: https://ip-info.app/open-api",
    "contact": {
      "name": "IP-INFO.APP Team",
      "url": "https://ip-info.app",
      "email": "support@ip-info.app"
    },
    "license": {
      "name": "Proprietary license",
      "url": "https://ip-info.app/terms-of-service"
    },
    "termsOfService": "https://ip-info.app/terms-of-service",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.ip-info.app",
      "description": "Production Server",
      "variables": {}
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key for IP lookup requests. Create and manage keys from your IP-Info account."
      },
      "JwtTokenAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-jwt-token",
        "description": "Account session token used for key management and usage reporting endpoints."
      }
    },
    "schemas": {
      "CreateApiKeyRequest": {
        "type": "object",
        "title": "Create API key request",
        "description": "Request body for creating an API key for your IP-Info.app account.",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Human-readable name for the key.",
            "example": "Production Key"
          },
          "services": {
            "type": "array",
            "description": "Services this key can access. For IP Info lookups, use `ip`.",
            "items": {
              "type": "string",
              "enum": ["ip"]
            },
            "example": ["ip"]
          },
          "isEnabled": {
            "type": "boolean",
            "description": "Whether the key should be usable immediately after creation.",
            "example": true
          }
        },
        "additionalProperties": true,
        "example": {
          "name": "Production Key",
          "services": ["ip"],
          "isEnabled": true
        }
      },
      "ApiKey": {
        "type": "object",
        "title": "API key",
        "description": "An API key that can authenticate requests to IP-Info.app.",
        "required": ["_id", "userId", "isEnabled", "host", "createdAt", "updatedAt"],
        "properties": {
          "_id": {
            "type": "string",
            "pattern": "^[a-fA-F0-9]{24}$",
            "description": "Unique ID for this API key.",
            "example": "507f1f77bcf86cd799439011"
          },
          "userId": {
            "type": "string",
            "pattern": "^[a-fA-F0-9]{24}$",
            "description": "Account ID that owns this API key.",
            "example": "507f1f77bcf86cd799439012"
          },
          "apiKey": {
            "type": "string",
            "description": "Secret API key value. Store it securely and avoid exposing it in client-side code.",
            "example": "507f1f77bcf86cd799439012-abc123"
          },
          "name": {
            "type": "string",
            "description": "Human-readable key name.",
            "example": "Production Key"
          },
          "environment": {
            "type": "string",
            "description": "Optional environment label for the key.",
            "example": "production"
          },
          "services": {
            "type": "array",
            "description": "Services this key can access. For IP Info lookups, use `ip`.",
            "items": {
              "type": "string",
              "enum": ["ip"]
            },
            "example": ["ip"]
          },
          "isEnabled": {
            "type": "boolean",
            "description": "Whether this key can currently authenticate requests.",
            "example": true
          },
          "host": {
            "type": "string",
            "description": "Product host associated with the key.",
            "example": "ip-info.app"
          },
          "note": {
            "type": "string",
            "description": "Optional note for your team.",
            "example": "Used by production workload"
          },
          "meta": {
            "type": "object",
            "nullable": true,
            "description": "Additional metadata captured when the key was created or updated.",
            "additionalProperties": true,
            "example": {
              "reqIpAddress": "127.0.0.1"
            }
          },
          "createdAt": {
            "type": "string",
            "description": "Creation timestamp in ISO 8601 format.",
            "example": "2025-01-01T12:00:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "description": "Last update timestamp in ISO 8601 format.",
            "example": "2025-01-01T12:00:00.000Z"
          }
        },
        "example": {
          "_id": "507f1f77bcf86cd799439011",
          "userId": "507f1f77bcf86cd799439012",
          "apiKey": "507f1f77bcf86cd799439012-abc123",
          "name": "Production Key",
          "environment": "production",
          "services": ["ip"],
          "isEnabled": true,
          "host": "ip-info.app",
          "note": "Used by production workload",
          "meta": {
            "reqIpAddress": "127.0.0.1"
          },
          "createdAt": "2025-01-01T12:00:00.000Z",
          "updatedAt": "2025-01-01T12:00:00.000Z"
        }
      },
      "DeleteApiKeyRequest": {
        "type": "object",
        "title": "Delete API key request",
        "description": "Request body for deleting an API key from your account.",
        "required": ["_id"],
        "properties": {
          "_id": {
            "type": "string",
            "pattern": "^[a-fA-F0-9]{24}$",
            "description": "ID of the API key to delete.",
            "example": "507f1f77bcf86cd799439011"
          }
        },
        "additionalProperties": true,
        "example": {
          "_id": "507f1f77bcf86cd799439011"
        }
      },
      "DeleteApiKeyResponse": {
        "type": "object",
        "title": "Delete API key response",
        "description": "Confirms that the API key was deleted.",
        "required": ["success"],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the key was deleted.",
            "example": true
          }
        },
        "example": {
          "success": true
        }
      },
      "GetApiKeyRequest": {
        "type": "object",
        "title": "Get API key request",
        "description": "Request body for retrieving one API key by ID.",
        "required": ["_id"],
        "properties": {
          "_id": {
            "type": "string",
            "pattern": "^[a-fA-F0-9]{24}$",
            "description": "ID of the API key to retrieve.",
            "example": "507f1f77bcf86cd799439011"
          }
        },
        "additionalProperties": true,
        "example": {
          "_id": "507f1f77bcf86cd799439011"
        }
      },
      "ListApiKeysRequest": {
        "type": "object",
        "title": "List API keys request",
        "description": "Optional request body for listing API keys in your account.",
        "properties": {},
        "additionalProperties": true,
        "example": {}
      },
      "ListApiKeysResponse": {
        "type": "object",
        "title": "List API keys response",
        "description": "API keys available in your account.",
        "required": ["list"],
        "properties": {
          "list": {
            "type": "array",
            "description": "API keys returned for the account.",
            "items": {
              "$ref": "#/components/schemas/ApiKey"
            }
          }
        },
        "example": {
          "list": [
            {
              "_id": "507f1f77bcf86cd799439011",
              "userId": "507f1f77bcf86cd799439012",
              "apiKey": "507f1f77bcf86cd799439012-abc123",
              "name": "Production Key",
              "environment": "production",
              "services": ["ip"],
              "isEnabled": true,
              "host": "ip-info.app",
              "note": "Used by production workload",
              "meta": {
                "reqIpAddress": "127.0.0.1"
              },
              "createdAt": "2025-01-01T12:00:00.000Z",
              "updatedAt": "2025-01-01T12:00:00.000Z"
            }
          ]
        }
      },
      "UpdateApiKeyRequest": {
        "type": "object",
        "title": "Update API key request",
        "description": "Request body for changing an API key name, enabled state, environment, or service access.",
        "required": ["_id"],
        "properties": {
          "_id": {
            "type": "string",
            "pattern": "^[a-fA-F0-9]{24}$",
            "description": "ID of the API key to update.",
            "example": "507f1f77bcf86cd799439011"
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Updated display name for the key.",
            "example": "Production Key"
          },
          "environment": {
            "type": "string",
            "description": "Optional environment label for the key.",
            "example": "production"
          },
          "services": {
            "type": "array",
            "description": "Services this key can access. For IP Info lookups, use `ip`.",
            "items": {
              "type": "string",
              "enum": ["ip"]
            },
            "example": ["ip"]
          },
          "isEnabled": {
            "type": "boolean",
            "description": "Whether this key should be enabled.",
            "example": true
          }
        },
        "additionalProperties": true,
        "example": {
          "_id": "507f1f77bcf86cd799439011",
          "name": "Production Key",
          "services": ["ip"],
          "isEnabled": true
        }
      },
      "ApiKeyIdentity": {
        "type": "object",
        "title": "Current credential identity",
        "description": "Account and request context associated with the credential used for the request.",
        "properties": {
          "userId": {
            "type": "string",
            "nullable": true,
            "description": "Account ID associated with the credential."
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "Account email address, when available."
          },
          "username": {
            "type": "string",
            "nullable": true,
            "description": "Account username, when available."
          },
          "reqIpAddress": {
            "type": "string",
            "nullable": true,
            "description": "IP address seen by the API for this request."
          },
          "reqIpCountry": {
            "type": "string",
            "nullable": true,
            "description": "Country inferred from the request IP address."
          },
          "reqUserAgent": {
            "type": "string",
            "nullable": true,
            "description": "User agent sent with this request."
          }
        },
        "example": {
          "userId": "507f1f77bcf86cd799439012",
          "email": "developer@example.com",
          "username": "developer",
          "reqIpAddress": "203.0.113.10",
          "reqIpCountry": "US",
          "reqUserAgent": "curl/8.7.1"
        }
      },
      "ApiUsageExport": {
        "type": "object",
        "title": "API usage export",
        "description": "Download metadata for an exported usage report.",
        "required": ["url", "filename", "contentType"],
        "properties": {
          "url": {
            "type": "string",
            "description": "Temporary URL for downloading the export.",
            "example": "https://api.ip-info.app/downloads/usage.csv"
          },
          "filename": {
            "type": "string",
            "description": "Suggested filename for the export.",
            "example": "ip-info-usage-2026-03.csv"
          },
          "contentType": {
            "type": "string",
            "description": "MIME type of the export.",
            "example": "text/csv"
          }
        },
        "example": {
          "url": "https://api.ip-info.app/downloads/usage.csv",
          "filename": "ip-info-usage-2026-03.csv",
          "contentType": "text/csv"
        }
      },
      "ApiUsageEntry": {
        "type": "object",
        "title": "API usage entry",
        "description": "Usage totals for one day and service.",
        "required": ["date", "service", "count", "userId"],
        "properties": {
          "date": {
            "type": "string",
            "description": "Usage date in YYYY-MM-DD format.",
            "example": "2026-03-12"
          },
          "service": {
            "type": "string",
            "description": "Service counted for this row.",
            "enum": ["get-ip-details"],
            "example": "get-ip-details"
          },
          "count": {
            "type": "number",
            "description": "Number of requests counted for the date and service.",
            "example": 14
          },
          "userId": {
            "type": "string",
            "pattern": "^[a-fA-F0-9]{24}$",
            "description": "Account ID that owns the usage.",
            "example": "507f1f77bcf86cd799439011"
          }
        }
      },
      "ApiUsage": {
        "type": "array",
        "title": "API usage",
        "description": "Daily IP Info API usage rows for the authenticated account.",
        "items": {
          "$ref": "#/components/schemas/ApiUsageEntry"
        },
        "example": [
          {
            "date": "2026-03-12",
            "service": "get-ip-details",
            "count": 14,
            "userId": "507f1f77bcf86cd799439011"
          }
        ]
      },
      "IpLocation": {
        "type": "object",
        "title": "IP location",
        "description": "Approximate city-level geolocation for an IP address.",
        "required": ["latitude", "longitude", "accuracyRadius"],
        "properties": {
          "name": {
            "type": "string",
            "description": "City name, when available.",
            "example": "Mountain View"
          },
          "region": {
            "type": "string",
            "description": "Region or state name, when available.",
            "example": "California"
          },
          "latitude": {
            "type": "number",
            "description": "Approximate latitude.",
            "example": 37.4223
          },
          "longitude": {
            "type": "number",
            "description": "Approximate longitude.",
            "example": -122.085
          },
          "accuracyRadius": {
            "type": "number",
            "description": "Estimated location accuracy radius in kilometers.",
            "example": 1000
          },
          "timeZone": {
            "type": "string",
            "description": "IANA timezone for the location.",
            "example": "America/Los_Angeles"
          },
          "areaCode": {
            "type": "string",
            "description": "Telephone area code when available.",
            "example": "650"
          }
        }
      },
      "IpDetails": {
        "type": "object",
        "title": "IP details",
        "description": "Geolocation, network ownership, and optional lookup performance details for an IP address.",
        "required": ["ip"],
        "properties": {
          "ip": {
            "type": "string",
            "description": "IP address that was resolved.",
            "example": "8.8.8.8"
          },
          "ptr": {
            "type": "string",
            "description": "Reverse DNS PTR hostname, when available.",
            "example": "dns.google"
          },
          "city": {
            "$ref": "#/components/schemas/IpLocation"
          },
          "continentCode": {
            "type": "string",
            "description": "Two-letter continent code.",
            "example": "NA"
          },
          "countryName": {
            "type": "string",
            "description": "Country name.",
            "example": "United States"
          },
          "countryCode": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code.",
            "example": "US"
          },
          "countryCode3": {
            "type": "string",
            "description": "ISO 3166-1 alpha-3 country code.",
            "example": "USA"
          },
          "registeredCountryCode": {
            "type": "string",
            "description": "Registered country code for the IP allocation, when available.",
            "example": "US"
          },
          "asn": {
            "type": "number",
            "description": "Autonomous System Number associated with the IP.",
            "example": 15169
          },
          "aso": {
            "type": "string",
            "description": "Autonomous System Organization name, when available.",
            "example": "Google LLC"
          },
          "organization": {
            "type": "string",
            "description": "Network or organization name associated with the IP.",
            "example": "Google LLC"
          },
          "performance": {
            "type": "object",
            "description": "Optional timing metadata returned when `getPerformanceData=true`.",
            "additionalProperties": {
              "type": "number"
            },
            "example": {
              "totalMs": 12
            }
          }
        },
        "example": {
          "ip": "8.8.8.8",
          "ptr": "dns.google",
          "city": {
            "name": "Mountain View",
            "region": "California",
            "latitude": 37.4223,
            "longitude": -122.085,
            "accuracyRadius": 1000,
            "timeZone": "America/Los_Angeles"
          },
          "continentCode": "NA",
          "countryName": "United States",
          "countryCode": "US",
          "countryCode3": "USA",
          "registeredCountryCode": "US",
          "asn": 15169,
          "aso": "Google LLC",
          "organization": "Google LLC"
        }
      },
      "ErrorDetail": {
        "type": "object",
        "title": "Error detail",
        "description": "Additional detail about a validation or processing error.",
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable issue code.",
            "example": "invalid_type"
          },
          "message": {
            "type": "string",
            "description": "Human-readable issue message.",
            "example": "Expected a valid IP address."
          },
          "path": {
            "description": "Field or input path associated with this issue.",
            "anyOf": [
              {
                "type": "string",
                "example": "ip"
              },
              {
                "type": "array",
                "items": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    }
                  ]
                },
                "example": ["ip"]
              }
            ]
          }
        }
      },
      "BadRequestError": {
        "type": "object",
        "title": "Bad request error",
        "description": "The request could not be processed because one or more inputs are invalid.",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code.",
            "example": "VALIDATION_ERROR"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "Invalid request parameters"
          },
          "issues": {
            "type": "array",
            "description": "Optional structured details, most often returned for validation errors.",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "default": []
          }
        },
        "example": {
          "error": "VALIDATION_ERROR",
          "message": "Invalid request parameters",
          "issues": []
        }
      },
      "UnauthorizedError": {
        "type": "object",
        "title": "Authentication error",
        "description": "Authentication is missing, invalid, or expired.",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code.",
            "example": "AUTHENTICATION_REQUIRED"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "Authentication token is required"
          },
          "issues": {
            "type": "array",
            "description": "Optional structured details, most often returned for validation errors.",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "default": []
          }
        },
        "example": {
          "error": "AUTHENTICATION_REQUIRED",
          "message": "Authentication token is required",
          "issues": []
        }
      },
      "PaymentRequiredError": {
        "type": "object",
        "title": "Payment required error",
        "description": "The account does not have enough credits or an active plan for the request.",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code.",
            "example": "PAYMENT_REQUIRED"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "Insufficient credits"
          },
          "issues": {
            "type": "array",
            "description": "Optional structured details, most often returned for validation errors.",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "default": []
          }
        },
        "example": {
          "error": "PAYMENT_REQUIRED",
          "message": "Insufficient credits",
          "issues": []
        }
      },
      "ForbiddenError": {
        "type": "object",
        "title": "Forbidden error",
        "description": "The credential is valid but does not have permission for this action.",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code.",
            "example": "ACCESS_DENIED"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "You do not have permission to perform this action"
          },
          "issues": {
            "type": "array",
            "description": "Optional structured details, most often returned for validation errors.",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "default": []
          }
        },
        "example": {
          "error": "ACCESS_DENIED",
          "message": "You do not have permission to perform this action",
          "issues": []
        }
      },
      "NotFoundError": {
        "type": "object",
        "title": "Not found error",
        "description": "The requested API key or resource was not found.",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code.",
            "example": "NOT_FOUND"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "The requested resource was not found"
          },
          "issues": {
            "type": "array",
            "description": "Optional structured details, most often returned for validation errors.",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "default": []
          }
        },
        "example": {
          "error": "NOT_FOUND",
          "message": "The requested resource was not found",
          "issues": []
        }
      },
      "TooManyRequestsError": {
        "type": "object",
        "title": "Rate limit error",
        "description": "The request was rate limited. Retry after the limit resets.",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code.",
            "example": "RATE_LIMIT_EXCEEDED"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "Too many requests, please try again later"
          },
          "issues": {
            "type": "array",
            "description": "Optional structured details, most often returned for validation errors.",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "default": []
          }
        },
        "example": {
          "error": "RATE_LIMIT_EXCEEDED",
          "message": "Too many requests, please try again later",
          "issues": []
        }
      },
      "ServerError": {
        "type": "object",
        "title": "Server error",
        "description": "An unexpected service error occurred while processing the request.",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code.",
            "example": "INTERNAL_SERVER_ERROR"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "An unexpected error occurred"
          },
          "issues": {
            "type": "array",
            "description": "Optional structured details, most often returned for validation errors.",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "default": []
          }
        },
        "example": {
          "error": "INTERNAL_SERVER_ERROR",
          "message": "An unexpected error occurred",
          "issues": []
        }
      }
    }
  },
  "paths": {
    "/v1-create-api-key": {
      "post": {
        "tags": ["API Keys"],
        "summary": "Create an API key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Create Api Key response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKey"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "createApiKey",
        "description": "Create a new API key for IP lookup requests. Use this endpoint from an authenticated account session.",
        "security": [
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-delete-api-key": {
      "post": {
        "tags": ["API Keys"],
        "summary": "Delete an API key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Delete Api Key response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteApiKeyResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "deleteApiKey",
        "description": "Permanently delete an API key from your account. Deleted keys can no longer authenticate lookup requests.",
        "security": [
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-get-api-key-details": {
      "post": {
        "tags": ["API Keys"],
        "summary": "Get API key details",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Get Api Key Details response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKey"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "getApiKey",
        "description": "Fetch one API key by ID, including enabled state, service access, and metadata.",
        "security": [
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-list-api-keys": {
      "post": {
        "tags": ["API Keys"],
        "summary": "List API keys",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListApiKeysRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "List Api Keys response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListApiKeysResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "listApiKeys",
        "description": "List API keys available in your authenticated IP-Info account.",
        "security": [
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-update-api-key": {
      "post": {
        "tags": ["API Keys"],
        "summary": "Update an API key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Update Api Key response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKey"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "updateApiKey",
        "description": "Update an API key name, enabled state, environment label, or IP Info service access.",
        "security": [
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-who-am-i": {
      "get": {
        "tags": ["API Keys"],
        "summary": "Identify the current credential",
        "responses": {
          "200": {
            "description": "Who Am I response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyIdentity"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "identifyCredential",
        "description": "Return account and request context for the API key or account token used on the request.",
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-download-api-usage": {
      "get": {
        "tags": ["Usage"],
        "summary": "Export API usage",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Start date for the report, in YYYY-MM-DD format.",
              "example": "2026-03-01"
            },
            "required": false,
            "name": "from",
            "in": "query",
            "description": "Start date for the report, in YYYY-MM-DD format."
          },
          {
            "schema": {
              "type": "string",
              "description": "End date for the report, in YYYY-MM-DD format.",
              "example": "2026-03-31"
            },
            "required": false,
            "name": "to",
            "in": "query",
            "description": "End date for the report, in YYYY-MM-DD format."
          },
          {
            "schema": {
              "type": "string",
              "description": "Optional service filter. Use `get-ip-details` for IP lookup usage.",
              "example": "get-ip-details",
              "enum": ["get-ip-details"]
            },
            "required": false,
            "name": "service",
            "in": "query",
            "description": "Optional service filter. Use `get-ip-details` for IP lookup usage."
          }
        ],
        "responses": {
          "200": {
            "description": "Download Api Usage response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiUsageExport"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "downloadApiUsage",
        "description": "Create a downloadable usage export for a date range. Use this for reporting, reconciliation, or cost tracking.",
        "security": [
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-get-api-usage": {
      "get": {
        "tags": ["Usage"],
        "summary": "Get API usage",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Start date for the report, in YYYY-MM-DD format.",
              "example": "2026-03-01"
            },
            "required": false,
            "name": "from",
            "in": "query",
            "description": "Start date for the report, in YYYY-MM-DD format."
          },
          {
            "schema": {
              "type": "string",
              "description": "End date for the report, in YYYY-MM-DD format.",
              "example": "2026-03-31"
            },
            "required": false,
            "name": "to",
            "in": "query",
            "description": "End date for the report, in YYYY-MM-DD format."
          },
          {
            "schema": {
              "type": "string",
              "description": "Optional service filter. Use `get-ip-details` for IP lookup usage.",
              "example": "get-ip-details",
              "enum": ["get-ip-details"]
            },
            "required": false,
            "name": "service",
            "in": "query",
            "description": "Optional service filter. Use `get-ip-details` for IP lookup usage."
          }
        ],
        "responses": {
          "200": {
            "description": "Get Api Usage response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiUsage"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        },
        "operationId": "getApiUsage",
        "description": "Return daily API usage rows for your authenticated account, optionally filtered by date range and service.",
        "security": [
          {
            "JwtTokenAuth": []
          }
        ]
      }
    },
    "/v1-get-ip-details": {
      "get": {
        "operationId": "getIpDetails",
        "tags": ["IP Lookup"],
        "summary": "Look up IP details",
        "description": "Resolve an IPv4 or IPv6 address into geolocation, registered country, ASN, organization, PTR hostname, and optional lookup timing details. If `ip` is omitted, the API resolves the caller IP.",
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "JwtTokenAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "ip"
                },
                {
                  "type": "string",
                  "format": "ip"
                }
              ],
              "description": "IPv4 or IPv6 address to inspect. Omit this parameter to look up the caller IP.",
              "example": "8.8.8.8"
            },
            "required": false,
            "description": "IPv4 or IPv6 address to inspect. Omit this parameter to look up the caller IP.",
            "name": "ip",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["maxmind", "geojs"],
              "description": "Optional geolocation data source override. Most integrations should omit this.",
              "example": "maxmind"
            },
            "required": false,
            "description": "Optional geolocation data source override. Most integrations should omit this.",
            "name": "provider",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "string",
                  "enum": ["0", "1", "true", "false"]
                }
              ],
              "default": false,
              "description": "Set to `true` to bypass cached provider results and force a fresh lookup.",
              "example": false
            },
            "required": false,
            "description": "Set to `true` to bypass cached provider results and force a fresh lookup.",
            "name": "skipCache",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "string",
                  "enum": ["0", "1", "true", "false"]
                }
              ],
              "default": false,
              "description": "Set to `true` to include lookup timing metadata in the response.",
              "example": false
            },
            "required": false,
            "description": "Set to `true` to include lookup timing metadata in the response.",
            "name": "getPerformanceData",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "IP geolocation and network ownership details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IpDetails"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. Check the request body, query parameters, or IP address format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedError"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient credits or requires an active plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The credential does not have permission to perform this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForbiddenError"
                }
              }
            }
          },
          "404": {
            "description": "The requested API key or resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                }
              }
            }
          },
          "429": {
            "description": "The request was rate limited. Retry after the limit resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TooManyRequestsError"
                }
              }
            }
          },
          "500": {
            "description": "An unexpected server error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "IP Lookup",
      "description": "Resolve IP addresses into geolocation, registered country, ASN, organization, PTR, and optional lookup timing details."
    },
    {
      "name": "API Keys",
      "description": "Create, update, list, inspect, and revoke API keys for your IP-Info account."
    },
    {
      "name": "Usage",
      "description": "Review and export daily API usage for cost tracking and operational reporting."
    }
  ]
}
