{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://quadruper.invalid/contracts/geoapi-geocode-query.v1.schema.json",
  "title": "GeocodeQuery",
  "description": "GET /v2/geocode query, parsed. Either q or at least one structured field; never near with near_text.",
  "type": "object",
  "properties": {
    "q": { "type": "string", "minLength": 1, "maxLength": 200 },
    "street": { "type": "string", "minLength": 1, "maxLength": 200 },
    "house_number": { "type": "string", "minLength": 1, "maxLength": 20 },
    "city": { "type": "string", "minLength": 1, "maxLength": 100 },
    "county": { "type": "string", "minLength": 1, "maxLength": 100 },
    "state": { "type": "string", "minLength": 1, "maxLength": 100 },
    "postcode": { "type": "string", "minLength": 1, "maxLength": 20 },
    "country_code": { "type": "string", "pattern": "^[a-z]{2}$" },
    "limit": { "type": "integer", "minimum": 1, "maximum": 10 },
    "lang": { "type": "string", "pattern": "^[a-z]{2}$" },
    "near": { "$ref": "geoapi-common.v1.schema.json#/$defs/lnglat" },
    "near_text": { "type": "string", "minLength": 1, "maxLength": 200 },
    "bbox": { "$ref": "geoapi-common.v1.schema.json#/$defs/bbox" }
  },
  "additionalProperties": false,
  "allOf": [
    { "not": { "required": ["near", "near_text"] } },
    {
      "oneOf": [
        {
          "required": ["q"],
          "not": {
            "anyOf": [
              { "required": ["street"] }, { "required": ["house_number"] }, { "required": ["city"] },
              { "required": ["county"] }, { "required": ["state"] }, { "required": ["postcode"] },
              { "required": ["country_code"] }
            ]
          }
        },
        {
          "not": { "required": ["q"] },
          "anyOf": [
            { "required": ["street"] }, { "required": ["house_number"] }, { "required": ["city"] },
            { "required": ["county"] }, { "required": ["state"] }, { "required": ["postcode"] },
            { "required": ["country_code"] }
          ]
        }
      ]
    }
  ]
}
