{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/cityparity-com/json-schema/cityparity-com-compare-request-schema.json",
  "title": "CompareRequest",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/_original/cityparity-com-api-openapi.json#/components/schemas/CompareRequest",
  "type": "object",
  "required": [
    "source_city",
    "target_city",
    "gross_salary"
  ],
  "properties": {
    "source_city": {
      "type": "string",
      "description": "City slug for the current city."
    },
    "target_city": {
      "type": "string",
      "description": "City slug for the destination city."
    },
    "gross_salary": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "User's annual gross salary in the SOURCE city's local currency."
    },
    "household": {
      "type": "object",
      "properties": {
        "has_partner": {
          "type": "boolean"
        },
        "partner_gross_salary": {
          "type": "number",
          "minimum": 0,
          "description": "In source-city currency. Required when has_partner=true."
        },
        "partner_works_in_source": {
          "type": "boolean",
          "description": "Required when has_partner=true; cityparity does not silently default this."
        },
        "partner_works_in_target": {
          "type": "boolean",
          "description": "Required when has_partner=true."
        },
        "kids_ages": {
          "type": "array",
          "items": {
            "type": "integer",
            "minimum": 0,
            "maximum": 25
          }
        }
      }
    },
    "living": {
      "type": "object",
      "properties": {
        "housing_mode": {
          "type": "string",
          "enum": [
            "rent",
            "own",
            "own_outright"
          ]
        },
        "bedrooms": {
          "type": "integer",
          "minimum": 0,
          "maximum": 5
        },
        "lifestyle": {
          "type": "string",
          "enum": [
            "frugal",
            "typical",
            "generous"
          ]
        }
      }
    },
    "advanced": {
      "type": "object",
      "properties": {
        "retirement_contrib_pct": {
          "type": "number",
          "minimum": 0,
          "maximum": 50
        },
        "age_bracket": {
          "type": "string",
          "enum": [
            "18-24",
            "25-34",
            "35-44",
            "45-54",
            "55-64"
          ]
        },
        "trips_home_per_year": {
          "type": "integer",
          "minimum": 0,
          "maximum": 12
        },
        "source_transit_choice": {
          "type": "string",
          "enum": [
            "car",
            "transit"
          ]
        },
        "target_transit_choice": {
          "type": "string",
          "enum": [
            "car",
            "transit"
          ]
        },
        "apply_inbound_regime": {
          "type": "boolean"
        }
      }
    },
    "score_weights": {
      "$ref": "#/$defs/ScoreWeights"
    }
  },
  "$defs": {
    "ScoreWeights": {
      "type": "object",
      "description": "Override composite-score weights. Defaults: financial 30, healthcare 20, vacation 15, childcare 15, safety_net 20.",
      "properties": {
        "financial": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        },
        "healthcare": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        },
        "vacation": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        },
        "childcare": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        },
        "safety_net": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        }
      }
    }
  }
}