{
  "openapi": "3.0.3",
  "info": {
    "title": "ZIP Code API",
    "version": "1.0.0",
    "description": "REST API for US ZIP code lookups, radius search, city/state exploration, and geographic data. Powered by GeoNames."
  },
  "servers": [
    {
      "url": "https://api.apibarn.com/v1/zipcode",
      "description": "Production"
    },
    {
      "url": "http://localhost:4300",
      "description": "Local development"
    }
  ],
  "tags": [
    { "name": "Health" },
    { "name": "Stats" },
    { "name": "Lookup" },
    { "name": "Search" },
    { "name": "States" },
    { "name": "Cities" }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {
      "ZipcodeRecord": {
        "type": "object",
        "properties": {
          "zip":        { "type": "string", "example": "90210" },
          "city":       { "type": "string", "example": "Beverly Hills" },
          "stateCode":  { "type": "string", "example": "CA" },
          "stateName":  { "type": "string", "example": "California" },
          "county":     { "type": "string", "example": "Los Angeles" },
          "countyFips": { "type": "string", "nullable": true, "example": "06037" },
          "lat":        { "type": "number", "example": 34.0901 },
          "lng":        { "type": "number", "example": -118.4065 },
          "lastUpdated":{ "type": "string", "format": "date-time" }
        }
      },
      "NearbyResult": {
        "allOf": [
          { "$ref": "#/components/schemas/ZipcodeRecord" },
          {
            "type": "object",
            "properties": {
              "distanceMiles": { "type": "number", "example": 2.1 }
            }
          }
        ]
      }
    }
  },
  "security": [{ "ApiKeyHeader": [] }],
  "paths": {
    "/health": {
      "get": {
        "tags": ["Health"],
        "summary": "Health check",
        "security": [],
        "responses": {
          "200": {
            "description": "Service health",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status":    { "type": "string", "example": "ok" },
                    "service":   { "type": "string", "example": "zipcode-api" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/stats": {
      "get": {
        "tags": ["Stats"],
        "summary": "Dataset statistics",
        "description": "Returns the total number of ZIP codes and states in the database.",
        "responses": {
          "200": {
            "description": "Stats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "totalZips":   { "type": "integer", "example": 42129 },
                    "totalStates": { "type": "integer", "example": 51 }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/zip/{zip}": {
      "get": {
        "tags": ["Lookup"],
        "summary": "Get a single ZIP code",
        "parameters": [
          {
            "name": "zip",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "90210" },
            "description": "5-digit US ZIP code"
          }
        ],
        "responses": {
          "200": {
            "description": "ZIP code record",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ZipcodeRecord" }
              }
            }
          },
          "404": { "description": "ZIP code not found" }
        }
      }
    },
    "/api/zip/{zip}/nearby": {
      "get": {
        "tags": ["Lookup"],
        "summary": "Find nearby ZIP codes",
        "description": "Returns ZIP codes within a given radius of the specified ZIP, sorted by distance ascending.",
        "parameters": [
          {
            "name": "zip",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "10001" }
          },
          {
            "name": "radiusMiles",
            "in": "query",
            "schema": { "type": "number", "default": 25, "maximum": 200 },
            "description": "Search radius in miles"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 50, "maximum": 200 },
            "description": "Maximum number of results"
          }
        ],
        "responses": {
          "200": {
            "description": "Nearby ZIPs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "center": {
                      "type": "object",
                      "properties": {
                        "zip": { "type": "string" },
                        "lat": { "type": "number" },
                        "lng": { "type": "number" }
                      }
                    },
                    "radiusMiles": { "type": "number" },
                    "results": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/NearbyResult" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "tags": ["Search"],
        "summary": "Search ZIP codes",
        "description": "Full-text search across city, county, and state. Supports pagination.",
        "parameters": [
          { "name": "q",      "in": "query", "schema": { "type": "string" }, "description": "General keyword" },
          { "name": "city",   "in": "query", "schema": { "type": "string" }, "description": "City name (case-insensitive contains)" },
          { "name": "state",  "in": "query", "schema": { "type": "string" }, "description": "2-letter state code" },
          { "name": "county", "in": "query", "schema": { "type": "string" }, "description": "County name" },
          { "name": "limit",  "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "total":   { "type": "integer" },
                    "limit":   { "type": "integer" },
                    "offset":  { "type": "integer" },
                    "results": { "type": "array", "items": { "$ref": "#/components/schemas/ZipcodeRecord" } }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/states": {
      "get": {
        "tags": ["States"],
        "summary": "List all US states",
        "description": "Returns all states/territories with ZIP code counts.",
        "responses": {
          "200": {
            "description": "State list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "stateCode": { "type": "string", "example": "CA" },
                      "stateName": { "type": "string", "example": "California" },
                      "zipCount":  { "type": "integer", "example": 2647 }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/states/{state}/zipcodes": {
      "get": {
        "tags": ["States"],
        "summary": "Get ZIP codes for a state",
        "parameters": [
          { "name": "state",  "in": "path",  "required": true, "schema": { "type": "string", "example": "NY" } },
          { "name": "limit",  "in": "query", "schema": { "type": "integer", "default": 100 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": {
          "200": {
            "description": "ZIP codes for the state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stateCode": { "type": "string" },
                    "total":     { "type": "integer" },
                    "limit":     { "type": "integer" },
                    "offset":    { "type": "integer" },
                    "results":   { "type": "array", "items": { "$ref": "#/components/schemas/ZipcodeRecord" } }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/city/{city}": {
      "get": {
        "tags": ["Cities"],
        "summary": "Get ZIP codes for a city",
        "parameters": [
          { "name": "city",  "in": "path",  "required": true, "schema": { "type": "string", "example": "Portland" } },
          { "name": "state", "in": "query", "schema": { "type": "string" }, "description": "Optional 2-letter state code to disambiguate" }
        ],
        "responses": {
          "200": {
            "description": "ZIP codes for the city",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/ZipcodeRecord" }
                }
              }
            }
          }
        }
      }
    }
  }
}
