Search Properties

Search and filter property listings with text queries, location filters, geo search, and more.

Search for property listings using text queries, structured filters, geographic search, and sorting.

Endpoint

POST /properties/search

Authentication: Required (API key or JWT)

Query Parameters

These are passed as URL query parameters, not in the request body.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | filterByOrganization | boolean | false | When true, only return properties belonging to your organization | | includeBranding | boolean | false | Include organization branding settings in results | | includeAdCount | boolean | false | Include ad creative count per property | | includeAdCreatives | boolean | false | Include full ad creative data per property |

Request Body

All fields are optional. An empty body {} returns all properties with default pagination.

Text Search

| Field | Type | Description | |-------|------|-------------| | query | string | Natural language text search. Supports queries like "3 bedroom villa with pool in Dubai Marina" or structured field:value syntax like "bedrooms:3 AND hasPool:true" |

Array Filters

Each accepts a single value or an array of values to match against.

| Field | Type | Values | |-------|------|--------| | propertyType | string[] | apartment, condominium, house_detached, house_semi_detached, house_terraced, townhouse, multi_family_home, penthouse, studio, land_residential, land_commercial, land_agricultural, land_other, office, retail, commercial_other, industrial_warehouse, industrial_other, hospitality, other | | propertyCategory | string[] | residential, commercial, industrial, land | | listingType | string[] | sale, rent, sale_or_rent, fraction | | countryCode | string[] | ISO 3166-1 alpha-2 codes (e.g., ES, AE, US) | | region | string[] | Region names (e.g., Costa del Sol, Dubai) | | city | string[] | City names (e.g., Marbella, Dubai Marina) | | status | string[] | active, inactive, pending, sold, rented, deleted |

Range Filters

Each range filter is an object with optional min and max fields.

| Field | Type | Description | |-------|------|-------------| | bedrooms | { min?, max? } | Number of bedrooms | | bathrooms | { min?, max? } | Number of bathrooms | | price | { min?, max? } | Price in the property's currency | | livingArea | { min?, max? } | Living area in the property's area unit | | plotArea | { min?, max? } | Plot area in the property's area unit | | commission | { min?, max? } | Agent commission percentage (0–100) |

Feature Filters

Nest these inside a features object. Each is a boolean.

| Field | Type | Description | |-------|------|-------------| | hasPool | boolean | Swimming pool | | hasSeaView | boolean | Sea or ocean view | | hasGarage | boolean | Garage or covered parking | | hasTerrace | boolean | Terrace or balcony | | hasGarden | boolean | Garden | | isFurnished | boolean | Comes furnished | | hasAirConditioning | boolean | Air conditioning | | hasLift | boolean | Elevator / lift |

Geographic Filters

Use one of these — not both.

Radius search (location):

| Field | Type | Required | Description | |-------|------|----------|-------------| | location.lat | number | Yes | Latitude of center point | | location.lon | number | Yes | Longitude of center point | | location.distance | string | No | Search radius (default: "10km") |

Bounding box (boundingBox):

| Field | Type | Required | Description | |-------|------|----------|-------------| | boundingBox.northEast.lat | number | Yes | North-east corner latitude | | boundingBox.northEast.lon | number | Yes | North-east corner longitude | | boundingBox.southWest.lat | number | Yes | South-west corner latitude | | boundingBox.southWest.lon | number | Yes | South-west corner longitude |

Sorting

Use either the sort array or the flat sortBy/sortOrder fields.

sort array:

{
  "sort": [{ "field": "price", "order": "asc" }]
}

Flat fields:

| Field | Type | Description | |-------|------|-------------| | sortBy | string | Sort field name | | sortOrder | "asc" or "desc" | Sort direction (default: desc) |

Allowed sort fields: price, createdAt, updatedAt, publishedAt, bedrooms, bathrooms, livingArea, plotArea, commission, yearBuilt, city, countryCode, referenceNumber, status, propertyType, propertyCategory, listingType

Pagination

| Field | Type | Default | Description | |-------|------|---------|-------------| | page | integer | 1 | Page number (1-indexed) | | limit | integer | 20 | Results per page (1–100) |

Price Distribution

Request histogram data for building price range charts.

| Field | Type | Default | Description | |-------|------|---------|-------------| | priceDistribution.interval | number | 50000 | Bucket size | | priceDistribution.min | number | — | Minimum price for distribution | | priceDistribution.max | number | — | Maximum price for distribution |

Response

{
  "results": [
    {
      "id": "a1b2c3d4-...",
      "referenceNumber": "HQL-12345",
      "listingType": "sale",
      "propertyCategory": "residential",
      "propertyType": "villa",
      "city": "Marbella",
      "countryCode": "ES",
      "price": 1250000,
      "currency": "EUR",
      "bedrooms": 4,
      "bathrooms": 3,
      "livingArea": 320,
      "hasPool": true,
      "hasSeaView": true,
      "status": "active",
      ...
    }
  ],
  "total": 142,
  "priceDistribution": {
    "interval": 50000,
    "minPrice": 200000,
    "maxPrice": 5000000,
    "buckets": [
      { "key": 200000, "count": 5 },
      { "key": 250000, "count": 12 },
      ...
    ]
  },
  "relaxedFilters": ["bedrooms"]
}

| Field | Type | Description | |-------|------|-------------| | results | array | Array of property listing objects | | total | number | Total matching properties (for pagination) | | priceDistribution | object | Only present if priceDistribution was included in the request | | relaxedFilters | string[] | If the search returned few results, lists which filters were progressively relaxed to find more matches |

Examples

Basic Search

curl -X POST https://api.leadhql.com/properties/search \
  -H "Authorization: Bearer leadhql_pk_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "villa with pool in Marbella",
    "limit": 10
  }'

Filtered Search

curl -X POST https://api.leadhql.com/properties/search \
  -H "Authorization: Bearer leadhql_pk_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "propertyType": ["villa", "townhouse"],
    "listingType": ["sale"],
    "countryCode": ["ES"],
    "price": { "min": 500000, "max": 2000000 },
    "bedrooms": { "min": 3 },
    "features": {
      "hasPool": true,
      "hasSeaView": true
    },
    "sort": [{ "field": "price", "order": "asc" }],
    "page": 1,
    "limit": 20
  }'

Geo Radius Search

curl -X POST https://api.leadhql.com/properties/search \
  -H "Authorization: Bearer leadhql_pk_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "location": {
      "lat": 36.5101,
      "lon": -4.8824,
      "distance": "5km"
    },
    "propertyType": ["apartment"],
    "limit": 20
  }'

Organization Properties with Branding

curl -X POST "https://api.leadhql.com/properties/search?filterByOrganization=true&includeBranding=true" \
  -H "Authorization: Bearer leadhql_pk_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "status": ["active"],
    "sort": [{ "field": "createdAt", "order": "desc" }]
  }'

LeadHQL Help

Docs & support

Hi there, how can we help?

Browse popular articles or ask a question below.

Popular articles

Or ask a question