{
  "openapi": "3.1.0",
  "info": {
    "title": "Packetrove API",
    "version": "0.5.0",
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/license/mit/"
    },
    "description": "Network tools for humans and agents, including local calculations and request-based diagnostics. Address counts are decimal strings for exact IPv6 representation."
  },
  "servers": [
    {
      "url": "/",
      "description": "The host serving this specification"
    }
  ],
  "tags": [
    {
      "name": "CIDR",
      "description": "IP address and CIDR calculations."
    },
    {
      "name": "Certificates",
      "description": "Diagnostics for supplied public certificate bundles."
    },
    {
      "name": "IP",
      "description": "Request-based IP address diagnostics."
    },
    {
      "name": "Platform",
      "description": "Service metadata."
    }
  ],
  "security": [],
  "components": {
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "INVALID_INPUT",
                  "MIXED_ADDRESS_FAMILIES",
                  "INVALID_JSON",
                  "PAYLOAD_TOO_LARGE",
                  "UNSUPPORTED_MEDIA_TYPE",
                  "NOT_FOUND",
                  "METHOD_NOT_ALLOWED",
                  "INTERNAL_ERROR",
                  "CLIENT_IP_UNAVAILABLE",
                  "NETWORK_ERROR",
                  "INVALID_RESPONSE"
                ]
              },
              "message": {
                "type": "string"
              },
              "issues": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "index": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Zero-based index in inputs, or in the identified include/exclude list."
                    },
                    "list": {
                      "type": "string",
                      "minLength": 1,
                      "description": "The input list containing the invalid entry. Existing subtraction errors use include or exclude."
                    },
                    "field": {
                      "type": "string",
                      "minLength": 1,
                      "description": "The input field containing the invalid value. Existing range errors use start or end."
                    },
                    "path": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1
                          },
                          {
                            "type": "integer",
                            "minimum": 0
                          }
                        ]
                      },
                      "description": "Input field names and zero-based array indices, from the request root. An empty path identifies the whole request. Takes precedence over legacy field, list, and index locations."
                    },
                    "message": {
                      "type": "string"
                    },
                    "location": {
                      "type": "object",
                      "properties": {
                        "line": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "offset": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "end": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "line",
                        "offset",
                        "end"
                      ],
                      "additionalProperties": false,
                      "description": "Original text location: one-based line and zero-based UTF-16 start/end offsets. Certificate PEM errors use this to identify rejected material without echoing it."
                    }
                  },
                  "required": [
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "HealthResult": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          }
        },
        "required": [
          "status"
        ],
        "additionalProperties": false
      },
      "CidrCoverResult": {
        "type": "object",
        "properties": {
          "family": {
            "type": "string",
            "enum": [
              "ipv4",
              "ipv6"
            ]
          },
          "normalizedInputs": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "minItems": 1,
            "maxItems": 1000,
            "description": "Canonical CIDRs in input order. Individual addresses become /32 or /128. Duplicates are retained here."
          },
          "cidr": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "The smallest single canonical CIDR containing every input address."
          },
          "range": {
            "type": "object",
            "properties": {
              "first": {
                "type": "string",
                "minLength": 1
              },
              "last": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "first",
              "last"
            ],
            "additionalProperties": false
          },
          "inputAddressCount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Number of distinct addresses in the union of the inputs."
          },
          "coveredAddressCount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Number of all addresses in the resulting CIDR."
          },
          "additionalAddressCount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Covered address count minus input address count."
          }
        },
        "required": [
          "family",
          "normalizedInputs",
          "cidr",
          "range",
          "inputAddressCount",
          "coveredAddressCount",
          "additionalAddressCount"
        ],
        "additionalProperties": false
      },
      "CidrCoverRequest": {
        "type": "object",
        "properties": {
          "inputs": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "minItems": 1,
            "maxItems": 1000,
            "description": "IP addresses or CIDRs from one address family. Surrounding whitespace is ignored during parsing; CIDRs with host bits are normalized."
          }
        },
        "required": [
          "inputs"
        ],
        "additionalProperties": false
      },
      "CidrSubtractResult": {
        "type": "object",
        "properties": {
          "family": {
            "type": "string",
            "enum": [
              "ipv4",
              "ipv6"
            ]
          },
          "normalizedInclude": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "minItems": 1,
            "maxItems": 1000
          },
          "normalizedExclude": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "maxItems": 1000
          },
          "cidrs": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "maxItems": 10000
          },
          "includedAddressCount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Exact number of addresses as a base-10 string, including network and broadcast addresses."
          },
          "removedAddressCount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Exact number of addresses as a base-10 string, including network and broadcast addresses."
          },
          "remainingAddressCount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Exact number of addresses as a base-10 string, including network and broadcast addresses."
          }
        },
        "required": [
          "family",
          "normalizedInclude",
          "normalizedExclude",
          "cidrs",
          "includedAddressCount",
          "removedAddressCount",
          "remainingAddressCount"
        ],
        "additionalProperties": false
      },
      "CidrSubtractRequest": {
        "type": "object",
        "properties": {
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "minItems": 1,
            "maxItems": 1000,
            "description": "The nonempty included address space. Use at most 1,000 entries across include and exclude, from one address family."
          },
          "exclude": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "maxItems": 1000,
            "description": "Ranges to remove from the included address space. An empty array simplifies the exact include union."
          }
        },
        "required": [
          "include",
          "exclude"
        ],
        "additionalProperties": false
      },
      "RangeToCidrsResult": {
        "type": "object",
        "properties": {
          "family": {
            "type": "string",
            "enum": [
              "ipv4",
              "ipv6"
            ]
          },
          "range": {
            "type": "object",
            "properties": {
              "first": {
                "type": "string"
              },
              "last": {
                "type": "string"
              }
            },
            "required": [
              "first",
              "last"
            ],
            "additionalProperties": false,
            "description": "Canonical inclusive start and end IP addresses."
          },
          "cidrs": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "minItems": 1,
            "maxItems": 254,
            "description": "Complete minimal CIDR list, sorted by network address, with no gaps, overlaps, or additional addresses."
          },
          "cidrCount": {
            "type": "integer",
            "minimum": 1,
            "maximum": 254
          },
          "addressCount": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Exact number of addresses as a base-10 string, including network and broadcast addresses."
          }
        },
        "required": [
          "family",
          "range",
          "cidrs",
          "cidrCount",
          "addressCount"
        ],
        "additionalProperties": false
      },
      "RangeToCidrsRequest": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "Inclusive start IP address. Use IPv4 or IPv6 without a CIDR prefix; surrounding whitespace is ignored."
          },
          "end": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "Inclusive end IP address, in the same family and at or after start. Endpoints are never silently swapped."
          }
        },
        "required": [
          "start",
          "end"
        ],
        "additionalProperties": false
      },
      "CertificateBundleResult": {
        "type": "object",
        "properties": {
          "evaluatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Evaluation time from this runtime clock, not a deployment observation."
          },
          "certificates": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 15,
                  "description": "Zero-based original input position; duplicates retain their positions."
                },
                "line": {
                  "type": "integer",
                  "minimum": 1,
                  "description": "One-based input line of the BEGIN boundary."
                },
                "subject": {
                  "type": "string"
                },
                "issuer": {
                  "type": "string"
                },
                "commonName": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "serialNumber": {
                  "type": "string"
                },
                "sans": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string"
                      },
                      "value": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "value"
                    ],
                    "additionalProperties": false
                  }
                },
                "notBefore": {
                  "type": "string",
                  "format": "date-time"
                },
                "notAfter": {
                  "type": "string",
                  "format": "date-time"
                },
                "ca": {
                  "type": "boolean"
                },
                "basicConstraintsPresent": {
                  "type": "boolean"
                },
                "keyCertSign": {
                  "type": [
                    "boolean",
                    "null"
                  ]
                },
                "fingerprintSha256": {
                  "type": "string",
                  "pattern": "^(?:[0-9A-F]{2}:){31}[0-9A-F]{2}$"
                },
                "signatureAlgorithm": {
                  "type": "string"
                },
                "selfSignature": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "verified",
                    "failed",
                    "unsupported",
                    "unavailable",
                    null
                  ]
                }
              },
              "required": [
                "index",
                "line",
                "subject",
                "issuer",
                "commonName",
                "serialNumber",
                "sans",
                "notBefore",
                "notAfter",
                "ca",
                "basicConstraintsPresent",
                "keyCertSign",
                "fingerprintSha256",
                "signatureAlgorithm",
                "selfSignature"
              ],
              "additionalProperties": false
            },
            "minItems": 1,
            "maxItems": 16
          },
          "relationships": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "childIndex": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 15
                },
                "issuerIndex": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 15
                },
                "signature": {
                  "type": "string",
                  "enum": [
                    "verified",
                    "failed",
                    "unsupported",
                    "unavailable"
                  ]
                },
                "issuerEligible": {
                  "type": "boolean",
                  "description": "basicConstraints CA=true and, if present, Key Usage permits keyCertSign. Does not include validity, trust, or full path constraints."
                },
                "keyIdentifierMatch": {
                  "type": [
                    "boolean",
                    "null"
                  ]
                }
              },
              "required": [
                "childIndex",
                "issuerIndex",
                "signature",
                "issuerEligible",
                "keyIdentifierMatch"
              ],
              "additionalProperties": false
            },
            "maxItems": 240
          },
          "leafIndexes": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0,
              "maximum": 15
            },
            "maxItems": 16,
            "description": "First occurrences of distinct non-CA certificates; these are possible leaves, not a verified deployment selection."
          },
          "selectedLeafIndex": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 15
          },
          "hostname": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "expected": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "matched",
                  "mismatched",
                  "ambiguous",
                  "no-leaf"
                ]
              }
            },
            "required": [
              "expected",
              "status"
            ],
            "additionalProperties": false
          },
          "findings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "enum": [
                    "DUPLICATE_CERTIFICATE",
                    "CERTIFICATE_EXPIRED",
                    "CERTIFICATE_NOT_YET_VALID",
                    "SELF_SIGNED_CERTIFICATE",
                    "SELF_SIGNATURE_FAILED",
                    "SIGNATURE_UNSUPPORTED",
                    "SIGNATURE_CHECK_UNAVAILABLE",
                    "ISSUER_NOT_IN_BUNDLE",
                    "CANDIDATE_SIGNATURE_FAILED",
                    "ISSUER_NOT_CA",
                    "ISSUER_KEY_USAGE_REJECTED",
                    "ISSUER_KEY_ID_MISMATCH",
                    "MULTIPLE_ISSUERS",
                    "LEAF_SELECTION_REQUIRED",
                    "NO_LEAF_CERTIFICATE",
                    "HOSTNAME_MATCH",
                    "HOSTNAME_MISMATCH"
                  ]
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "error",
                    "warning",
                    "info"
                  ]
                },
                "certificateIndexes": {
                  "type": "array",
                  "items": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 15
                  },
                  "maxItems": 16
                },
                "observed": {
                  "type": "string"
                },
                "evidence": {
                  "type": "object",
                  "additionalProperties": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "number"
                      },
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "nextAction": {
                  "type": "string"
                }
              },
              "required": [
                "code",
                "severity",
                "certificateIndexes",
                "observed",
                "evidence",
                "nextAction"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "evaluatedAt",
          "certificates",
          "relationships",
          "leafIndexes",
          "selectedLeafIndex",
          "hostname",
          "findings"
        ],
        "additionalProperties": false,
        "description": "Structural and cryptographic observations about the supplied bundle. Not full RFC 5280 path validation, client trust, revocation checking, or deployment safety. Candidate failures do not invalidate other paths."
      },
      "CertificateBundleRequest": {
        "type": "object",
        "properties": {
          "pem": {
            "type": "string",
            "maxLength": 49152,
            "description": "One or more PEM CERTIFICATE blocks, with only whitespace between blocks. At most 48 KiB of UTF-8 and 16 blocks. Private keys and other block types are rejected."
          },
          "hostname": {
            "type": "string",
            "maxLength": 255,
            "description": "Optional ASCII DNS hostname, including pre-converted IDNA A-labels. No URL, port, IP address, or wildcard. Blank skips identity checking."
          },
          "leafIndex": {
            "type": "integer",
            "minimum": 0,
            "maximum": 15,
            "description": "Zero-based original position of a non-CA certificate. Required to resolve multiple possible leaves for hostname checking."
          }
        },
        "required": [
          "pem"
        ],
        "additionalProperties": false
      },
      "PublicIpResult": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "family": {
                "type": "string",
                "enum": [
                  "ipv4"
                ]
              },
              "ip": {
                "type": "string",
                "format": "ip"
              }
            },
            "required": [
              "family",
              "ip"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "family": {
                "type": "string",
                "enum": [
                  "ipv6"
                ]
              },
              "ip": {
                "type": "string",
                "format": "ip"
              }
            },
            "required": [
              "family",
              "ip"
            ],
            "additionalProperties": false
          }
        ],
        "description": "The IP address observed for this request. A VPN, proxy, or hosted client can change whose exit address is observed. One request observes one address family."
      }
    },
    "parameters": {}
  },
  "paths": {
    "/v1/cidr-cover": {
      "post": {
        "operationId": "cidr-cover",
        "tags": [
          "CIDR"
        ],
        "summary": "Find the smallest single CIDR covering all inputs",
        "description": "Accepts IPv4 or IPv6 addresses and CIDRs from one address family. The output maximizes the prefix length while covering every input address, and may include additional addresses. Overlapping inputs are counted once. CIDRs with host bits are normalized. The request body must not exceed 65536 bytes. This is a stateless calculation and does not modify firewall rules.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "examples": {
                "example1": {
                  "summary": "Adjacent IPv4 ranges without expansion",
                  "value": {
                    "inputs": [
                      "203.0.113.0/25",
                      "203.0.113.128/25"
                    ]
                  }
                },
                "example2": {
                  "summary": "Multiple IPv4 addresses with expansion",
                  "value": {
                    "inputs": [
                      "203.0.113.1",
                      "203.0.113.2",
                      "203.0.113.6"
                    ]
                  }
                },
                "example3": {
                  "summary": "IPv6 counts beyond the JavaScript safe integer range",
                  "value": {
                    "inputs": [
                      "2001:db8::/64",
                      "2001:db8:0:1::/64"
                    ]
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/CidrCoverRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The calculated result and exact address counts.",
            "content": {
              "application/json": {
                "examples": {
                  "example1": {
                    "summary": "Adjacent IPv4 ranges without expansion",
                    "value": {
                      "family": "ipv4",
                      "normalizedInputs": [
                        "203.0.113.0/25",
                        "203.0.113.128/25"
                      ],
                      "cidr": "203.0.113.0/24",
                      "range": {
                        "first": "203.0.113.0",
                        "last": "203.0.113.255"
                      },
                      "inputAddressCount": "256",
                      "coveredAddressCount": "256",
                      "additionalAddressCount": "0"
                    }
                  },
                  "example2": {
                    "summary": "Multiple IPv4 addresses with expansion",
                    "value": {
                      "family": "ipv4",
                      "normalizedInputs": [
                        "203.0.113.1/32",
                        "203.0.113.2/32",
                        "203.0.113.6/32"
                      ],
                      "cidr": "203.0.113.0/29",
                      "range": {
                        "first": "203.0.113.0",
                        "last": "203.0.113.7"
                      },
                      "inputAddressCount": "3",
                      "coveredAddressCount": "8",
                      "additionalAddressCount": "5"
                    }
                  },
                  "example3": {
                    "summary": "IPv6 counts beyond the JavaScript safe integer range",
                    "value": {
                      "family": "ipv6",
                      "normalizedInputs": [
                        "2001:db8::/64",
                        "2001:db8:0:1::/64"
                      ],
                      "cidr": "2001:db8::/63",
                      "range": {
                        "first": "2001:db8::",
                        "last": "2001:db8:0:1:ffff:ffff:ffff:ffff"
                      },
                      "inputAddressCount": "36893488147419103232",
                      "coveredAddressCount": "36893488147419103232",
                      "additionalAddressCount": "0"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/CidrCoverResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, invalid input, or mixed address families. Input issues include a zero-based index.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Method is not supported for this endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 64 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "415": {
            "description": "Expected an application/json request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cidr-subtract": {
      "post": {
        "operationId": "cidr-subtract",
        "tags": [
          "CIDR"
        ],
        "summary": "Subtract excluded networks from included address space exactly",
        "description": "Return the minimal sorted canonical CIDR list for union(include) minus union(exclude), without adding addresses. Use one address family and at most 1000 entries across both lists, with at most 64 characters per entry. Include must be nonempty; exclude may be empty. Overlaps count once and host bits are normalized. Results include exact decimal-string counts; complete removal succeeds with an empty list. Results exceeding 10000 CIDRs fail without returning a partial list. The request body must not exceed 65536 bytes. Calls send inputs to the server; no firewall or WireGuard configuration is changed and remaining ranges do not prove live availability.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "examples": {
                "example1": {
                  "summary": "IPv4",
                  "value": {
                    "include": [
                      "203.0.113.0/24"
                    ],
                    "exclude": [
                      "203.0.113.64/26"
                    ]
                  }
                },
                "example2": {
                  "summary": "IPv6",
                  "value": {
                    "include": [
                      "2001:db8::/124"
                    ],
                    "exclude": [
                      "2001:db8::4/126"
                    ]
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/CidrSubtractRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The calculated result and exact address counts.",
            "content": {
              "application/json": {
                "examples": {
                  "example1": {
                    "summary": "IPv4",
                    "value": {
                      "family": "ipv4",
                      "normalizedInclude": [
                        "203.0.113.0/24"
                      ],
                      "normalizedExclude": [
                        "203.0.113.64/26"
                      ],
                      "cidrs": [
                        "203.0.113.0/26",
                        "203.0.113.128/25"
                      ],
                      "includedAddressCount": "256",
                      "removedAddressCount": "64",
                      "remainingAddressCount": "192"
                    }
                  },
                  "example2": {
                    "summary": "IPv6",
                    "value": {
                      "family": "ipv6",
                      "normalizedInclude": [
                        "2001:db8::/124"
                      ],
                      "normalizedExclude": [
                        "2001:db8::4/126"
                      ],
                      "cidrs": [
                        "2001:db8::/126",
                        "2001:db8::8/125"
                      ],
                      "includedAddressCount": "16",
                      "removedAddressCount": "4",
                      "remainingAddressCount": "12"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/CidrSubtractResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, invalid input, mixed address families, or output limit exceeded. Entry issues include a zero-based index and identify the include/exclude list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Method is not supported for this endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 64 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "415": {
            "description": "Expected an application/json request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/range-to-cidrs": {
      "post": {
        "operationId": "range-to-cidrs",
        "tags": [
          "CIDR"
        ],
        "summary": "Convert an inclusive IP range to its minimal exact CIDR list",
        "description": "Accept exactly one start and one end IP address of the same family, without CIDR prefixes, at most 64 characters each. Both endpoints are inclusive; end must be at or after start and endpoints are never swapped. Return canonical endpoints and the minimal sorted non-overlapping CIDR list covering exactly that range, with cidrCount and an exact decimal-string addressCount. Every address counts, including IPv4 network and broadcast addresses. Calculations do not enumerate addresses. The request body must not exceed 65536 bytes. Calls submit inputs to the server; no live allocation or firewall configuration is inspected or changed.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "examples": {
                "example1": {
                  "summary": "IPv4",
                  "value": {
                    "start": "203.0.113.11",
                    "end": "203.0.113.23"
                  }
                },
                "example2": {
                  "summary": "IPv6",
                  "value": {
                    "start": "2001:db8::b",
                    "end": "2001:db8::17"
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/RangeToCidrsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The calculated result and exact address counts.",
            "content": {
              "application/json": {
                "examples": {
                  "example1": {
                    "summary": "IPv4",
                    "value": {
                      "family": "ipv4",
                      "range": {
                        "first": "203.0.113.11",
                        "last": "203.0.113.23"
                      },
                      "cidrs": [
                        "203.0.113.11/32",
                        "203.0.113.12/30",
                        "203.0.113.16/29"
                      ],
                      "cidrCount": 3,
                      "addressCount": "13"
                    }
                  },
                  "example2": {
                    "summary": "IPv6",
                    "value": {
                      "family": "ipv6",
                      "range": {
                        "first": "2001:db8::b",
                        "last": "2001:db8::17"
                      },
                      "cidrs": [
                        "2001:db8::b/128",
                        "2001:db8::c/126",
                        "2001:db8::10/125"
                      ],
                      "cidrCount": 3,
                      "addressCount": "13"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/RangeToCidrsResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, invalid endpoints, mixed address families, or reversed range. Issues identify the start or end field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Method is not supported for this endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 64 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "415": {
            "description": "Expected an application/json request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/certificate-bundle": {
      "post": {
        "operationId": "certificate-bundle",
        "tags": [
          "Certificates"
        ],
        "summary": "Inspect a PEM certificate bundle and optional DNS hostname",
        "description": "Accept up to 16 CERTIFICATE blocks in at most 49152 UTF-8 PEM bytes, with only whitespace between blocks. Private keys are rejected. Preserve original zero-based positions and verify candidate signatures separately from issuer CA and keyCertSign constraints. Distinguish failed, unsupported, and unavailable checks. An issuer absent from this input is informational; roots are commonly omitted. Multiple leaves require an explicit leafIndex for hostname checking. Check ASCII DNS SAN names, with a complete leftmost wildcard matching one label and no Common Name fallback. Evaluation uses the server clock; documentation examples use a fixed illustrative time. Remote calls transmit certificates and optional hostname to the server; inputs, results, and certificate details are excluded from application logs. No full RFC 5280 path validation, client trust, revocation checking, live probing, or proof of deployment safety. JSON transport bodies remain limited to 65536 bytes.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "examples": {
                "example1": {
                  "summary": "Synthetic leaf, intermediate, and root",
                  "value": {
                    "pem": "-----BEGIN CERTIFICATE-----\nMIICCjCCAbCgAwIBAgIBCDAKBggqhkjOPQQDAjBEMRowGAYDVQQDExFEZW1vIElu\ndGVybWVkaWF0ZTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBs\nZXMwHhcNMjAwMTAxMDAwMDAwWhcNNDAwMTAxMDAwMDAwWjBGMRwwGgYDVQQDExNz\nZXJ2aWNlLmV4YW1wbGUuY29tMSYwJAYDVQQKEx1QYWNrZXRyb3ZlIFN5bnRoZXRp\nYyBFeGFtcGxlczBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABB5fn3dU7OLbmhjX\np3yyIx+2XV+Tm2SLDoKzqkh1tghkRRujbnOabparI3MRHv4xHE6OePpzrbjxRhRP\n6zFolZWjgZAwgY0wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0O\nBBYEFAfVEb9iWb+ZcGsM/Kn4GuAuzRDBMB8GA1UdIwQYMBaAFLVIZXp5pvnton0C\nEDqX/742N1ieMC0GA1UdEQQmMCSCE3NlcnZpY2UuZXhhbXBsZS5jb22CDSouZXhh\nbXBsZS5uZXQwCgYIKoZIzj0EAwIDSAAwRQIgVEcSRPkS5CuPS5aocD9DJHzXlrc1\nPdUma+rZtx2bN0UCIQD1C3NNIDmH1Xy4oJhwfKWcITyxyIXmlcK9pUiMjD+qdg==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIB1zCCAX2gAwIBAgIBAzAKBggqhkjOPQQDAjA+MRQwEgYDVQQDEwtEZW1vIFJv\nb3QgQTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBsZXMwHhcN\nMjAwMTAxMDAwMDAwWhcNNDAwMTAxMDAwMDAwWjBEMRowGAYDVQQDExFEZW1vIElu\ndGVybWVkaWF0ZTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBs\nZXMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARt9zn152ODLv2A7zMzZjK+5+8h\niuosIcwmRwEhVU/hxg0g22S/EppbLGahIl9r+gyjv1Z9cm4AYzWJ21qQ8xkpo2Yw\nZDASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwICBDAdBgNVHQ4EFgQU\ntUhlenmm+e2ifQIQOpf/vjY3WJ4wHwYDVR0jBBgwFoAUG028VQAIWmJos9X4aPvx\nebvw8dEwCgYIKoZIzj0EAwIDSAAwRQIhAJuznXANK1Rdaa0ukjaLMvVEx8L1vLVz\n8o4jwLtPmbFKAiB6koDuWdkdLRxnMQ43X2ze1SRy665HHyfQemuCjzrQjw==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIBsDCCAVagAwIBAgIBATAKBggqhkjOPQQDAjA+MRQwEgYDVQQDEwtEZW1vIFJv\nb3QgQTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBsZXMwHhcN\nMjAwMTAxMDAwMDAwWhcNNDAwMTAxMDAwMDAwWjA+MRQwEgYDVQQDEwtEZW1vIFJv\nb3QgQTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBsZXMwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS+Zp+N67NDEXRI1BrIw/iBk6raReb/UqYN\nsOaEVJZANsmih5h7VYPyJnAn5eJbU4uE/ebeZ7aSrFvHOu7EplDZo0UwQzASBgNV\nHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUG028VQAI\nWmJos9X4aPvxebvw8dEwCgYIKoZIzj0EAwIDSAAwRQIhAJk5L1v5StGaAboH6L4Z\nKOA71UEUUb2Y0pIbQsBL7Uq2AiBgIVRaev+zDSY0jTRmgIWTkR+49B/E3WWeOfBm\nmMB+/Q==\n-----END CERTIFICATE-----",
                    "hostname": "service.example.com"
                  }
                },
                "example2": {
                  "summary": "Synthetic served bundle with omitted root",
                  "value": {
                    "pem": "-----BEGIN CERTIFICATE-----\nMIICCjCCAbCgAwIBAgIBCDAKBggqhkjOPQQDAjBEMRowGAYDVQQDExFEZW1vIElu\ndGVybWVkaWF0ZTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBs\nZXMwHhcNMjAwMTAxMDAwMDAwWhcNNDAwMTAxMDAwMDAwWjBGMRwwGgYDVQQDExNz\nZXJ2aWNlLmV4YW1wbGUuY29tMSYwJAYDVQQKEx1QYWNrZXRyb3ZlIFN5bnRoZXRp\nYyBFeGFtcGxlczBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABB5fn3dU7OLbmhjX\np3yyIx+2XV+Tm2SLDoKzqkh1tghkRRujbnOabparI3MRHv4xHE6OePpzrbjxRhRP\n6zFolZWjgZAwgY0wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0O\nBBYEFAfVEb9iWb+ZcGsM/Kn4GuAuzRDBMB8GA1UdIwQYMBaAFLVIZXp5pvnton0C\nEDqX/742N1ieMC0GA1UdEQQmMCSCE3NlcnZpY2UuZXhhbXBsZS5jb22CDSouZXhh\nbXBsZS5uZXQwCgYIKoZIzj0EAwIDSAAwRQIgVEcSRPkS5CuPS5aocD9DJHzXlrc1\nPdUma+rZtx2bN0UCIQD1C3NNIDmH1Xy4oJhwfKWcITyxyIXmlcK9pUiMjD+qdg==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIB1zCCAX2gAwIBAgIBAzAKBggqhkjOPQQDAjA+MRQwEgYDVQQDEwtEZW1vIFJv\nb3QgQTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBsZXMwHhcN\nMjAwMTAxMDAwMDAwWhcNNDAwMTAxMDAwMDAwWjBEMRowGAYDVQQDExFEZW1vIElu\ndGVybWVkaWF0ZTEmMCQGA1UEChMdUGFja2V0cm92ZSBTeW50aGV0aWMgRXhhbXBs\nZXMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARt9zn152ODLv2A7zMzZjK+5+8h\niuosIcwmRwEhVU/hxg0g22S/EppbLGahIl9r+gyjv1Z9cm4AYzWJ21qQ8xkpo2Yw\nZDASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwICBDAdBgNVHQ4EFgQU\ntUhlenmm+e2ifQIQOpf/vjY3WJ4wHwYDVR0jBBgwFoAUG028VQAIWmJos9X4aPvx\nebvw8dEwCgYIKoZIzj0EAwIDSAAwRQIhAJuznXANK1Rdaa0ukjaLMvVEx8L1vLVz\n8o4jwLtPmbFKAiB6koDuWdkdLRxnMQ43X2ze1SRy665HHyfQemuCjzrQjw==\n-----END CERTIFICATE-----",
                    "hostname": "service.example.com"
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/CertificateBundleRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Certificates in original order, independently checked candidate issuer links, leaf selection, and findings with evidence and next actions.",
            "headers": {
              "Cache-Control": {
                "description": "Do not store certificate inputs or results.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "example1": {
                    "summary": "Synthetic leaf, intermediate, and root",
                    "value": {
                      "evaluatedAt": "2026-10-04T06:00:00.000Z",
                      "certificates": [
                        {
                          "index": 0,
                          "line": 1,
                          "subject": "CN=service.example.com, O=Packetrove Synthetic Examples",
                          "issuer": "CN=Demo Intermediate, O=Packetrove Synthetic Examples",
                          "commonName": "service.example.com",
                          "serialNumber": "08",
                          "sans": [
                            {
                              "type": "dns",
                              "value": "service.example.com"
                            },
                            {
                              "type": "dns",
                              "value": "*.example.net"
                            }
                          ],
                          "notBefore": "2020-01-01T00:00:00.000Z",
                          "notAfter": "2040-01-01T00:00:00.000Z",
                          "ca": false,
                          "basicConstraintsPresent": true,
                          "keyCertSign": false,
                          "fingerprintSha256": "DF:1C:D6:9A:55:27:32:F6:32:16:B5:27:34:9F:04:B6:32:DD:1E:BB:A9:E8:EF:17:3B:38:B3:97:30:55:B4:BE",
                          "signatureAlgorithm": "ECDSA / SHA-256",
                          "selfSignature": null
                        },
                        {
                          "index": 1,
                          "line": 14,
                          "subject": "CN=Demo Intermediate, O=Packetrove Synthetic Examples",
                          "issuer": "CN=Demo Root A, O=Packetrove Synthetic Examples",
                          "commonName": "Demo Intermediate",
                          "serialNumber": "03",
                          "sans": [],
                          "notBefore": "2020-01-01T00:00:00.000Z",
                          "notAfter": "2040-01-01T00:00:00.000Z",
                          "ca": true,
                          "basicConstraintsPresent": true,
                          "keyCertSign": true,
                          "fingerprintSha256": "50:0B:A0:34:32:D4:4E:BB:D0:9C:4F:D8:14:47:1B:9B:63:82:C8:1C:72:D5:CE:88:AB:7C:3D:7D:49:22:AB:46",
                          "signatureAlgorithm": "ECDSA / SHA-256",
                          "selfSignature": null
                        },
                        {
                          "index": 2,
                          "line": 26,
                          "subject": "CN=Demo Root A, O=Packetrove Synthetic Examples",
                          "issuer": "CN=Demo Root A, O=Packetrove Synthetic Examples",
                          "commonName": "Demo Root A",
                          "serialNumber": "01",
                          "sans": [],
                          "notBefore": "2020-01-01T00:00:00.000Z",
                          "notAfter": "2040-01-01T00:00:00.000Z",
                          "ca": true,
                          "basicConstraintsPresent": true,
                          "keyCertSign": true,
                          "fingerprintSha256": "42:B6:C1:BF:13:27:15:4E:7E:EF:E3:7A:82:A3:FF:3A:05:1B:E2:4D:B5:F1:EF:71:A6:E4:7F:17:F1:4C:7D:69",
                          "signatureAlgorithm": "ECDSA / SHA-256",
                          "selfSignature": "verified"
                        }
                      ],
                      "relationships": [
                        {
                          "childIndex": 0,
                          "issuerIndex": 1,
                          "signature": "verified",
                          "issuerEligible": true,
                          "keyIdentifierMatch": true
                        },
                        {
                          "childIndex": 1,
                          "issuerIndex": 2,
                          "signature": "verified",
                          "issuerEligible": true,
                          "keyIdentifierMatch": true
                        }
                      ],
                      "leafIndexes": [
                        0
                      ],
                      "selectedLeafIndex": 0,
                      "hostname": {
                        "expected": "service.example.com",
                        "status": "matched"
                      },
                      "findings": [
                        {
                          "code": "SELF_SIGNED_CERTIFICATE",
                          "severity": "info",
                          "certificateIndexes": [
                            2
                          ],
                          "observed": "The certificate verifies with its own public key.",
                          "evidence": {
                            "subject": "CN=Demo Root A, O=Packetrove Synthetic Examples",
                            "signature": "verified"
                          },
                          "nextAction": "A self-signature does not establish client trust. Check the intended trust configuration separately."
                        },
                        {
                          "code": "HOSTNAME_MATCH",
                          "severity": "info",
                          "certificateIndexes": [
                            0
                          ],
                          "observed": "The expected hostname matches a DNS SAN on the selected leaf.",
                          "evidence": {
                            "expectedHostname": "service.example.com",
                            "dnsSubjectAlternativeNames": "service.example.com, *.example.net"
                          },
                          "nextAction": "This identity check does not establish chain validity or client trust."
                        }
                      ]
                    }
                  },
                  "example2": {
                    "summary": "Synthetic served bundle with omitted root",
                    "value": {
                      "evaluatedAt": "2026-10-04T06:00:00.000Z",
                      "certificates": [
                        {
                          "index": 0,
                          "line": 1,
                          "subject": "CN=service.example.com, O=Packetrove Synthetic Examples",
                          "issuer": "CN=Demo Intermediate, O=Packetrove Synthetic Examples",
                          "commonName": "service.example.com",
                          "serialNumber": "08",
                          "sans": [
                            {
                              "type": "dns",
                              "value": "service.example.com"
                            },
                            {
                              "type": "dns",
                              "value": "*.example.net"
                            }
                          ],
                          "notBefore": "2020-01-01T00:00:00.000Z",
                          "notAfter": "2040-01-01T00:00:00.000Z",
                          "ca": false,
                          "basicConstraintsPresent": true,
                          "keyCertSign": false,
                          "fingerprintSha256": "DF:1C:D6:9A:55:27:32:F6:32:16:B5:27:34:9F:04:B6:32:DD:1E:BB:A9:E8:EF:17:3B:38:B3:97:30:55:B4:BE",
                          "signatureAlgorithm": "ECDSA / SHA-256",
                          "selfSignature": null
                        },
                        {
                          "index": 1,
                          "line": 14,
                          "subject": "CN=Demo Intermediate, O=Packetrove Synthetic Examples",
                          "issuer": "CN=Demo Root A, O=Packetrove Synthetic Examples",
                          "commonName": "Demo Intermediate",
                          "serialNumber": "03",
                          "sans": [],
                          "notBefore": "2020-01-01T00:00:00.000Z",
                          "notAfter": "2040-01-01T00:00:00.000Z",
                          "ca": true,
                          "basicConstraintsPresent": true,
                          "keyCertSign": true,
                          "fingerprintSha256": "50:0B:A0:34:32:D4:4E:BB:D0:9C:4F:D8:14:47:1B:9B:63:82:C8:1C:72:D5:CE:88:AB:7C:3D:7D:49:22:AB:46",
                          "signatureAlgorithm": "ECDSA / SHA-256",
                          "selfSignature": null
                        }
                      ],
                      "relationships": [
                        {
                          "childIndex": 0,
                          "issuerIndex": 1,
                          "signature": "verified",
                          "issuerEligible": true,
                          "keyIdentifierMatch": true
                        }
                      ],
                      "leafIndexes": [
                        0
                      ],
                      "selectedLeafIndex": 0,
                      "hostname": {
                        "expected": "service.example.com",
                        "status": "matched"
                      },
                      "findings": [
                        {
                          "code": "ISSUER_NOT_IN_BUNDLE",
                          "severity": "info",
                          "certificateIndexes": [
                            1
                          ],
                          "observed": "No certificate with the encoded issuer name was found in this input.",
                          "evidence": {
                            "issuer": "CN=Demo Root A, O=Packetrove Synthetic Examples"
                          },
                          "nextAction": "If a server actually serves this bundle, check its full-chain configuration. Roots are normally omitted; this observation alone does not prove a broken chain."
                        },
                        {
                          "code": "HOSTNAME_MATCH",
                          "severity": "info",
                          "certificateIndexes": [
                            0
                          ],
                          "observed": "The expected hostname matches a DNS SAN on the selected leaf.",
                          "evidence": {
                            "expectedHostname": "service.example.com",
                            "dnsSubjectAlternativeNames": "service.example.com, *.example.net"
                          },
                          "nextAction": "This identity check does not establish chain validity or client trust."
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/CertificateBundleResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, empty or malformed PEM/DER, rejected private-key or unsupported blocks, input limits, invalid hostname, or invalid leaf selection. PEM issues include original line and UTF-16 offsets without echoing input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Method is not supported for this endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 64 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "415": {
            "description": "Expected an application/json request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/public-ip": {
      "get": {
        "operationId": "public-ip",
        "tags": [
          "IP"
        ],
        "summary": "Get the IP address observed for the current request",
        "description": "Returns one IPv4 or IPv6 address from the current connection to Packetrove. Request Accept: text/plain for the address followed by a newline; JSON is the default. Errors remain structured JSON in either format. With a VPN or proxy this is its exit address. A hosted caller observes its own connection, not a user device behind it. It does not discover local addresses or separately probe both address families. The Cloudflare deployment reads edge-provided connection headers, including preserved IPv6 when Pseudo IPv4 overwrites headers. Results and errors are not cached; the application does not store or log the returned IP address.",
        "security": [],
        "responses": {
          "200": {
            "description": "The observed address as JSON with its address family, or as plain text when requested.",
            "headers": {
              "Cache-Control": {
                "description": "Do not store this per-request result.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Vary": {
                "description": "The response format depends on the Accept header.",
                "schema": {
                  "type": "string",
                  "const": "Accept"
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "example1": {
                    "summary": "IPv4",
                    "value": {
                      "ip": "203.0.113.1",
                      "family": "ipv4"
                    }
                  },
                  "example2": {
                    "summary": "IPv6",
                    "value": {
                      "ip": "2001:db8::1",
                      "family": "ipv6"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/PublicIpResult"
                }
              },
              "text/plain": {
                "examples": {
                  "ipv4": {
                    "value": "203.0.113.1\n"
                  },
                  "ipv6": {
                    "value": "2001:db8::1\n"
                  }
                },
                "schema": {
                  "type": "string",
                  "description": "One IPv4 or IPv6 address followed by a newline."
                }
              }
            }
          },
          "405": {
            "description": "Method is not supported for this endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "CLIENT_IP_UNAVAILABLE: edge connection information is missing or invalid. No guessed or caller-supplied forwarded address is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Platform"
        ],
        "summary": "Check service health",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResult"
                }
              }
            }
          },
          "405": {
            "description": "Method is not supported for this endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiSpecification",
        "tags": [
          "Platform"
        ],
        "summary": "Read the OpenAPI specification",
        "security": [],
        "responses": {
          "200": {
            "description": "The OpenAPI 3.1.0 document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "405": {
            "description": "Method is not supported for this endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
