POST /api/idealista/properties/search
Price: 10 credits
Search Idealista property listings in Portugal (idealista.pt) or Italy (idealista.it), for sale or to rent, across homes, land, garages, offices, buildings, storage rooms, commercial units and new developments. Narrows by dwelling sub-type, room and bathroom count, condition, energy band, storey, amenities, price range and floor area, and orders by price, price per m², area, storey, publication date or price cut. Returns listing cards with title, price with any recorded discount, price per m², area, rooms, storey, amenities, photos, the advertiser description and the selling agency.
Portugal and Italy only — set `domain` to pt (idealista.pt, the default) or it (idealista.it). Spain is not covered. `location` on pt is a plain accent-folded municipality name ('Vila Nova de Gaia'); on it the slug pairs comune and provincia ('milano-milano', 'forli-forli-cesena'), and a single bare word is doubled for you, which is right for most provincial capitals but not where the province differs. Widen to the whole district or province with the '-distrito' (pt) or '-provincia' (it) suffix — usually two to three times the listings. `rooms` and `home_types` are country-specific and prefixed pt_/it_; passing a value from the wrong country is rejected rather than ignored. Note the two room systems count different things: pt_t2 is two BEDROOMS, it_bilocale is two ROOMS in total, so it_bilocale is the smaller home. Filters intersect, so stacking several narrows fast and an over-constrained query returns 412 rather than an empty list. `property_type` homes covers flats and houses together; narrow with `home_types`. Renting land (pt) and buying rooms (it) are the only operation/property-type pairs idealista does not publish and are rejected. Some features are tied to one operation and are rejected with a message naming which; the amenity, bathroom, condition, energy and storey filters belong to the homes feed, so pairing them with another `property_type` answers 412. One query reaches at most 1800 listings however many match, so to cover a large city split it by `zone`, price band or `home_types` rather than raising `count`.
access-token string requiredtimeout integer — Max scrapping execution timeout (in seconds) (default: 300; min: 20; max: 1500)domain string — Country site to search: pt = idealista.pt, it = idealista.it (default: "pt"; one of: "pt", "it")location string required — Municipality or city. On pt a plain accent-folded name resolves ('Vila Nova de Gaia'); on it the slug is '{comune}-{provincia}' ('milano-milano', 'forli-forli-cesena') and a single bare name is doubled automatically. Append '-distrito' (pt) or '-provincia' (it) to widen to the whole district/province (examples: "Lisboa", "Vila Nova de Gaia", "lisboa-distrito", "milano-milano", "milano-provincia"; minLength: 1)zone string nullable — Optional parish or neighbourhood inside the location (examples: "alcantara", "citta-studi-lambrate")operation string — Buy or rent (default: "buy"; one of: "buy", "rent")property_type string — Kind of property to search (default: "homes"; one of: "homes", "land", "garages", "offices", "buildings", "storage_rooms", "commercial", "new_developments", "rooms")home_types array nullable — Dwelling sub-types; only meaningful when property_type is homes. Values are country-specific and prefixed pt_/it_ - they must match the selected domain (one of: "pt_apartamentos", "pt_apenas_apartamentos", "pt_moradias", "pt_moradias_em_banda", "pt_moradias_geminadas", "pt_moradias_independentes", "pt_moradias_terreas", "pt_duplex", "pt_lofts", "pt_aguas_furtadas", "pt_casas_rusticas", "pt_quintas", "pt_solares_ou_palacetes", "it_appartamenti", "it_solo_appartamenti", "it_attici", "it_loft_open_space", "it_mansarde", "it_case_indipendenti", "it_ville", "it_ville_indipendenti", "it_villette_a_schiera", "it_rustici", "it_casali_o_cascine", "it_appartamenti_due_livelli")rooms array nullable — Room-count buckets. Country-specific and prefixed pt_/it_: pt_* is the Portuguese T-typology counting BEDROOMS (pt_t2 = two bedrooms), it_* is the Italian 'locali' counting TOTAL rooms (it_bilocale = two rooms, i.e. one bedroom). They must match the selected domain (one of: "pt_t0", "pt_t1", "pt_t2", "pt_t3", "pt_t4_or_more", "it_monolocale", "it_bilocale", "it_trilocale", "it_quadrilocale", "it_5_locali_or_more")bathrooms array nullable — Number of bathrooms (one of: "one", "two", "three_or_more")condition array nullable — Property condition (one of: "new_construction", "good", "to_renovate")energy_rating array nullable — Energy certificate band (one of: "high", "medium", "low")floor array nullable — Storey position in the building (one of: "top", "intermediate", "ground")features array nullable — Amenities and listing attributes to require. Not every feature exists on every country site, and some exist only for one operation; a value the selected domain or operation does not publish is rejected with a message naming what is allowed rather than silently ignored. Idealista applies these filters to the homes feed, so most other property_type values refuse them upstream (one of: "elevator", "pool", "garden", "private_garden", "terrace", "balcony", "terrace_or_balcony", "parking", "storage_room", "air_conditioning", "built_in_wardrobes", "accessible", "luxury", "sea_view", "floor_plan", "virtual_tour", "bank_owned", "tenanted", "judicial_auction", "pets_allowed", "furnished")min_price integer nullable — Minimum price in euros (min: 0)max_price integer nullable — Maximum price in euros (min: 0)min_size integer nullable — Minimum floor area in m² (min: 0)max_size integer nullable — Maximum floor area in m² (min: 0)sort string — Result ordering (default: "relevance"; one of: "relevance", "price_asc", "price_desc", "newest", "oldest", "price_drop", "price_per_m2_asc", "price_per_m2_desc", "size_asc", "size_desc", "floor_asc", "floor_desc")count integer required — Max number of results to return (min: 1; max: 1800)@type string (default: "IdealistaPropertyCard")id string requiredurl string nullablelisting_title string nullableprice number nullableprevious_price number nullableprice_drop_percent integer nullableprice_per_m2 number nullablesurface integer nullableroom_count integer nullablephoto_count integer nullablefloor string nullablehas_elevator boolean nullablehas_parking boolean nullableis_professional boolean nullablehighlight string nullabledescription string nullabletags array (default: [])features array (default: [])images array (default: [])agency object nullable@type string (default: "IdealistaCardAgency")name string nullableurl string nullableimage string nullable422 — A filter value does not exist on the selected country domain, is tied to the other operation, or a required field is missing Check the fields against this schema. A URN with the wrong prefix is the most common cause.408 — The request ran past its time limit Raise `timeout` in the request body, up to the maximum this endpoint documents. Lowering `count` or turning off the `with_*` flags also helps, because less work finishes sooner.412 — No listings matched, or the location, zone or filter combination does not exist upstream — the commonest case is a filter that only the homes feed accepts Retrying will not help: either the entity does not exist, or the input points at a different one.429 — Too many requests: a rate limit or a usage window is exhausted When the response carries an X-Retry-After header, wait that many seconds and retry: the same number is in the body as `detail.retry_after`, and the limit clears once that window passes. The message in the body names the limit that was hit.500 — Something broke on our side Retrying will not help. If it keeps happening, send us the X-Request-ID from the response headers.529 — Rate limit reached, or the endpoint is overloaded Wait at least 30 seconds, then retry.X-Error — Error message text (present only on error)X-Request-ID — Unique request identifierX-Execution-Time — Execution time in secondsX-Result-Count — How many records the body carries. 0 means an empty result, which is a normal answer and not by itself an error. A non-zero count can come back together with X-Error when the failure happened partway through — read this header and X-Error independently.X-Total-Available-Results — How many records exist for this query, when the endpoint can say. On a `dry_run` request this is the answer and the body is empty. It saturates: the endpoint's documented maximum means 'at least that many', any smaller number is exact.X-Warning — Present when the request body carried keys this endpoint does not document. They were ignored, so any filter you meant to apply through them did not apply. Check the spelling against this schema and retry.X-Retry-After — Seconds to wait before retrying. Present only on 429.