{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://propbot.org/schemas/openpmx-json-draft.schema.json",
  "title": "PropBot JSON property pull \u2014 engine 2 shape, name not chosen",
  "description": "Working JSON document a realtor site serves for PropBot to pull. The public name is not chosen. Version marker is engine2-0.2. PropBot sends the access token on the request; the document has no credential. Query since with an update time and return only newer listings. An empty properties array, or HTTP 304, means nothing changed. A listing omitted from the document is left unchanged. Set status to Closed or Withdrawn to remove a listing from the market. This is not the OpenPMX XML file.",
  "type": "object",
  "required": [
    "schemaVersion",
    "publisherId",
    "generatedAt",
    "mode",
    "properties"
  ],
  "additionalProperties": false,
  "properties": {
    "schemaVersion": {
      "const": "engine2-0.2"
    },
    "publisherId": {
      "type": "string",
      "minLength": 1,
      "description": "Stable publisher key chosen by the realtor site. Not a PropBot account id."
    },
    "generatedAt": {
      "type": "string",
      "format": "date-time"
    },
    "mode": {
      "const": "upsert"
    },
    "properties": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/property"
      }
    }
  },
  "$defs": {
    "property": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "externalId",
        "updatedAt",
        "status",
        "category",
        "typeId"
      ],
      "properties": {
        "externalId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 96
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time"
        },
        "status": {
          "enum": [
            "Incomplete",
            "Active",
            "Closed",
            "Contingent",
            "Contingent Accepting Backup Offers",
            "Expired",
            "Pending",
            "Pending Accepting Backup Offers",
            "Temporary Off Market",
            "Withdrawn"
          ]
        },
        "category": {
          "enum": [
            "cfs",
            "cfl",
            "lfs",
            "rfs",
            "rfr"
          ]
        },
        "listingIntent": {
          "enum": [
            "for_sale",
            "for_rent"
          ]
        },
        "typeId": {
          "type": "integer",
          "enum": [
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26,
            27,
            28,
            29,
            30,
            31,
            32,
            33,
            34,
            35,
            36,
            37,
            38,
            39,
            40,
            41,
            42,
            43,
            44,
            45,
            46,
            47,
            48,
            49,
            50,
            51,
            52,
            53,
            54,
            55,
            56,
            57,
            58,
            59,
            60,
            61,
            62,
            63,
            64,
            65,
            66,
            67,
            68,
            69,
            70,
            71,
            72,
            73,
            74,
            75,
            76,
            77,
            78,
            79,
            80,
            81,
            82,
            83,
            84,
            85,
            86,
            87,
            88,
            89,
            90,
            91,
            92,
            93,
            94,
            95,
            96,
            97,
            98,
            99,
            100,
            101,
            102
          ]
        },
        "title": {
          "type": "string",
          "minLength": 1
        },
        "description": {
          "type": "string"
        },
        "address": {
          "$ref": "#/$defs/address"
        },
        "price": {
          "$ref": "#/$defs/money"
        },
        "bedrooms": {
          "type": "integer",
          "minimum": 0
        },
        "bathrooms": {
          "type": "number",
          "minimum": 0
        },
        "interiorSqft": {
          "type": "number",
          "minimum": 0
        },
        "lotSizeSqft": {
          "type": "number",
          "minimum": 0
        },
        "yearBuilt": {
          "type": "integer"
        },
        "latitude": {
          "type": "number",
          "minimum": -90,
          "maximum": 90
        },
        "longitude": {
          "type": "number",
          "minimum": -180,
          "maximum": 180
        },
        "images": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/image"
          }
        },
        "contact": {
          "$ref": "#/$defs/contact"
        },
        "mls": {
          "type": "string"
        },
        "available": {
          "type": "string",
          "format": "date"
        },
        "interiors": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/interior"
          }
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "status": {
                "enum": [
                  "Active",
                  "Pending",
                  "Contingent",
                  "Pending Accepting Backup Offers",
                  "Contingent Accepting Backup Offers"
                ]
              }
            },
            "required": [
              "status"
            ]
          },
          "then": {
            "required": [
              "title",
              "address",
              "latitude",
              "longitude",
              "listingIntent"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "listingIntent": {
                "const": "for_sale"
              }
            },
            "required": [
              "listingIntent"
            ]
          },
          "then": {
            "required": [
              "price"
            ]
          }
        }
      ],
      "not": {
        "description": "The unset map pin 0,0 is not a location.",
        "required": [
          "latitude",
          "longitude"
        ],
        "properties": {
          "latitude": {
            "const": 0
          },
          "longitude": {
            "const": 0
          }
        }
      }
    },
    "address": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "line1",
        "locality",
        "region",
        "postalCode",
        "country"
      ],
      "properties": {
        "line1": {
          "type": "string",
          "minLength": 1
        },
        "locality": {
          "type": "string",
          "minLength": 1
        },
        "region": {
          "type": "string",
          "minLength": 1
        },
        "postalCode": {
          "type": "string",
          "minLength": 1
        },
        "country": {
          "type": "string",
          "minLength": 2
        }
      }
    },
    "money": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "amount",
        "currency"
      ],
      "properties": {
        "amount": {
          "type": "number",
          "minimum": 0
        },
        "currency": {
          "type": "string",
          "minLength": 3,
          "maxLength": 3
        }
      }
    },
    "image": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "url"
      ],
      "properties": {
        "url": {
          "type": "string",
          "pattern": "^https://"
        },
        "caption": {
          "type": "string"
        },
        "isPrimary": {
          "type": "boolean"
        }
      }
    },
    "contact": {
      "type": "object",
      "additionalProperties": false,
      "description": "Public contact the publisher chooses to show. Omit private owner details.",
      "properties": {
        "name": {
          "type": "string"
        },
        "phone": {
          "type": "string"
        },
        "email": {
          "type": "string",
          "format": "email"
        },
        "website": {
          "type": "string",
          "pattern": "^https://"
        }
      }
    },
    "interior": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "externalId",
        "typeId"
      ],
      "properties": {
        "externalId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 96
        },
        "typeId": {
          "type": "integer",
          "enum": [
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26,
            27,
            28,
            29,
            30,
            31,
            32,
            33,
            34,
            35,
            36,
            37,
            38,
            39,
            40,
            41,
            42,
            43,
            44,
            45,
            46,
            47,
            48,
            49,
            50,
            51,
            52,
            53,
            54,
            55,
            56,
            57,
            58,
            59,
            60,
            61,
            62,
            63,
            64,
            65,
            66,
            67,
            68,
            69,
            70,
            71,
            72,
            73,
            74,
            75,
            76,
            77,
            78,
            79,
            80,
            81,
            82,
            83,
            84,
            85,
            86,
            87,
            88,
            89,
            90,
            91,
            92,
            93,
            94,
            95,
            96,
            97,
            98,
            99,
            100,
            101,
            102
          ]
        },
        "title": {
          "type": "string"
        },
        "sqft": {
          "type": "number",
          "minimum": 0
        },
        "bedrooms": {
          "type": "integer",
          "minimum": 0
        },
        "bathrooms": {
          "type": "number",
          "minimum": 0
        },
        "price": {
          "$ref": "#/$defs/money"
        },
        "rentType": {
          "enum": [
            "$/Day",
            "$/Week",
            "$/BiWeek",
            "$/Month",
            "$/Year",
            "$/SF/Year",
            "$/SF/Month"
          ]
        }
      }
    }
  }
}
