{
  "openapi": "3.0.3",
  "info": {
    "title": "QNAS API",
    "version": "2.0.0",
    "description": "Qatar National Address System utility service by NBOX.qa. Provides address lookup and zone identification capabilities for Qatar addresses using the official QNAS system.",
    "contact": {
      "name": "NBOX.qa",
      "url": "https://nbox.qa"
    }
  },
  "servers": [
    {
      "url": "/",
      "description": "Current server"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API authentication token. Include as: Authorization: Bearer <token>"
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          }
        },
        "required": [
          "status"
        ]
      },
      "SearchSuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "$ref": "#/components/schemas/AddressResult"
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "AddressResult": {
        "type": "object",
        "properties": {
          "zone": {
            "type": "string"
          },
          "street": {
            "type": "string"
          },
          "building": {
            "type": "string"
          },
          "lat": {
            "type": "number"
          },
          "lng": {
            "type": "number"
          },
          "cached": {
            "type": "boolean"
          }
        },
        "required": [
          "zone",
          "street",
          "building",
          "lat",
          "lng",
          "cached"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "message": {
            "type": "string"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "message"
        ]
      },
      "RateLimitErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "message": {
            "type": "string"
          },
          "retryAfter": {
            "type": "number",
            "description": "Seconds until the rate limit window resets"
          }
        },
        "required": [
          "success",
          "message",
          "retryAfter"
        ]
      },
      "ZoneLookupSuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "$ref": "#/components/schemas/ZoneInfo"
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "ZoneInfo": {
        "type": "object",
        "properties": {
          "zone_number": {
            "type": "string"
          },
          "name_en": {
            "type": "string"
          },
          "name_ar": {
            "type": "string"
          },
          "classification": {
            "$ref": "#/components/schemas/Classification"
          },
          "street": {
            "$ref": "#/components/schemas/StreetInfo"
          },
          "building": {
            "$ref": "#/components/schemas/BuildingInfo"
          },
          "confidence": {
            "$ref": "#/components/schemas/Confidence"
          }
        },
        "required": [
          "zone_number",
          "name_en",
          "name_ar",
          "classification",
          "confidence"
        ]
      },
      "Classification": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "description": "Zone category (e.g. \"zone_a\", \"zone_b\")"
          },
          "location": {
            "type": "string",
            "description": "Zone location (e.g. \"inside_doha\", \"outside_doha\")"
          }
        }
      },
      "StreetInfo": {
        "type": "object",
        "nullable": true,
        "properties": {
          "street_number": {
            "type": "string"
          },
          "name_en": {
            "type": "string"
          },
          "name_ar": {
            "type": "string"
          }
        },
        "required": [
          "street_number",
          "name_en",
          "name_ar"
        ]
      },
      "BuildingInfo": {
        "type": "object",
        "nullable": true,
        "properties": {
          "building_number": {
            "type": "string"
          },
          "lat": {
            "type": "number"
          },
          "lng": {
            "type": "number"
          }
        },
        "required": [
          "building_number",
          "lat",
          "lng"
        ]
      },
      "Confidence": {
        "type": "object",
        "properties": {
          "zone": {
            "$ref": "#/components/schemas/MatchConfidence"
          },
          "street": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MatchConfidence"
              },
              {
                "nullable": true
              }
            ]
          },
          "building": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MatchConfidence"
              },
              {
                "nullable": true
              }
            ]
          }
        },
        "required": [
          "zone"
        ]
      },
      "MatchConfidence": {
        "type": "object",
        "properties": {
          "match": {
            "type": "string",
            "enum": [
              "exact",
              "nearest"
            ],
            "description": "Whether the result is an exact polygon match or nearest-centroid estimate"
          },
          "distance_km": {
            "type": "number",
            "description": "Distance from query point to matched entity centroid in km. 0 for exact matches."
          }
        },
        "required": [
          "match",
          "distance_km"
        ]
      },
      "ZonesSuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "count": {
            "type": "number"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ZoneGrouped"
            }
          }
        },
        "required": [
          "success",
          "count",
          "data"
        ]
      },
      "ZoneGrouped": {
        "type": "object",
        "properties": {
          "zone_number": {
            "type": "string"
          },
          "neighborhoods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Neighborhood"
            }
          },
          "has_polygon": {
            "type": "boolean"
          },
          "polygon": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PolygonPoint"
            }
          },
          "classifications": {
            "$ref": "#/components/schemas/ZoneClassifications"
          }
        },
        "required": [
          "zone_number",
          "neighborhoods",
          "has_polygon"
        ]
      },
      "Neighborhood": {
        "type": "object",
        "properties": {
          "name_en": {
            "type": "string"
          },
          "name_ar": {
            "type": "string"
          }
        },
        "required": [
          "name_en",
          "name_ar"
        ]
      },
      "PolygonPoint": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number"
          },
          "lng": {
            "type": "number"
          }
        },
        "required": [
          "lat",
          "lng"
        ]
      },
      "ZoneClassifications": {
        "type": "object",
        "additionalProperties": {}
      },
      "SyncResponse": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/SyncListResponse"
          },
          {
            "$ref": "#/components/schemas/SyncPolygonsResponse"
          },
          {
            "$ref": "#/components/schemas/SyncStreetPolygonsResponse"
          },
          {
            "$ref": "#/components/schemas/SyncBuildingsResponse"
          },
          {
            "$ref": "#/components/schemas/SyncAllResponse"
          }
        ]
      },
      "SyncListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "message": {
            "type": "string"
          },
          "phase": {
            "type": "string",
            "enum": [
              "list"
            ]
          },
          "inserted": {
            "type": "number"
          },
          "updated": {
            "type": "number"
          }
        },
        "required": [
          "success",
          "message",
          "phase",
          "inserted",
          "updated"
        ]
      },
      "SyncPolygonsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "message": {
            "type": "string"
          },
          "phase": {
            "type": "string",
            "enum": [
              "polygons"
            ]
          },
          "synced": {
            "type": "number"
          },
          "failed": {
            "type": "number"
          },
          "skipped": {
            "type": "number"
          }
        },
        "required": [
          "success",
          "message",
          "phase",
          "synced",
          "failed",
          "skipped"
        ]
      },
      "SyncStreetPolygonsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "message": {
            "type": "string"
          },
          "phase": {
            "type": "string",
            "enum": [
              "street-polygons"
            ]
          },
          "synced": {
            "type": "number"
          },
          "failed": {
            "type": "number"
          },
          "skipped": {
            "type": "number"
          }
        },
        "required": [
          "success",
          "message",
          "phase",
          "synced",
          "failed",
          "skipped"
        ]
      },
      "SyncBuildingsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "message": {
            "type": "string"
          },
          "phase": {
            "type": "string",
            "enum": [
              "buildings"
            ]
          },
          "synced": {
            "type": "number"
          },
          "failed": {
            "type": "number"
          }
        },
        "required": [
          "success",
          "message",
          "phase",
          "synced",
          "failed"
        ]
      },
      "SyncAllResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "message": {
            "type": "string"
          },
          "synced": {
            "type": "number"
          },
          "failed": {
            "type": "number"
          }
        },
        "required": [
          "success",
          "message",
          "synced",
          "failed"
        ]
      },
      "SyncStatusResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "zonesInDatabase": {
            "type": "number"
          }
        },
        "required": [
          "success",
          "zonesInDatabase"
        ]
      },
      "SmartSearchSuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "$ref": "#/components/schemas/SmartSearchResult"
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "SmartSearchResult": {
        "type": "object",
        "properties": {
          "coordinates": {
            "$ref": "#/components/schemas/SmartSearchCoordinates"
          },
          "resolution_method": {
            "$ref": "#/components/schemas/ResolutionMethod"
          },
          "qnas": {
            "$ref": "#/components/schemas/SmartSearchQnas"
          },
          "google": {
            "$ref": "#/components/schemas/SmartSearchGoogle"
          },
          "in_qatar": {
            "type": "boolean",
            "description": "Whether the resolved coordinates fall within Qatar"
          }
        },
        "required": [
          "coordinates",
          "resolution_method",
          "qnas",
          "in_qatar"
        ]
      },
      "SmartSearchCoordinates": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number"
          },
          "lng": {
            "type": "number"
          }
        },
        "required": [
          "lat",
          "lng"
        ]
      },
      "ResolutionMethod": {
        "type": "string",
        "enum": [
          "map_url",
          "coordinates",
          "qnas_structured",
          "google_geocoding"
        ]
      },
      "SmartSearchQnas": {
        "type": "object",
        "nullable": true,
        "properties": {
          "zone": {
            "$ref": "#/components/schemas/SmartSearchZone"
          },
          "street": {
            "$ref": "#/components/schemas/SmartSearchStreet"
          },
          "building": {
            "$ref": "#/components/schemas/SmartSearchBuilding"
          },
          "confidence": {
            "$ref": "#/components/schemas/SmartSearchConfidence"
          }
        },
        "required": [
          "zone",
          "street",
          "building",
          "confidence"
        ]
      },
      "SmartSearchZone": {
        "type": "object",
        "nullable": true,
        "properties": {
          "zone_number": {
            "type": "string"
          },
          "name_en": {
            "type": "string"
          },
          "name_ar": {
            "type": "string"
          },
          "classification": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "zone_number",
          "name_en",
          "name_ar"
        ]
      },
      "SmartSearchStreet": {
        "type": "object",
        "nullable": true,
        "properties": {
          "street_number": {
            "type": "string"
          },
          "name_en": {
            "type": "string"
          },
          "name_ar": {
            "type": "string"
          }
        },
        "required": [
          "street_number",
          "name_en",
          "name_ar"
        ]
      },
      "SmartSearchBuilding": {
        "type": "object",
        "nullable": true,
        "properties": {
          "building_number": {
            "type": "string"
          },
          "lat": {
            "type": "number"
          },
          "lng": {
            "type": "number"
          }
        },
        "required": [
          "building_number",
          "lat",
          "lng"
        ]
      },
      "SmartSearchConfidence": {
        "type": "object",
        "nullable": true,
        "properties": {
          "zone": {
            "$ref": "#/components/schemas/MatchConfidence"
          },
          "street": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MatchConfidence"
              },
              {
                "nullable": true
              }
            ]
          },
          "building": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MatchConfidence"
              },
              {
                "nullable": true
              }
            ]
          }
        },
        "required": [
          "zone"
        ]
      },
      "SmartSearchGoogle": {
        "type": "object",
        "nullable": true,
        "properties": {
          "formatted_address": {
            "type": "string"
          },
          "place_id": {
            "type": "string"
          }
        },
        "required": [
          "formatted_address",
          "place_id"
        ]
      },
      "SearchMode": {
        "type": "string",
        "enum": [
          "smart",
          "qnas",
          "google"
        ],
        "default": "smart",
        "description": "Search strategy: smart (all strategies), qnas (QNAS structured only), google (Google Geocoding only)"
      }
    },
    "parameters": {}
  },
  "paths": {
    "/api/health": {
      "get": {
        "summary": "Health check",
        "description": "Returns the health status of the API. No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "summary": "Search address",
        "description": "Search for a Qatar address and retrieve its GPS coordinates. Results are cached for faster subsequent lookups.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Zone number (e.g. \"61\")"
            },
            "required": true,
            "description": "Zone number (e.g. \"61\")",
            "name": "zone",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Street number (e.g. \"123\")"
            },
            "required": true,
            "description": "Street number (e.g. \"123\")",
            "name": "street",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Building number (e.g. \"45\")"
            },
            "required": true,
            "description": "Building number (e.g. \"45\")",
            "name": "building",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Address found",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing required parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Address not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — too many requests in the current window",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/zone": {
      "get": {
        "summary": "Lookup zone by coordinates",
        "description": "Get zone information for GPS coordinates using point-in-polygon algorithm. Always includes zone classification. Use the 'detail' parameter to include street and building information.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Latitude coordinate (e.g. \"25.286106\")"
            },
            "required": true,
            "description": "Latitude coordinate (e.g. \"25.286106\")",
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Longitude coordinate (e.g. \"51.534817\")"
            },
            "required": true,
            "description": "Longitude coordinate (e.g. \"51.534817\")",
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "street",
                "full"
              ],
              "description": "Level of detail: 'street' includes street info, 'full' includes street + nearest building"
            },
            "required": false,
            "description": "Level of detail: 'street' includes street info, 'full' includes street + nearest building",
            "name": "detail",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Zone found",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZoneLookupSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid coordinates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No zone found for the given coordinates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — too many requests in the current window",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/zones": {
      "get": {
        "summary": "List all zones",
        "description": "List all zones grouped by zone number with their neighborhoods. Optionally includes polygon data.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ],
              "description": "Whether to include polygon data in the response"
            },
            "required": false,
            "description": "Whether to include polygon data in the response",
            "name": "include_polygon",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List of zones",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZonesSuccessResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — too many requests in the current window",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/sync/zones": {
      "post": {
        "summary": "Sync zone data",
        "description": "Synchronize zone data from the official QNAS API to the local database. Use phase=\"list\" for zone list only, phase=\"polygons\" for polygon data only, or omit for a full sync.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "list",
                "polygons",
                "street-polygons",
                "buildings"
              ],
              "description": "Sync phase to run. \"list\" syncs zone list, \"polygons\" syncs zone polygon data, \"street-polygons\" syncs street polygon data. Omit for full sync."
            },
            "required": false,
            "description": "Sync phase to run. \"list\" syncs zone list, \"polygons\" syncs zone polygon data, \"street-polygons\" syncs street polygon data. Omit for full sync.",
            "name": "phase",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Sync completed successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — too many requests in the current window",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Sync failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/sync/status": {
      "get": {
        "summary": "Sync status",
        "description": "Get the current number of zones stored in the database.",
        "responses": {
          "200": {
            "description": "Current sync status",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncStatusResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — too many requests in the current window",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/smartsearch": {
      "get": {
        "summary": "Smart search",
        "description": "Intelligent search that accepts any freeform input — map URLs, coordinates (decimal/DMS), zone/street/building patterns, or place names — and resolves it to GPS coordinates with QNAS address data. Uses a resolution pipeline: URL parsing → coordinate detection → QNAS structured search → Google Geocoding fallback.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Freeform search input: coordinates, map URL, zone/street/building, or place name"
            },
            "required": true,
            "description": "Freeform search input: coordinates, map URL, zone/street/building, or place name",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "$ref": "#/components/schemas/SearchMode"
            },
            "required": false,
            "description": "Search strategy: smart (all strategies), qnas (QNAS structured only), google (Google Geocoding only)",
            "name": "mode",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Location resolved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmartSearchSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid query parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Could not resolve the input to a location",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — too many requests in the current window",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Maximum number of requests allowed per window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of requests remaining in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp (seconds) when the current window resets"
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  }
}