{
  "openapi": "3.1.0",
  "info": {
    "title": "Vestta API",
    "summary": "Integrate websites, applications and external services with a Vestta workspace.",
    "description": "Public, versioned Vestta API. Every operation requires an active API key and respects the scopes granted to it in Settings → API. Send the key in the `X-Api-Key` header. For compatibility, `Authorization: ApiKey <key>` is also accepted.",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.vestta.app/v1/ext",
      "description": "Production"
    }
  ],
  "paths": {
    "/leads": {
      "get": {
        "tags": [
          "Leads"
        ],
        "summary": "List leads",
        "description": "Returns the leads of the authenticated business, newest first. Requires the `leads:read` scope.",
        "operationId": "listLeads",
        "security": [
          {
            "VesttaApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "Maximum number of leads to return.",
              "default": 100,
              "title": "Limit"
            },
            "description": "Maximum number of leads to return."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Number of leads to skip, newest first.",
              "default": 0,
              "title": "Offset"
            },
            "description": "Number of leads to skip, newest first."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadListResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, unknown, revoked or expired, or lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "422": {
            "description": "A path parameter, query parameter or body field is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalValidationError"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          }
        },
        "x-vestta-scopes": [
          "leads:read"
        ]
      }
    },
    "/leads/ingest": {
      "post": {
        "tags": [
          "Leads"
        ],
        "summary": "Ingest a rental lead",
        "description": "Creates a rental-seeking lead from the compact payload used by rental landing forms. If the business already has a lead with the same primary phone, nothing is created and the response is still `ok`. Requires the `leads:ingest` scope.",
        "operationId": "ingestRentalLead",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RentingLead"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadIngestResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, unknown, revoked or expired, or lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "422": {
            "description": "A path parameter, query parameter or body field is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalValidationError"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          }
        },
        "security": [
          {
            "VesttaApiKey": []
          }
        ],
        "x-vestta-scopes": [
          "leads:ingest"
        ]
      }
    },
    "/leads/inquiries": {
      "post": {
        "tags": [
          "Leads"
        ],
        "summary": "Create an inquiry",
        "description": "Creates a lead with full contact details and structured search preferences, as submitted by a contact form. Returns the ID of the created lead. Requires the `leads:ingest` scope.",
        "operationId": "createLeadInquiry",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadInquiryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadInquiryResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, unknown, revoked or expired, or lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "422": {
            "description": "A path parameter, query parameter or body field is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalValidationError"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "400": {
            "description": "The lead could not be stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "409": {
            "description": "The business already has a named lead with this primary phone.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          }
        },
        "security": [
          {
            "VesttaApiKey": []
          }
        ],
        "x-vestta-scopes": [
          "leads:ingest"
        ]
      }
    },
    "/properties": {
      "get": {
        "tags": [
          "Properties"
        ],
        "summary": "List properties",
        "description": "Returns the public catalogue of the authenticated business: properties marked as public that are not sold, rented or withdrawn. Results are ordered by last update unless `sort` is set. Requires the `properties:read` scope.",
        "operationId": "listProperties",
        "security": [
          {
            "VesttaApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "Maximum number of properties to return.",
              "default": 100,
              "title": "Limit"
            },
            "description": "Maximum number of properties to return."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Number of matching properties to skip before returning results.",
              "default": 0,
              "title": "Offset"
            },
            "description": "Number of matching properties to skip before returning results."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exact status match. Only `disponible` and `reservada` can match: sold, rented and withdrawn properties are never returned.",
              "title": "Status"
            },
            "description": "Exact status match. Only `disponible` and `reservada` can match: sold, rented and withdrawn properties are never returned."
          },
          {
            "name": "operation",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Operation: `venta`, `alquiler` or `traspaso`. Case-insensitive partial match, so properties offered for several operations match each of them. Also selects which price `min_price`, `max_price` and `sort` use.",
              "title": "Operation"
            },
            "description": "Operation: `venta`, `alquiler` or `traspaso`. Case-insensitive partial match, so properties offered for several operations match each of them. Also selects which price `min_price`, `max_price` and `sort` use."
          },
          {
            "name": "rental_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "temporal",
                    "anual"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Rental type: `temporal` for temporary rentals, `anual` for long-term rentals that are neither temporary nor holiday rentals.",
              "title": "Rental Type"
            },
            "description": "Rental type: `temporal` for temporary rentals, `anual` for long-term rentals that are neither temporary nor holiday rentals."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exact property type: `apartamento`, `casa`, `local`, `nave`, `almacenaje`, `oficina`, `terreno`, `aparcamiento` or `edificio`.",
              "title": "Type"
            },
            "description": "Exact property type: `apartamento`, `casa`, `local`, `nave`, `almacenaje`, `oficina`, `terreno`, `aparcamiento` or `edificio`."
          },
          {
            "name": "subtype",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exact subtype key as stored in Vestta, for example `atico`, `duplex`, `chalet` or `villa`. Responses return the subtype as a display label.",
              "title": "Subtype"
            },
            "description": "Exact subtype key as stored in Vestta, for example `atico`, `duplex`, `chalet` or `villa`. Responses return the subtype as a display label."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "City name. Case-insensitive exact match.",
              "title": "City"
            },
            "description": "City name. Case-insensitive exact match."
          },
          {
            "name": "locations",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "URL-encoded JSON array of map areas. Supports `circle` (center + radius in metres), `polygon`/`rectangle` (coordinates) and `point`/`marker` (500 m default radius). Invalid JSON is ignored.",
              "title": "Locations"
            },
            "description": "URL-encoded JSON array of map areas. Supports `circle` (center + radius in metres), `polygon`/`rectangle` (coordinates) and `point`/`marker` (500 m default radius). Invalid JSON is ignored."
          },
          {
            "name": "min_price",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number",
                  "minimum": 0
                },
                {
                  "type": "null"
                }
              ],
              "description": "Minimum price, inclusive. Uses the rent or transfer price when `operation` is `alquiler` or `traspaso`.",
              "title": "Min Price"
            },
            "description": "Minimum price, inclusive. Uses the rent or transfer price when `operation` is `alquiler` or `traspaso`."
          },
          {
            "name": "max_price",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number",
                  "minimum": 0
                },
                {
                  "type": "null"
                }
              ],
              "description": "Maximum price, inclusive. Uses the rent or transfer price when `operation` is `alquiler` or `traspaso`.",
              "title": "Max Price"
            },
            "description": "Maximum price, inclusive. Uses the rent or transfer price when `operation` is `alquiler` or `traspaso`."
          },
          {
            "name": "min_bedrooms",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer",
                  "minimum": 0
                },
                {
                  "type": "null"
                }
              ],
              "description": "Minimum number of bedrooms, inclusive.",
              "title": "Min Bedrooms"
            },
            "description": "Minimum number of bedrooms, inclusive."
          },
          {
            "name": "is_featured",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`true` returns only featured properties; `false` only non-featured ones.",
              "title": "Is Featured"
            },
            "description": "`true` returns only featured properties; `false` only non-featured ones."
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "price_asc",
                    "price_desc"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Sort by price (properties without a price go last). When omitted, results are ordered by last update, newest first.",
              "title": "Sort"
            },
            "description": "Sort by price (properties without a price go last). When omitted, results are ordered by last update, newest first."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PropertyListResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, unknown, revoked or expired, or lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "422": {
            "description": "A path parameter, query parameter or body field is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalValidationError"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          }
        },
        "x-vestta-scopes": [
          "properties:read"
        ]
      }
    },
    "/properties/{property_id}": {
      "get": {
        "tags": [
          "Properties"
        ],
        "summary": "Retrieve a property",
        "description": "Returns one property from the public catalogue of the authenticated business. Requires the `properties:read` scope.",
        "operationId": "getProperty",
        "security": [
          {
            "VesttaApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "property_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "description": "Numeric property ID, as returned in `data[].id` by List properties.",
              "title": "Property Id"
            },
            "description": "Numeric property ID, as returned in `data[].id` by List properties."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PropertyDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, unknown, revoked or expired, or lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "422": {
            "description": "A path parameter, query parameter or body field is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalValidationError"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "404": {
            "description": "The property does not exist, is not public, or is sold, rented or withdrawn.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          }
        },
        "x-vestta-scopes": [
          "properties:read"
        ]
      }
    },
    "/me": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Retrieve key context",
        "description": "Returns the business and scopes of the API key used for the request. Any active key can call it; no scope is required.",
        "operationId": "getApiKeyContext",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentApiKeyResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, unknown, revoked or expired, or lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          },
          "422": {
            "description": "A path parameter, query parameter or body field is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalValidationError"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalApiError"
                }
              }
            }
          }
        },
        "security": [
          {
            "VesttaApiKey": []
          }
        ],
        "x-vestta-scopes": []
      }
    }
  },
  "components": {
    "schemas": {
      "AparcamientoPreferences": {
        "properties": {
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "min_seats": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Seats"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          }
        },
        "type": "object",
        "title": "AparcamientoPreferences"
      },
      "ApartmentPreferences": {
        "properties": {
          "specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specs"
          },
          "views": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Views"
          },
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          },
          "bedrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bedrooms Min"
          },
          "bathrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bathrooms Min"
          },
          "num_terraces_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Terraces Min"
          },
          "size_terraces_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Terraces Min"
          },
          "doble_bedrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Doble Bedrooms Min"
          },
          "suite_bathrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suite Bathrooms Min"
          }
        },
        "type": "object",
        "title": "ApartmentPreferences"
      },
      "ApiKeyContext": {
        "properties": {
          "company_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Company Name",
            "description": "Name of the business that owns the API key."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "Scopes granted to the key: `properties:read`, `leads:read`, `leads:ingest`."
          },
          "auth_method": {
            "type": "string",
            "const": "api_key",
            "title": "Auth Method"
          }
        },
        "type": "object",
        "required": [
          "scopes",
          "auth_method"
        ],
        "title": "ApiKeyContext"
      },
      "BuildingPreferences": {
        "properties": {
          "specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specs"
          },
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          },
          "num_floors_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Floors Min"
          },
          "num_locales_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Locales Min"
          },
          "usable_area_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Usable Area Min"
          },
          "num_parkings_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Parkings Min"
          },
          "num_viviendas_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Viviendas Min"
          }
        },
        "type": "object",
        "title": "BuildingPreferences"
      },
      "CurrentApiKeyResponse": {
        "properties": {
          "status": {
            "type": "string",
            "const": "ok",
            "title": "Status"
          },
          "user": {
            "$ref": "#/components/schemas/ApiKeyContext"
          }
        },
        "type": "object",
        "required": [
          "status",
          "user"
        ],
        "title": "CurrentApiKeyResponse",
        "examples": [
          {
            "status": "ok",
            "user": {
              "auth_method": "api_key",
              "company_name": "Inmobiliaria Ejemplo",
              "scopes": [
                "properties:read",
                "leads:read"
              ]
            }
          }
        ]
      },
      "ExternalApiError": {
        "properties": {
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "Human-readable error message in English. Stable enough to log, not meant for end users.",
            "examples": [
              "Invalid API key"
            ]
          }
        },
        "type": "object",
        "required": [
          "detail"
        ],
        "title": "ExternalApiError"
      },
      "ExternalLead": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id",
            "description": "Numeric lead ID."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Type",
            "description": "`demandante` (looking for a property), `propietario` (owner), `agencia-inmobiliaria`, `entidad-bancaria` or `proveedor-servicios`."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Pipeline status, e.g. `new`, `searching_property`, `active_negotiation`, `closed` or `inactive`."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active"
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where the lead came from, e.g. `web`, `manual`, or the `source` sent on ingestion."
          },
          "phone_number_1": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone Number 1",
            "description": "Primary phone in E.164 format."
          },
          "phone_number_2": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone Number 2"
          },
          "landline_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Landline Phone"
          },
          "personal_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Personal Email"
          },
          "professional_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Professional Email"
          },
          "preferred_language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Preferred Language",
            "description": "`es`, `gb`, `fr`, `ge` or `it`."
          },
          "search_preferences": {
            "title": "Search Preferences",
            "description": "What the lead is looking for (same shape as `search_preferences` in Create an inquiry), without internal notes."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "ISO 8601 timestamp with UTC offset. Leads are ordered by this field, newest first."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "ISO 8601 timestamp with UTC offset."
          }
        },
        "type": "object",
        "required": [
          "id"
        ],
        "title": "ExternalLead"
      },
      "ExternalProperty": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id",
            "description": "Numeric property ID. Use it with Retrieve a property."
          },
          "operation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Operation",
            "description": "Operations the property is offered for: `venta`, `alquiler`, `traspaso`, or several joined by commas (e.g. `venta,alquiler`)."
          },
          "type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Type",
            "description": "Property type key, e.g. `apartamento`, `casa`, `local`, `oficina`, `terreno` or `edificio`."
          },
          "subtype": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtype",
            "description": "Subtype as a Spanish display label (e.g. `Ático`, `Local Comercial`), or `Sin Especificar`."
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title",
            "description": "Listing title. May be empty."
          },
          "price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price",
            "description": "Sale price in euros. Rent and transfer prices are in `specs.price_calc`."
          },
          "size_total": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Total",
            "description": "Total size in m²."
          },
          "bedrooms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bedrooms"
          },
          "bathrooms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bathrooms"
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Omitted when the property's location is hidden."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Listing description as HTML."
          },
          "images": {
            "items": {},
            "type": "array",
            "title": "Images",
            "description": "Public images, as `{id, url, order, is_primary, title}` objects."
          },
          "videos": {
            "anyOf": [
              {
                "items": {},
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Videos",
            "description": "Processed videos, as `{id, title, order, url, hls_url, thumbnail_url, embed_url}` objects."
          },
          "specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specs",
            "description": "Listing characteristics. Keys depend on the property type. `price_calc.price_alq` and `price_calc.price_trasp` hold the monthly rent and transfer price; `address_privacy` is `public`, `approximate` or `hidden`; `building_name` is only present when the address is public."
          },
          "features": {
            "anyOf": [
              {
                "items": {},
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features",
            "description": "Amenities as `{label, key, value, isextra}` objects. `label` is a display string; `key` is stable."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "`disponible` or `reservada`. Sold, rented and withdrawn properties are never returned."
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Address",
            "description": "Follows the property's address privacy: the full address when public, the approximate address when approximate, omitted when hidden."
          },
          "city": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "City"
          },
          "province": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Province"
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country"
          },
          "lat": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lat",
            "description": "Latitude in decimal degrees. Exact when the address is public, rounded to 2 decimals (about 1 km) when approximate, omitted when hidden."
          },
          "lon": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lon",
            "description": "Longitude in decimal degrees, with the same precision rules as `lat`."
          },
          "is_featured": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Featured",
            "description": "Whether the business marked the property as featured."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "ISO 8601 timestamp with UTC offset."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "ISO 8601 timestamp with UTC offset. The default sort key."
          }
        },
        "type": "object",
        "required": [
          "id"
        ],
        "title": "ExternalProperty"
      },
      "ExternalValidationError": {
        "properties": {
          "detail": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ValidationErrorItem"
                },
                "type": "array"
              },
              {
                "type": "string"
              }
            ],
            "title": "Detail",
            "description": "List of validation errors. Phone numbers that cannot be normalised return a single message string instead."
          }
        },
        "type": "object",
        "required": [
          "detail"
        ],
        "title": "ExternalValidationError",
        "examples": [
          {
            "detail": [
              {
                "ctx": {
                  "ge": 1
                },
                "input": "0",
                "loc": [
                  "query",
                  "limit"
                ],
                "msg": "Input should be greater than or equal to 1",
                "type": "greater_than_equal"
              }
            ]
          }
        ]
      },
      "HousePreferences": {
        "properties": {
          "specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specs"
          },
          "views": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Views"
          },
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          },
          "bedrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bedrooms Min"
          },
          "bathrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bathrooms Min"
          },
          "num_terraces_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Terraces Min"
          },
          "size_terraces_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Terraces Min"
          },
          "doble_bedrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Doble Bedrooms Min"
          },
          "suite_bathrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suite Bathrooms Min"
          },
          "plot_size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Plot Size Min"
          },
          "porch_size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Porch Size Min"
          }
        },
        "type": "object",
        "title": "HousePreferences"
      },
      "LeadIngestResponse": {
        "properties": {
          "status": {
            "type": "string",
            "const": "ok",
            "title": "Status"
          },
          "authenticated_as": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Authenticated As",
            "description": "Name of the business that owns the API key."
          }
        },
        "type": "object",
        "required": [
          "status"
        ],
        "title": "LeadIngestResponse",
        "examples": [
          {
            "authenticated_as": "Inmobiliaria Ejemplo",
            "status": "ok"
          }
        ]
      },
      "LeadInquiryRequest": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Contact's full name."
          },
          "dni": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dni",
            "description": "National ID document number."
          },
          "rating": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rating",
            "description": "Ignored: inquiries are stored with rating 3.",
            "default": 0,
            "x-vestta-ignored": true
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "Ignored: inquiries are always stored as active.",
            "x-vestta-ignored": true
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "Lead type. `buyer`, `comprador`, `demandante`, `tenant` and `inquilino` are stored as `demandante`; `owner` and `propietario` as `propietario`. Other values must be a Vestta lead type (`agencia-inmobiliaria`, `entidad-bancaria`, `proveedor-servicios`)."
          },
          "profile_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Profile Category",
            "description": "`standard` or `potencial`. Defaults to `potencial`."
          },
          "urgency_profile": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Urgency Profile",
            "description": "`alta-urgencia` or `poca-urgencia`. Defaults to `poca-urgencia`."
          },
          "preferred_language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Preferred Language",
            "description": "`es`, `gb`, `fr`, `ge` or `it`."
          },
          "phone_number_1": {
            "type": "string",
            "title": "Phone Number 1",
            "description": "Primary phone. Normalised to E.164: include the international prefix (`+34600111222`); numbers without one are read as Spanish."
          },
          "phone_number_2": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone Number 2",
            "description": "Secondary phone, normalised to E.164."
          },
          "landline_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Landline Phone",
            "description": "Landline, normalised to E.164."
          },
          "personal_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Personal Email",
            "description": "Personal email address."
          },
          "professional_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Professional Email",
            "description": "Work email address."
          },
          "captured_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Captured By",
            "description": "Ignored: inquiries are stored as captured by `Web`.",
            "x-vestta-ignored": true
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where the inquiry comes from, e.g. `web` or your site's name. Stored as the lead source; defaults to `manual`.",
            "default": "manual"
          },
          "sourcePage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sourcepage",
            "description": "URL of the page where the inquiry was submitted. Added to the lead notes."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free-text message. Vestta stores a generated summary of the inquiry as the lead notes and includes this text in it, unless `search_preferences[0].internal_notes` is set."
          },
          "search_preferences": {
            "items": {
              "$ref": "#/components/schemas/SearchPreferences"
            },
            "type": "array",
            "title": "Search Preferences",
            "description": "What the contact is looking for. All entries are stored and used for property matching; the first one is summarised in the notes."
          },
          "agency_id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Agency Id",
            "description": "Ignored by this endpoint.",
            "x-vestta-ignored": true
          },
          "agency_client_ids": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Agency Client Ids",
            "description": "Ignored by this endpoint.",
            "x-vestta-ignored": true
          },
          "agency_property_ids": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Agency Property Ids",
            "description": "Property IDs linked to the contact. Stored only when `type` is `agencia-inmobiliaria`."
          },
          "services": {
            "items": {
              "$ref": "#/components/schemas/LeadServiceInput"
            },
            "type": "array",
            "title": "Services",
            "description": "Services offered by the contact. Stored only when `type` is `entidad-bancaria` or `proveedor-servicios`."
          },
          "time_to_create": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Time To Create",
            "description": "Ignored by this endpoint.",
            "default": 0,
            "x-vestta-ignored": true
          }
        },
        "type": "object",
        "required": [
          "name",
          "type",
          "phone_number_1"
        ],
        "title": "LeadInquiryRequest",
        "examples": [
          {
            "name": "Ana García",
            "notes": "Busco piso de dos habitaciones cerca del centro.",
            "personal_email": "ana@example.com",
            "phone_number_1": "+34600111222",
            "preferred_language": "es",
            "search_preferences": [
              {
                "apartamento": {
                  "bedrooms_min": 2,
                  "price_rent_max": 1200
                },
                "locations": [
                  {
                    "name": "Madrid"
                  }
                ],
                "operations": [
                  "alquiler"
                ],
                "property_types": [
                  "apartamento"
                ]
              }
            ],
            "source": "web",
            "sourcePage": "https://example.com/contacto",
            "type": "demandante"
          }
        ]
      },
      "LeadInquiryResponse": {
        "properties": {
          "status": {
            "type": "string",
            "const": "ok",
            "title": "Status"
          },
          "authenticated_as": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Authenticated As",
            "description": "Name of the business that owns the API key."
          },
          "lead_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lead Id",
            "description": "ID of the created lead, or of the existing unnamed lead that was completed."
          }
        },
        "type": "object",
        "required": [
          "status"
        ],
        "title": "LeadInquiryResponse",
        "examples": [
          {
            "authenticated_as": "Inmobiliaria Ejemplo",
            "lead_id": 228,
            "status": "ok"
          }
        ]
      },
      "LeadListResponse": {
        "properties": {
          "status": {
            "type": "string",
            "const": "ok",
            "title": "Status"
          },
          "data": {
            "items": {
              "$ref": "#/components/schemas/ExternalLead"
            },
            "type": "array",
            "title": "Data"
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Number of leads in this page (not the total across pages)."
          },
          "limit": {
            "type": "integer",
            "title": "Limit",
            "description": "The `limit` that was applied."
          },
          "offset": {
            "type": "integer",
            "title": "Offset",
            "description": "The `offset` that was applied."
          },
          "authenticated_as": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Authenticated As",
            "description": "Name of the business that owns the API key."
          }
        },
        "type": "object",
        "required": [
          "status",
          "data",
          "count",
          "limit",
          "offset"
        ],
        "title": "LeadListResponse",
        "examples": [
          {
            "authenticated_as": "Inmobiliaria Ejemplo",
            "count": 1,
            "data": [
              {
                "active": true,
                "created_at": "2026-09-29T18:24:55.569028+02:00",
                "id": 227,
                "name": "Ana García",
                "phone_number_1": "+34600111222",
                "preferred_language": "es",
                "search_preferences": [
                  {
                    "locations": [
                      {
                        "name": "Madrid"
                      }
                    ],
                    "operations": [
                      "alquiler"
                    ],
                    "property_types": [
                      "apartamento"
                    ]
                  }
                ],
                "source": "web",
                "status": "searching_property",
                "type": "demandante",
                "updated_at": "2026-09-29T18:24:55.569028+02:00"
              }
            ],
            "limit": 20,
            "offset": 0,
            "status": "ok"
          }
        ]
      },
      "LeadServiceInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "title": "Name"
          },
          "category": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Category"
          },
          "approximate_cost": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Approximate Cost"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "LeadServiceInput"
      },
      "LocalPreferences": {
        "properties": {
          "specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specs"
          },
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          },
          "height_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height Min"
          },
          "facade_meters_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Facade Meters Min"
          },
          "showcase_meters_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Showcase Meters Min"
          },
          "bathrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bathrooms Min"
          }
        },
        "type": "object",
        "title": "LocalPreferences"
      },
      "NavePreferences": {
        "properties": {
          "specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specs"
          },
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          },
          "height_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height Min"
          },
          "facade_meters_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Facade Meters Min"
          },
          "showcase_meters_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Showcase Meters Min"
          }
        },
        "type": "object",
        "title": "NavePreferences"
      },
      "OficinaPreferences": {
        "properties": {
          "specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specs"
          },
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          },
          "offices_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Offices Min"
          },
          "bathrooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bathrooms Min"
          },
          "meeting_rooms_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Meeting Rooms Min"
          },
          "num_terraces_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Terraces Min"
          },
          "size_terraces_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Terraces Min"
          }
        },
        "type": "object",
        "title": "OficinaPreferences"
      },
      "PropertyDetailResponse": {
        "properties": {
          "status": {
            "type": "string",
            "const": "ok",
            "title": "Status"
          },
          "data": {
            "$ref": "#/components/schemas/ExternalProperty"
          }
        },
        "type": "object",
        "required": [
          "status",
          "data"
        ],
        "title": "PropertyDetailResponse",
        "examples": [
          {
            "data": {
              "address": "San Antonio",
              "bathrooms": 1,
              "bedrooms": 0,
              "city": "San Antonio",
              "country": "España",
              "created_at": "2026-07-21T11:42:51.820440+02:00",
              "description": "<h2>Características del local</h2><p>Superficie total de 120 m² en planta baja…</p>",
              "features": [
                {
                  "isextra": false,
                  "key": "air_conditioning",
                  "label": "Aire Acondicionado",
                  "value": "Sí"
                }
              ],
              "id": 1355,
              "images": [
                {
                  "id": "63cfd9acfb62c728a6721ca0dd4afdcb_1784627270",
                  "is_primary": true,
                  "order": 1,
                  "url": "https://cdn.vestta.app/images/caa459b11e9f/73121a89c611/63cfd9acfb62c728a6721ca0dd4afdcb_1784627270.jpeg"
                }
              ],
              "is_featured": false,
              "lat": 38.98,
              "lon": 1.3,
              "operation": "traspaso,alquiler",
              "postal_code": "07820",
              "price": 0.0,
              "province": "Islas Baleares",
              "size_total": 120.0,
              "specs": {
                "address_privacy": "approximate",
                "holiday_renting": false,
                "price_calc": {
                  "price_alq": 2000.0,
                  "price_trasp": 25000.0
                },
                "temporal_renting": false
              },
              "status": "disponible",
              "subtype": "Local Comercial",
              "title": "Local comercial en el centro",
              "type": "local",
              "updated_at": "2026-09-26T19:38:41.390976+02:00",
              "videos": []
            },
            "status": "ok"
          }
        ]
      },
      "PropertyListResponse": {
        "properties": {
          "status": {
            "type": "string",
            "const": "ok",
            "title": "Status"
          },
          "data": {
            "items": {
              "$ref": "#/components/schemas/ExternalProperty"
            },
            "type": "array",
            "title": "Data",
            "description": "The requested page of properties."
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Total number of properties matching the filters, across all pages."
          },
          "limit": {
            "type": "integer",
            "title": "Limit",
            "description": "The `limit` that was applied."
          },
          "offset": {
            "type": "integer",
            "title": "Offset",
            "description": "The `offset` that was applied."
          },
          "filters": {
            "additionalProperties": true,
            "type": "object",
            "title": "Filters",
            "description": "Echo of the filters that were applied; `null` for filters that were not sent. `locations` contains only the areas that were understood."
          },
          "authenticated_as": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Authenticated As",
            "description": "Name of the business that owns the API key."
          }
        },
        "type": "object",
        "required": [
          "status",
          "data",
          "count",
          "limit",
          "offset",
          "filters"
        ],
        "title": "PropertyListResponse",
        "examples": [
          {
            "authenticated_as": "Inmobiliaria Ejemplo",
            "count": 78,
            "data": [
              {
                "address": "San Antonio",
                "bathrooms": 1,
                "bedrooms": 0,
                "city": "San Antonio",
                "country": "España",
                "created_at": "2026-07-21T11:42:51.820440+02:00",
                "description": "<h2>Características del local</h2><p>Superficie total de 120 m² en planta baja…</p>",
                "features": [
                  {
                    "isextra": false,
                    "key": "air_conditioning",
                    "label": "Aire Acondicionado",
                    "value": "Sí"
                  }
                ],
                "id": 1355,
                "images": [
                  {
                    "id": "63cfd9acfb62c728a6721ca0dd4afdcb_1784627270",
                    "is_primary": true,
                    "order": 1,
                    "url": "https://cdn.vestta.app/images/caa459b11e9f/73121a89c611/63cfd9acfb62c728a6721ca0dd4afdcb_1784627270.jpeg"
                  }
                ],
                "is_featured": false,
                "lat": 38.98,
                "lon": 1.3,
                "operation": "traspaso,alquiler",
                "postal_code": "07820",
                "price": 0.0,
                "province": "Islas Baleares",
                "size_total": 120.0,
                "specs": {
                  "address_privacy": "approximate",
                  "holiday_renting": false,
                  "price_calc": {
                    "price_alq": 2000.0,
                    "price_trasp": 25000.0
                  },
                  "temporal_renting": false
                },
                "status": "disponible",
                "subtype": "Local Comercial",
                "title": "Local comercial en el centro",
                "type": "local",
                "updated_at": "2026-09-26T19:38:41.390976+02:00",
                "videos": []
              }
            ],
            "filters": {
              "locations": [],
              "operation": "alquiler"
            },
            "limit": 20,
            "offset": 0,
            "status": "ok"
          }
        ]
      },
      "RentingLead": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Your identifier for the submission. Required, but not stored by Vestta."
          },
          "createdAt": {
            "type": "string",
            "title": "Createdat",
            "description": "When the form was submitted, ISO 8601. Required, but not stored by Vestta."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Where the lead comes from, e.g. `web`. Stored as the lead source."
          },
          "sourcePage": {
            "type": "string",
            "title": "Sourcepage",
            "description": "URL of the page with the form. Added to the lead notes."
          },
          "contact": {
            "$ref": "#/components/schemas/RentingLeadContact"
          },
          "search": {
            "$ref": "#/components/schemas/RentingLeadSearch"
          }
        },
        "type": "object",
        "required": [
          "id",
          "createdAt",
          "source",
          "sourcePage",
          "contact",
          "search"
        ],
        "title": "RentingLead",
        "examples": [
          {
            "contact": {
              "name": "Ana García",
              "phone": "+34600111222"
            },
            "createdAt": "2026-09-22T10:30:00Z",
            "id": "web-123",
            "search": {
              "area": "Madrid centro",
              "budget": "900-1200",
              "entryDate": "2026-10-01",
              "exitDate": "2027-09-30",
              "freeText": "Preferimos una vivienda amueblada",
              "habs": "2",
              "location": {
                "name": "Madrid"
              },
              "people": "2",
              "pets": "No",
              "workSituation": "Contrato indefinido"
            },
            "source": "web",
            "sourcePage": "https://example.com/alquiler"
          }
        ]
      },
      "RentingLeadContact": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Contact's full name. Stored as the lead name."
          },
          "phone": {
            "type": "string",
            "title": "Phone",
            "description": "Phone number. Include the international prefix (`+34600111222`); numbers without one are read as Spanish."
          },
          "phoneRaw": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phoneraw",
            "description": "Phone exactly as typed. Used only when no other phone field can be normalised."
          },
          "areaCode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Areacode",
            "description": "International prefix, e.g. `+34`. Combined with `phoneNumber` and tried first."
          },
          "phoneNumber": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phonenumber",
            "description": "National number without prefix. Combined with `areaCode`."
          },
          "phoneE164": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phonee164",
            "description": "Phone already in E.164 format. Tried after `areaCode` + `phoneNumber`."
          }
        },
        "type": "object",
        "required": [
          "name",
          "phone"
        ],
        "title": "RentingLeadContact",
        "examples": [
          {
            "name": "Ana García",
            "phone": "+34600111222"
          }
        ]
      },
      "RentingLeadSearch": {
        "properties": {
          "budget": {
            "type": "string",
            "title": "Budget",
            "description": "Monthly budget in euros: a whole number (`1200`) or a range (`900-1200`). The upper bound is stored as the maximum rent."
          },
          "entryDate": {
            "type": "string",
            "title": "Entrydate",
            "description": "Desired move-in date. Free text, added to the lead notes; `YYYY-MM-DD` recommended."
          },
          "exitDate": {
            "type": "string",
            "title": "Exitdate",
            "description": "Desired move-out date. Free text, added to the lead notes."
          },
          "people": {
            "type": "string",
            "title": "People",
            "description": "Number of occupants. Added to the lead notes."
          },
          "area": {
            "type": "string",
            "title": "Area",
            "description": "Preferred area, as free text. Added to the lead notes."
          },
          "habs": {
            "type": "string",
            "title": "Habs",
            "description": "Minimum bedrooms. Stored as the minimum bedrooms for apartments and houses."
          },
          "pets": {
            "type": "string",
            "title": "Pets",
            "description": "Whether the occupants have pets. Added to the lead notes."
          },
          "workSituation": {
            "type": "string",
            "title": "Worksituation",
            "description": "Employment situation. Added to the lead notes."
          },
          "location": {
            "additionalProperties": true,
            "type": "object",
            "title": "Location",
            "description": "Location used for property matching, e.g. `{\"name\": \"Madrid\"}`, or a map area with `geometry`."
          },
          "freeText": {
            "type": "string",
            "title": "Freetext",
            "description": "Free-text message from the contact. Added to the lead notes."
          }
        },
        "type": "object",
        "required": [
          "budget",
          "entryDate",
          "exitDate",
          "people",
          "area",
          "habs",
          "pets",
          "workSituation",
          "location",
          "freeText"
        ],
        "title": "RentingLeadSearch",
        "examples": [
          {
            "area": "Madrid centro",
            "budget": "900-1200",
            "entryDate": "2026-10-01",
            "exitDate": "2027-09-30",
            "freeText": "Preferimos una vivienda amueblada",
            "habs": "2",
            "location": {
              "name": "Madrid"
            },
            "people": "2",
            "pets": "No",
            "workSituation": "Contrato indefinido"
          }
        ]
      },
      "SearchPreferences": {
        "properties": {
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Request Id"
          },
          "operations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Operations"
          },
          "property_types": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Property Types"
          },
          "apartamento": {
            "$ref": "#/components/schemas/ApartmentPreferences"
          },
          "casa": {
            "$ref": "#/components/schemas/HousePreferences"
          },
          "local": {
            "$ref": "#/components/schemas/LocalPreferences"
          },
          "nave": {
            "$ref": "#/components/schemas/NavePreferences"
          },
          "almacenaje": {
            "$ref": "#/components/schemas/StoragePreferences"
          },
          "oficina": {
            "$ref": "#/components/schemas/OficinaPreferences"
          },
          "terreno": {
            "$ref": "#/components/schemas/TerrenoPreferences"
          },
          "aparcamiento": {
            "$ref": "#/components/schemas/AparcamientoPreferences"
          },
          "edificio": {
            "$ref": "#/components/schemas/BuildingPreferences"
          },
          "locations": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Locations"
          },
          "internal_notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Internal Notes"
          }
        },
        "type": "object",
        "title": "SearchPreferences"
      },
      "StoragePreferences": {
        "properties": {
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          }
        },
        "type": "object",
        "title": "StoragePreferences",
        "description": "Preferencias para almacenes y trasteros independientes."
      },
      "TerrenoPreferences": {
        "properties": {
          "views": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Views"
          },
          "features": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Features"
          },
          "subtypes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtypes"
          },
          "topography": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Topography"
          },
          "size_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Max"
          },
          "size_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Min"
          },
          "price_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Max"
          },
          "price_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Min"
          },
          "price_rent_max": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Max"
          },
          "price_rent_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Rent Min"
          },
          "size_built_min": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Built Min"
          }
        },
        "type": "object",
        "title": "TerrenoPreferences"
      },
      "ValidationErrorItem": {
        "properties": {
          "type": {
            "type": "string",
            "title": "Type",
            "description": "Machine-readable error type, e.g. `missing`, `int_parsing` or `greater_than_equal`."
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Loc",
            "description": "Where the error is: `query`, `path` or `body`, followed by the field path."
          },
          "msg": {
            "type": "string",
            "title": "Msg",
            "description": "Human-readable explanation."
          },
          "input": {
            "title": "Input",
            "description": "The value that failed validation."
          },
          "ctx": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ctx",
            "description": "Constraint details, such as the `ge` limit that was not met."
          }
        },
        "type": "object",
        "required": [
          "type",
          "loc",
          "msg"
        ],
        "title": "ValidationErrorItem"
      }
    },
    "securitySchemes": {
      "VesttaApiKey": {
        "type": "apiKey",
        "description": "Vestta API key, formatted as `AC_LIVE_<key_id>.<secret>`.",
        "in": "header",
        "name": "X-Api-Key"
      }
    }
  },
  "tags": [
    {
      "name": "Properties",
      "description": "Read the public property catalogue of the authenticated business."
    },
    {
      "name": "Leads",
      "description": "Read leads and send new leads into Vestta."
    },
    {
      "name": "Authentication",
      "description": "Inspect the API key used for the request."
    }
  ]
}
