{
  "openapi": "3.1.0",
  "info": {
    "title": "CleanedWeb Maintained Property API",
    "version": "2.0.0",
    "description": "Stable customer operations over the global property-profile-v2 contract. Workspace sessions and read-scoped API keys share the same canonical property profile."
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "servers": [
    {
      "url": "https://app.cleanedweb.com",
      "description": "CleanedWeb customer API"
    }
  ],
  "tags": [
    {
      "name": "Markets",
      "description": "Maintained markets available to the authenticated workspace."
    },
    {
      "name": "Properties",
      "description": "Canonical maintained properties and their finalized observed changes."
    }
  ],
  "security": [
    {
      "cookieAuth": []
    },
    {
      "bearerApiKey": []
    }
  ],
  "paths": {
    "/v1/markets": {
      "get": {
        "operationId": "listMarkets",
        "summary": "List available maintained markets",
        "description": "Returns only markets enabled for the authenticated workspace with maintained data ready to query.",
        "tags": ["Markets"],
        "responses": {
          "200": {
            "description": "Available maintained markets",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/MarketList"}
              }
            }
          },
          "401": {"$ref": "#/components/responses/Unauthorized"},
          "403": {"$ref": "#/components/responses/Forbidden"},
          "503": {"$ref": "#/components/responses/Unavailable"}
        }
      }
    },
    "/v1/properties/count": {
      "post": {
        "operationId": "countProperties",
        "summary": "Count matching maintained properties",
        "description": "Use this operation whenever the requested output is only a number; do not call property search merely to derive a total. Returns an exact count without retrieving rich property records. Results are cached by normalized filters and serving-projection generation, so a new projection can never reuse a stale count. This read-only aggregate does not consume delivery Units.",
        "tags": ["Properties"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {"$ref": "#/components/schemas/PropertyCountRequest"},
              "example": {
                "market": "ES",
                "response_schema": "property-profile-v2",
                "deal_type": ["buy"],
                "location": "Madrid",
                "max_price": 250000,
                "min_bedrooms": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Exact count from one ready serving-projection generation",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/PropertyCountResponse"}
              }
            }
          },
          "401": {"$ref": "#/components/responses/Unauthorized"},
          "403": {"$ref": "#/components/responses/Forbidden"},
          "422": {"$ref": "#/components/responses/InvalidRequest"},
          "429": {"$ref": "#/components/responses/RateLimited"},
          "503": {"$ref": "#/components/responses/Unavailable"}
        }
      }
    },
    "/v1/properties/search": {
      "post": {
        "operationId": "searchProperties",
        "summary": "Search maintained canonical properties",
        "description": "Searches one current maintained-data snapshot. A bounded request returns a signed next_cursor when more matches exist; browser sessions may still omit limit to stream every match. API-key requests must supply a bounded limit, max_units, and Idempotency-Key.",
        "tags": ["Properties"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Required for API-key requests; reuse only for an exact retry within 24 hours.",
            "schema": {"type": "string", "minLength": 1, "maxLength": 200}
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {"$ref": "#/components/schemas/PropertySearchRequest"},
              "examples": {
                "maintainedPropertySearch": {
                  "$ref": "#/components/examples/SearchRequest"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One maintained-property search page or complete unbounded response",
            "headers": {
              "Cache-Control": {
                "schema": {"type": "string"},
                "description": "Always no-store for workspace search responses."
              }
            },
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/PropertySearchResponse"},
                "examples": {
                  "maintainedPropertySearch": {
                    "$ref": "#/components/examples/SearchResponse"
                  }
                }
              }
            }
          },
          "401": {"$ref": "#/components/responses/Unauthorized"},
          "402": {"$ref": "#/components/responses/InsufficientUnits"},
          "403": {"$ref": "#/components/responses/Forbidden"},
          "409": {"$ref": "#/components/responses/Conflict"},
          "422": {"$ref": "#/components/responses/InvalidRequest"},
          "429": {"$ref": "#/components/responses/RateLimited"},
          "503": {"$ref": "#/components/responses/Unavailable"}
        }
      }
    },
    "/v1/properties/{property_entity_id}": {
      "get": {
        "operationId": "getProperty",
        "summary": "Retrieve a canonical maintained property",
        "description": "Returns the current delivery-safe canonical property when it belongs to a market enabled for the authenticated workspace.",
        "tags": ["Properties"],
        "parameters": [
          {"$ref": "#/components/parameters/PropertyEntityId"}
        ],
        "responses": {
          "200": {
            "description": "Current canonical property",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "./schemas/property-profile-v2.json"
                }
              }
            }
          },
          "401": {"$ref": "#/components/responses/Unauthorized"},
          "403": {"$ref": "#/components/responses/Forbidden"},
          "404": {"$ref": "#/components/responses/NotFound"},
          "503": {"$ref": "#/components/responses/Unavailable"}
        }
      }
    },
    "/v1/properties/{property_entity_id}/changes": {
      "get": {
        "operationId": "listPropertyChanges",
        "summary": "Retrieve finalized observed property changes",
        "description": "Returns newest-first finalized discovery, price and status changes. Suspected lifecycle transitions and incomplete updates are excluded.",
        "tags": ["Properties"],
        "parameters": [
          {"$ref": "#/components/parameters/PropertyEntityId"},
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of newest finalized changes to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Finalized observed changes",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/PropertyChangeList"}
              }
            }
          },
          "401": {"$ref": "#/components/responses/Unauthorized"},
          "403": {"$ref": "#/components/responses/Forbidden"},
          "404": {"$ref": "#/components/responses/NotFound"},
          "422": {"$ref": "#/components/responses/InvalidRequest"},
          "503": {"$ref": "#/components/responses/Unavailable"}
        }
      }
    }
  },
  "webhooks": {
    "propertyEvent": {
      "post": {
        "operationId": "receivePropertyEvent",
        "summary": "Receive a signed finalized property event",
        "description": "CleanedWeb signs the exact request body with Standard Webhooks headers. A receiver should verify the signature before parsing the JSON and deduplicate on webhook-id.",
        "security": [],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "schema": {"type": "string"}
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "schema": {"type": "string", "pattern": "^[0-9]+$"}
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "schema": {"type": "string", "minLength": 1}
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "./schemas/property-event-v1.json"
              },
              "examples": {
                "propertyEvent": {"$ref": "#/components/examples/WebhookEvent"}
              }
            }
          }
        },
        "responses": {
          "200": {"description": "Event accepted."},
          "204": {"description": "Event accepted without a response body."}
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-cw_session",
        "description": "Current production workspace session."
      },
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "CleanedWeb API key",
        "description": "Invite-only workspace credential with the properties:read scope. The secret is returned once and is revocable."
      }
    },
    "parameters": {
      "PropertyEntityId": {
        "name": "property_entity_id",
        "in": "path",
        "required": true,
        "description": "Stable canonical property identifier.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        }
      }
    },
    "schemas": {
      "PropertyCountRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["market", "response_schema"],
        "properties": {
          "market": {"type": "string", "pattern": "^[A-Za-z]{2,3}$"},
          "response_schema": {"const": "property-profile-v2"},
          "deal_type": {
            "type": "array",
            "items": {"enum": ["buy", "rent", "off_market"]},
            "uniqueItems": true,
            "description": "Omit or send an empty array to include every deal type."
          },
          "bounds": {
            "type": ["object", "null"],
            "additionalProperties": false,
            "required": ["west", "south", "east", "north"],
            "properties": {
              "west": {"type": "number", "minimum": -180, "maximum": 180},
              "south": {"type": "number", "minimum": -90, "maximum": 90},
              "east": {"type": "number", "minimum": -180, "maximum": 180},
              "north": {"type": "number", "minimum": -90, "maximum": 90}
            }
          },
          "location": {"type": ["string", "null"], "maxLength": 500},
          "location_place_id": {"type": ["string", "null"], "maxLength": 500},
          "keyword": {"type": ["string", "null"], "maxLength": 500},
          "property_categories": {
            "type": "array",
            "items": {
              "enum": ["apartment", "house", "land", "commercial", "parking", "building", "room", "other"]
            },
            "uniqueItems": true
          },
          "lifecycle_states": {"$ref": "#/components/schemas/StringSet"},
          "advertiser_types": {
            "type": "array",
            "items": {"enum": ["individual", "agency", "developer", "other_professional", "unknown"]},
            "uniqueItems": true
          },
          "representation_mixes": {
            "type": "array",
            "items": {"enum": ["individual_only", "agency_only", "developer_only", "other_professional_only", "mixed", "unknown"]},
            "uniqueItems": true
          },
          "contact_channels": {
            "type": "array",
            "items": {"enum": ["phone", "email", "website", "contact_form"]},
            "uniqueItems": true
          },
          "price_qualities": {
            "type": "array",
            "items": {"enum": ["known", "hidden", "placeholder", "missing"]},
            "uniqueItems": true
          },
          "first_observed_since": {"type": ["string", "null"], "format": "date"},
          "min_source_count": {"type": ["integer", "null"], "minimum": 1},
          "max_source_count": {"type": ["integer", "null"], "minimum": 1},
          "min_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_floor_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_floor_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_land_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_land_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_floor": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_floor": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_rooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_rooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_bedrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_bedrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_bathrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_bathrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "cadastral_block": {"type": ["string", "null"], "maxLength": 150},
          "cadastral_parcel": {"type": ["string", "null"], "maxLength": 150},
          "exterior_door_number": {"type": ["string", "null"], "maxLength": 80},
          "zoning_uses": {"$ref": "#/components/schemas/StringSet"},
          "min_allowed_floors": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_allowed_floors": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_floor_area_ratio": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_floor_area_ratio": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_building_count": {"type": ["integer", "null"], "minimum": 0},
          "max_building_count": {"type": ["integer", "null"], "minimum": 0},
          "min_building_footprint": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_building_footprint": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_transit_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_school_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_park_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_grocery_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_healthcare_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "exclude_heritage_overlays": {"type": "boolean", "default": false},
          "exclude_risk_overlays": {"type": "boolean", "default": false},
          "hotel_candidate": {"type": "boolean", "default": false},
          "advertiser_contact_required": {"type": "boolean", "default": false},
          "min_year_built": {"type": ["integer", "null"], "minimum": 0},
          "max_year_built": {"type": ["integer", "null"], "minimum": 0},
          "min_assessed_value": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_assessed_value": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_last_transfer_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_last_transfer_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_residential_units": {"type": ["integer", "null"], "minimum": 0},
          "max_residential_units": {"type": ["integer", "null"], "minimum": 0},
          "has_coordinates": {"type": ["boolean", "null"]},
          "has_assessment": {"type": ["boolean", "null"]},
          "has_transfer_history": {"type": ["boolean", "null"]}
        }
      },
      "PropertyCountResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["total_matched", "cached", "resolved_query", "snapshot"],
        "properties": {
          "total_matched": {"type": "integer", "minimum": 0},
          "cached": {
            "type": "boolean",
            "description": "True when the exact count was reused for this projection generation."
          },
          "resolved_query": {
            "type": "object",
            "additionalProperties": true,
            "required": ["market", "response_schema", "location"]
          },
          "snapshot": {"$ref": "#/components/schemas/MarketSnapshot"}
        }
      },
      "PropertySearchRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["market", "response_schema"],
        "properties": {
          "market": {"type": "string", "pattern": "^[A-Za-z]{2,3}$"},
          "response_schema": {"const": "property-profile-v2"},
          "deal_type": {
            "type": "array",
            "items": {"enum": ["buy", "rent", "off_market"]},
            "uniqueItems": true,
            "description": "Omit or send an empty array to include every deal type."
          },
          "bounds": {
            "type": ["object", "null"],
            "additionalProperties": false,
            "required": ["west", "south", "east", "north"],
            "properties": {
              "west": {"type": "number", "minimum": -180, "maximum": 180},
              "south": {"type": "number", "minimum": -90, "maximum": 90},
              "east": {"type": "number", "minimum": -180, "maximum": 180},
              "north": {"type": "number", "minimum": -90, "maximum": 90}
            }
          },
          "location": {"type": ["string", "null"], "maxLength": 500},
          "location_place_id": {"type": ["string", "null"], "maxLength": 500},
          "keyword": {"type": ["string", "null"], "maxLength": 500},
          "property_categories": {
            "type": "array",
            "items": {
              "enum": ["apartment", "house", "land", "commercial", "parking", "building", "room", "other"]
            },
            "uniqueItems": true
          },
          "lifecycle_states": {"$ref": "#/components/schemas/StringSet"},
          "advertiser_types": {
            "type": "array",
            "items": {"enum": ["individual", "agency", "developer", "other_professional", "unknown"]},
            "uniqueItems": true
          },
          "representation_mixes": {
            "type": "array",
            "items": {"enum": ["individual_only", "agency_only", "developer_only", "other_professional_only", "mixed", "unknown"]},
            "uniqueItems": true
          },
          "contact_channels": {
            "type": "array",
            "items": {"enum": ["phone", "email", "website", "contact_form"]},
            "uniqueItems": true
          },
          "price_qualities": {
            "type": "array",
            "items": {"enum": ["known", "hidden", "placeholder", "missing"]},
            "uniqueItems": true
          },
          "first_observed_since": {"type": ["string", "null"], "format": "date"},
          "min_source_count": {"type": ["integer", "null"], "minimum": 1},
          "max_source_count": {"type": ["integer", "null"], "minimum": 1},
          "min_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_floor_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_floor_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_land_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_land_area": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_floor": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_floor": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_rooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_rooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_bedrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_bedrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_bathrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_bathrooms": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "cadastral_block": {"type": ["string", "null"], "maxLength": 150},
          "cadastral_parcel": {"type": ["string", "null"], "maxLength": 150},
          "exterior_door_number": {"type": ["string", "null"], "maxLength": 80},
          "zoning_uses": {"$ref": "#/components/schemas/StringSet"},
          "min_allowed_floors": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_allowed_floors": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_floor_area_ratio": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_floor_area_ratio": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_building_count": {"type": ["integer", "null"], "minimum": 0},
          "max_building_count": {"type": ["integer", "null"], "minimum": 0},
          "min_building_footprint": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_building_footprint": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_transit_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_school_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_park_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_grocery_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_healthcare_walk_minutes": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "exclude_heritage_overlays": {"type": "boolean", "default": false},
          "exclude_risk_overlays": {"type": "boolean", "default": false},
          "hotel_candidate": {"type": "boolean", "default": false},
          "advertiser_contact_required": {"type": "boolean", "default": false},
          "min_year_built": {"type": ["integer", "null"], "minimum": 0},
          "max_year_built": {"type": ["integer", "null"], "minimum": 0},
          "min_assessed_value": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_assessed_value": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_last_transfer_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "max_last_transfer_price": {"$ref": "#/components/schemas/NullableNonNegativeNumber"},
          "min_residential_units": {"type": ["integer", "null"], "minimum": 0},
          "max_residential_units": {"type": ["integer", "null"], "minimum": 0},
          "has_coordinates": {"type": ["boolean", "null"]},
          "has_assessment": {"type": ["boolean", "null"]},
          "has_transfer_history": {"type": ["boolean", "null"]},
          "sort_by": {
            "enum": ["observed_at", "first_observed_at", "price", "floor_area", "land_area", "source_count", "transit_walk_minutes", "school_walk_minutes", "park_walk_minutes", "grocery_walk_minutes", "healthcare_walk_minutes", "year_built", "assessed_value", "last_transfer_price", "residential_units", "building_count"],
            "default": "observed_at"
          },
          "sort_order": {"enum": ["asc", "desc"], "default": "desc"},
          "limit": {"type": ["integer", "null"], "minimum": 1},
          "cursor": {
            "type": ["string", "null"],
            "maxLength": 4096,
            "description": "Opaque signed next_cursor from the preceding page. Requires limit and an unchanged query."
          },
          "max_units": {
            "type": ["number", "null"],
            "minimum": 0,
            "description": "Required spend ceiling for API-key requests. Ignored for browser-session requests."
          }
        }
      },
      "PropertySearchResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["total_matched", "returned", "truncated", "has_more", "next_cursor", "resolved_query", "snapshot", "results"],
        "properties": {
          "total_matched": {
            "type": ["integer", "null"],
            "minimum": 0,
            "description": "Exact total when the query is complete; null while another cursor page exists."
          },
          "returned": {"type": "integer", "minimum": 0},
          "truncated": {
            "type": "boolean",
            "deprecated": true,
            "description": "Compatibility field. True when this response alone is not the complete query."
          },
          "has_more": {"type": "boolean"},
          "next_cursor": {"type": ["string", "null"]},
          "resolved_query": {
            "type": "object",
            "additionalProperties": true,
            "required": ["market", "response_schema", "location"],
            "properties": {
              "market": {"type": "string"},
              "response_schema": {"const": "property-profile-v2"},
              "deal_type": {
                "type": "array",
                "items": {"enum": ["buy", "rent", "off_market"]},
                "uniqueItems": true
              },
              "location": {"type": ["object", "null"], "additionalProperties": true}
            }
          },
          "snapshot": {"$ref": "#/components/schemas/MarketSnapshot"},
          "usage": {"$ref": "#/components/schemas/UnitUsageReceipt"},
          "results": {
            "type": "array",
            "items": {
              "$ref": "./schemas/property-profile-v2.json"
            }
          }
        }
      },
      "MarketSnapshot": {
        "type": "object",
        "additionalProperties": false,
        "required": ["dataUpdatedAt", "availableRecords"],
        "properties": {
          "dataUpdatedAt": {"type": ["string", "null"], "format": "date-time"},
          "availableRecords": {"type": "integer", "minimum": 0},
          "projectionGenerationId": {"type": ["string", "null"]},
          "sourceStatus": {"type": "object", "additionalProperties": true}
        }
      },
      "Market": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "available_records", "data_updated_at"],
        "properties": {
          "id": {"type": "string", "pattern": "^[A-Z]{2,3}$"},
          "available_records": {"type": "integer", "minimum": 0},
          "data_updated_at": {"type": ["string", "null"], "format": "date-time"}
        }
      },
      "MarketList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["markets"],
        "properties": {
          "markets": {
            "type": "array",
            "items": {"$ref": "#/components/schemas/Market"}
          }
        }
      },
      "PropertyChangeList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["property_entity_id", "returned", "changes"],
        "properties": {
          "property_entity_id": {"type": "string", "minLength": 1},
          "returned": {"type": "integer", "minimum": 0},
          "changes": {
            "type": "array",
            "items": {
              "$ref": "./schemas/property-event-v1.json"
            }
          }
        }
      },
      "StringSet": {
        "type": "array",
        "items": {"type": "string", "minLength": 1},
        "uniqueItems": true
      },
      "NullableNonNegativeNumber": {
        "type": ["number", "null"],
        "minimum": 0
      },
      "UnitUsageReceipt": {
        "type": "object",
        "additionalProperties": false,
        "required": ["requestId", "units", "maxUnits", "balanceAfter", "recordsRetrieved", "classifications", "idempotentReplay", "createdAt"],
        "properties": {
          "requestId": {"type": "string", "format": "uuid"},
          "units": {"type": "number", "minimum": 0},
          "maxUnits": {"type": "number", "minimum": 0},
          "balanceAfter": {"type": "number", "minimum": 0},
          "recordsRetrieved": {"type": "integer", "minimum": 0},
          "classifications": {
            "type": "object",
            "additionalProperties": false,
            "required": ["firstDelivery", "unchangedDelivery", "listingEvent"],
            "properties": {
              "firstDelivery": {"type": "integer", "minimum": 0},
              "unchangedDelivery": {"type": "integer", "minimum": 0},
              "listingEvent": {"type": "integer", "minimum": 0}
            }
          },
          "idempotentReplay": {"type": "boolean"},
          "createdAt": {"type": "string", "format": "date-time"}
        }
      }
    },
    "examples": {
      "SearchRequest": {
        "summary": "Filtered global property-profile-v2 search",
        "externalValue": "./examples/search-request.json"
      },
      "SearchResponse": {
        "summary": "Complete property-profile-v2 response",
        "externalValue": "./examples/search-response.json"
      },
      "WebhookEvent": {
        "summary": "Signed finalized property event",
        "externalValue": "./examples/webhook-event.json"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Authentication is required or expired.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      },
      "Forbidden": {
        "description": "The account, workspace or market is not authorized.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      },
      "NotFound": {
        "description": "The canonical resource was not found in an entitled market.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      },
      "InvalidRequest": {
        "description": "The request or location selection was invalid.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      },
      "InsufficientUnits": {
        "description": "The workspace does not have enough Units for the delivery.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      },
      "Conflict": {
        "description": "The projection changed during cursor traversal, max_units was exceeded, or the request conflicted with an idempotent request.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      },
      "RateLimited": {
        "description": "The shared per-key request limit was exceeded. Retry-After is returned.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      },
      "Unavailable": {
        "description": "Maintained property data is temporarily unavailable.",
        "content": {
          "application/json": {
            "schema": {"$ref": "./schemas/error-v1.json"}
          }
        }
      }
    }
  }
}
