---
title: "Search properties"
method: POST
path: "/v1/property-sourcing/searches"
tags: ["platform---property-sourcing"]
---

# Search properties

`POST /v1/property-sourcing/searches`

## Request

- Base URL: `https://platform.casafari.com`
- URL: `https://platform.casafari.com/v1/property-sourcing/searches`
- Auth: HTTP bearer

Structured search of the property graph: one request body for every country. Name the places with `location_ids` (find them with `GET /v1/locations/search`), then filter by property type, price, price per m², bedrooms, bathrooms, living and plot area and features, and sort. Each result is one property, however many listings advertise it, with an opaque `prop_` id. `next` is a URL for the following page (valid for one hour, bound to your account) or `null`. Plain-language phrases go to `POST /v1/property-sourcing/searches/describe`. 100 tokens per page.

## Request body

- PropertySourcingSearchRequest
  - `location_ids` integer[], required: 1 to 100 location ids, from GET /v1/locations/search?query=<place>.
  - `country` string: ISO 3166-1 alpha-2 code, e.g. "ES". Needed when the location ids do not include the country's own id and the account covers more than one country.
  - `operation` 'sale' | 'rent': For sale or for rent.
  - `types` string[]: Property type names in lower case, e.g. "apartment", "house", "villa".
  - `price` PlatformRange: A range; either end may be left out.
    - `min` integer: Lowest value, inclusive.
    - `max` integer: Highest value, inclusive.
  - `price_per_sqm` PlatformRange: A range; either end may be left out.
    - `min` integer: Lowest value, inclusive.
    - `max` integer: Highest value, inclusive.
  - `bedrooms` PlatformRange: A range; either end may be left out.
    - `min` integer: Lowest value, inclusive.
    - `max` integer: Highest value, inclusive.
  - `bathrooms` PlatformRange: A range; either end may be left out.
    - `min` integer: Lowest value, inclusive.
    - `max` integer: Highest value, inclusive.
  - `living_area_sqm` PlatformRange: A range; either end may be left out.
    - `min` integer: Lowest value, inclusive.
    - `max` integer: Highest value, inclusive.
  - `plot_area_sqm` PlatformRange: A range; either end may be left out.
    - `min` integer: Lowest value, inclusive.
    - `max` integer: Highest value, inclusive.
  - `features` string[]: Features every result must have.
  - `exclude_features` string[]: Features no result may have.
  - `sort` 'newest' | 'oldest' | 'recently_updated' | 'price_asc' | 'price_desc' | 'price_per_sqm_asc' | 'price_per_sqm_desc' | 'largest': Order of the results.
  - `page_size` integer: Results per page: up to 100 (25 on Free).

## Response `200`

One page of properties.

- PropertySourcingSearchPage
  - `results` PropertySourcingResult[]
    - `id` string: Opaque property id, `prop_...`.
    - `type` string, nullable: Property type.
    - `operation` 'sale' | 'rent'
    - `price` PlatformPrice
      - `amount` number, nullable: Asking price; null when the price is on request.
      - `currency` string, nullable: ISO 4217 currency code.
      - `per_sqm` number, nullable: Asking price per m².
    - `bedrooms` number, nullable
    - `living_area_sqm` number, nullable
    - `location` PlatformLocation
      - `id` integer, nullable: Location id.
      - `name` string, nullable: Location name.
      - `coordinates` object, nullable: Latitude and longitude.
        - `lat` number
        - `lon` number
    - `first_seen` string, nullable: When the property came on the market for this operation.
    - `listings_count` integer, nullable: How many listings advertise it; known on a property read with expand=listings, null in search results.
    - `matched_tags` string[], nullable: The phrases of a plain-language search this property matched; null for structured searches.
  - `total` integer, nullable: How many properties match, when known.
  - `next` string, nullable: URL of the next page (valid one hour), or null.

## Other responses

- `400`: Invalid request: the problem names each field to fix (`invalid_request`), or `page_size` is over the plan's limit (`page_depth_exceeded`).
- `401`: Missing or unknown API key or token.
- `402`: No tokens left to fund the call (`payment_required`, with `reason` and an `upgrade_url`).
- `403`: The account is not entitled to this product or country (`not_entitled`).
- `429`: A request limit of the plan was reached (`request_limit_reached`, with `window` and `Retry-After`).

---

[API](https://skmtc.dev/casafari/apis/casafari-api.md) · [All operations](https://skmtc.dev/casafari/apis/casafari-api/llms.txt) · [OpenAPI document](https://skmtc.dev/casafari/apis/casafari-api/revisions/6743b99d4bf9?raw)
