{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/propertyindex-ae/json-schema/propertyindex-ae-sale-list-schema.json",
  "title": "SaleList",
  "x-generated": "2026-11-07",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/propertyindex-ae-openapi.json#/components/schemas/SaleList",
  "type": "object",
  "required": [
    "data",
    "next_cursor",
    "as_of",
    "total",
    "page",
    "limit"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Sale"
      }
    },
    "next_cursor": {
      "type": [
        "string",
        "null"
      ],
      "description": "Returned for cursor and numbered pages when more data exists. Pass as cursor to fetch the next page, removing page and preserving sort, order and filters. null on the last page."
    },
    "as_of": {
      "type": [
        "string",
        "null"
      ],
      "format": "date",
      "description": "The DLD delivery date the data was built from."
    },
    "total": {
      "type": "integer",
      "minimum": 0,
      "description": "Exact number of records matching all filters, including q, location_search and location scopes where supported. Ignores page, limit and cursor. Always included, even on empty pages. Not a snapshot: can change after a data refresh."
    },
    "page": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 1,
      "maximum": 9007199254740991,
      "description": "Requested numbered page, or 1 when neither page nor cursor was supplied. null for cursor requests because a cursor position is not a numbered page."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 1000,
      "description": "Requested page size, or 100 when omitted. This is the maximum rows requested, not the actual number returned; data can contain fewer rows."
    }
  },
  "$defs": {
    "Sale": {
      "type": "object",
      "description": "Registered DLD sale records resolved to the property's own location node.",
      "properties": {
        "sale_id": {
          "type": "string",
          "description": "Opaque public identifier of this sale record. Stable; use it with the single-record endpoint. It carries no meaning outside this API."
        },
        "highest_location_level": {
          "type": [
            "string",
            "null"
          ],
          "description": "First location after Dubai in the record's breadcrumb, regardless of location kind. For Dubai > Dubai Harbour > Emaar Beachfront > Beach Vista > Beach Vista Tower 1, this is Dubai Harbour. Null when no location below the city is known."
        },
        "lowest_location_level": {
          "type": [
            "string",
            "null"
          ],
          "description": "Final assigned location in the record's breadcrumb. This may be an area, community, subcommunity or building, rather than a physical building. For Dubai > Dubai Harbour > Emaar Beachfront > Beach Vista > Beach Vista Tower 1, this is Beach Vista Tower 1. Labels are not unique. Null when no location is known."
        },
        "location_path": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          },
          "minItems": 1,
          "description": "Ordered location labels from Dubai to the record's assigned location, following the published location hierarchy. For a record assigned to Beach Vista Tower 1 this is [\"Dubai\", \"Dubai Harbour\", \"Emaar Beachfront\", \"Beach Vista\", \"Beach Vista Tower 1\"]. When present, it starts with Dubai and ends with lowest_location_level, and any second element equals highest_location_level. Labels only: names are not unique and are not identifiers. Null when the location cannot be resolved. Returned only; not a filter, sort or cursor field."
        },
        "floor": {
          "type": [
            "string",
            "null"
          ],
          "description": "Registered floor label, as text: numeric floors plus values such as 'G' or 'P'-prefixed podium levels. Null for houses and unresolved records."
        },
        "sale_date": {
          "type": [
            "string",
            "null"
          ],
          "format": "date",
          "description": "DLD registration date."
        },
        "property_type": {
          "type": [
            "string",
            "null"
          ],
          "description": "Normalized property type. Known values: Apartment, Building, Clinic, Hotel Apartment, Hotel Room, Land, Office, Other Commercial, Parking, Shop, Villa, Warehouse."
        },
        "bedrooms": {
          "type": [
            "string",
            "null"
          ],
          "description": "Normalized bedroom label; empty when the record carries no bedroom count. Known values: Studio, 1 Bed, 2 Bed, 3 Bed, 4 Bed, 5 Bed, 6 Bed, 7 Bed, 8 Bed, 9 Bed, 10 Bed, 11 Bed, 15 Bed, Penthouse, Duplex."
        },
        "sale_price": {
          "type": [
            "number",
            "null"
          ],
          "description": "Registered sale price. Unit: AED."
        },
        "sale_psf": {
          "type": [
            "number",
            "null"
          ],
          "description": "Registered sale price per square foot. Unit: AED/sqft."
        },
        "size_sqft": {
          "type": [
            "number",
            "null"
          ],
          "description": "Registered property size. Unit: sqft."
        },
        "market_basis": {
          "type": [
            "string",
            "null"
          ],
          "description": "DLD registration category. A delayed handover still registers as off_plan. Known values: existing, off_plan."
        },
        "procedure": {
          "type": [
            "string",
            "null"
          ],
          "description": "DLD transaction procedure name."
        },
        "financed": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "Whether a mortgage was registered on the property the same day."
        }
      }
    }
  }
}