# Property Finder Home Scraper (`axiomworks/propertyfinder-listings-scraper`) Actor

Extract property records from public Property Finder UAE searches, including price, location, property type, bedrooms, size, agent and broker details, and images. Supports filtered search URLs and deduplicates repeated property IDs.

- **URL**: https://apify.com/axiomworks/propertyfinder-listings-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.74 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Propertyfinder Listing Scraper

**Returns:** one row per property with title, listingType, propertyType, price, location, bedrooms, sizeSqft, and agentName.
**Input:** `{"startUrls":[{"url":"https://www.propertyfinder.ae/en/search?c=1&t=1&fu=0&ob=mr"}],"maxItems":30}`
**Best for:** UAE property market research, listing comparisons, and monitoring advertised sale or rental inventory.

```json
{
  "id": "154608004",
  "title": "Full Fountain View | Fully Upgraded | Vacant",
  "listingType": "buy",
  "propertyType": "Apartment",
  "price": 5999999,
  "location": "Burj Khalifa, Burj Khalifa Area, Downtown Dubai, Dubai",
  "bedrooms": "2",
  "sizeSqft": 1716
}
```

Propertyfinder Listing Scraper collects public UAE property listings from Property Finder search pages. It uses the search page's embedded listing data to return a structured dataset. You can supply a filtered search URL or build a search with sale or rental mode, property type, location, price, and bedrooms. Each result has a stable property ID and the URL of the search page that supplied it. This Property Finder scraper is useful when a Property Finder API style dataset is needed for analysis, without opening individual listing detail pages.

### What does Propertyfinder Listing Scraper do?

The Actor visits public Property Finder UAE search result pages and extracts the property listings embedded in those pages. Search results can mix properties with project advertisements, so the output contains property records only. It follows the search pagination until it reaches your `maxItems` limit, runs out of results, or encounters a page it cannot read. Promoted property listings can reappear on later pages; the Actor uses the property's stable ID to keep one record per property within a run.

The search page includes the property headline, type, price, full location, coordinates, bedroom and bathroom labels, size, agent and broker details, images, reference, listed date, and description. The Actor also reads amenity codes, furnishing and completion status, the site's verification flag, published RERA permit, image count, and a phone contact when present in the same search record. It also returns published agent, broker and location IDs, the location ID path, readable amenity names, listing tier, and the advertised price per area with its unit. These values come from the same search response. It does not infer missing values. If a field is absent, the corresponding output field is null; image and amenity arrays are empty when not supplied.

No login is required. The Actor uses Apify Proxy by default with a residential UAE connection. Property Finder may block individual requests; the Actor retries blocked responses with increasing delays and fresh proxy sessions. It sends at most one search request per second and processes pages sequentially.

### What data can you get?

Each dataset row represents one public property listing. The field table below describes the exact output keys. The values come from the embedded search listing, so the search page is also preserved as `sourceUrl`. The detail `url` is supplied by the same listing data and is provided as a reference; the Actor does not visit it.

| Field | Meaning |
| --- | --- |
| `id` | Stable Property Finder property ID used to remove duplicates. |
| `sourceUrl` | Search result page that contained this property. |
| `url` | Public detail URL supplied in the search listing. |
| `title` | Property listing headline. |
| `listingType` | `buy` or `rent`, based on the listing price period and search. |
| `propertyType` | Advertised type such as Apartment. |
| `price` | Numeric advertised amount. |
| `currency` | Price currency, such as AED. |
| `pricePeriod` | Site period, such as `sell`, `yearly`, or `monthly`. |
| `location` | Full location name as shown by Property Finder. |
| `latitude` | Latitude from the location data, if present. |
| `longitude` | Longitude from the location data, if present. |
| `bedrooms` | Bedroom label, including `studio` where applicable. |
| `bathrooms` | Bathroom label. |
| `sizeSqft` | Advertised area when the size unit is square feet. |
| `agentName` | Name of the listing agent. |
| `brokerName` | Broker company name. |
| `brokerPhone` | Public phone number in the broker record. |
| `agentId` | Published agent identifier for grouping listings. |
| `brokerId` | Published broker identifier for grouping listings. |
| `locationId` | Published listing location identifier; distinct from the input search location. |
| `locationPath` | Dot-separated location IDs copied from the source hierarchy. |
| `amenityNames` | Readable amenity labels published with the listing; null when absent. |
| `listingLevel` | Source promotional listing tier, such as premium; not a quality assessment. |
| `pricePerArea` | Advertised price per area copied from the source, without calculation or rental annualization. |
| `pricePerAreaUnit` | Source area unit paired with pricePerArea, such as sqft. |
| `images` | Image URL array from the search listing. |
| `reference` | Broker or listing reference. |
| `listedDate` | Listing date returned by the site. |
| `description` | Property description in the search listing. |
| `amenities` | Amenity codes published in the search listing; an empty array when unavailable. |
| `furnished` | Furnishing status as supplied by Property Finder. |
| `completionStatus` | Published completion status, such as `off_plan`. |
| `verified` | Property Finder's listing verification flag. |
| `rera` | Published RERA permit number when provided. |
| `imageCount` | Published number of listing images; this can exceed the image URLs exposed in search results. |
| `agentPhone` | Public phone entry in the listing's contact options, when supplied. |

The overview table highlights title, listing type, price, location, bedrooms, size, furnishing, verification, agent, and listing URL. The full dataset includes the fields above. Null means the source did not supply a usable value.

The additional identifiers help join records without relying on agent or agency name spelling. `locationId` describes the listing's own location, while the input `locationId` selects a search area. `locationPath` preserves the site's dot-separated hierarchy; it is not a postal address. `amenityNames` contains the readable labels supplied alongside the existing `amenities` codes, and remains null when that array is missing. `listingLevel` reports a promotional tier such as premium, rather than an independent judgment of property quality. `pricePerArea` and `pricePerAreaUnit` preserve the source's advertised amount and unit. They are not calculated by dividing price by size, and rental values are not converted to annual amounts. Compare matching price periods and units before using them in a market report.

### How to use

Open the Actor input form and paste one or more Property Finder UAE search URLs into `startUrls`. Set `maxItems` to the number of unique property listings you want. A URL can already contain the site's sale or rental mode, property type, location, and price filters. The Actor preserves those filters while changing the `page` parameter to read later results.

For a search without a pasted URL, leave `startUrls` empty. Choose `mode` as `buy` or `rent`, then optionally set `propertyTypeId`, `locationId`, `minPrice`, `maxPrice`, or `bedrooms`. The Actor builds a Property Finder search URL from these values. Location and property type IDs are the site's numeric identifiers; copy them from a working search URL if you do not know them. For example, a URL with `t=1` requests apartments. A location parameter uses `l`.

Empty or blocked targets complete successfully without placeholder rows. The final empty-result message suggests broader filters or residential AE proxy settings; logs identify failed targets. Later URLs still run, and collected rows remain. Invalid URLs fail with a corrective input message. maxItems is shared across every target.

### Input

The input fields are optional so either a pasted search URL or search options can start a run. The default search is public UAE sale listings. The proxy option is exposed because a residential UAE connection is important for this site. The schema prefill demonstrates a filtered apartment search; it is an example in the editor, not a requirement for API calls.

| Input field | Use |
| --- | --- |
| `startUrls` | Array of URL objects, e.g. `[{"url":"https://www.propertyfinder.ae/en/search?c=1"}]`. Accepts HTTPS UAE `/en/search` pages, not detail URLs or plain strings. Nonempty URLs override all search filters below. |
| `mode` | `buy` or `rent` for a generated search; default `buy`. |
| `propertyTypeId` | Property type ID for a generated search; `1` is an apartment example. |
| `locationId` | Location ID from a Property Finder search URL for a generated search. |
| `minPrice` | Minimum advertised price for a generated search. |
| `maxPrice` | Maximum advertised price for a generated search. |
| `bedrooms` | Array of bedroom labels for a generated search. |
| `maxItems` | Maximum number of unique property records; default 50. |
| `proxyConfiguration` | Apify Proxy settings; default residential UAE. |

For a reproducible apartment sale search, use:

```json
{
  "startUrls": [
    {"url": "https://www.propertyfinder.ae/en/search?c=1&t=1&fu=0&ob=mr"}
  ],
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "AE"
  }
}
```

To collect rental listings, use a rental search URL with `c=2` or omit `startUrls` and choose `"mode":"rent"`. The site can show yearly and monthly rental prices. Read `pricePeriod` alongside `price` before comparing rental amounts. A sale price with `pricePeriod` set to `sell` has a different meaning from a rent price with a periodic label.

### Output

The following shortened record is from a local run on October 14, 2026, of the apartment sale search shown above. The full dataset record also contained latitude, longitude, bathrooms, broker phone, images, reference, listed date, and description. Live listings can change between runs.

```json
{
  "id": "154608004",
  "sourceUrl": "https://www.propertyfinder.ae/en/search?c=1&t=1&fu=0&ob=mr&page=1",
  "url": "https://www.propertyfinder.ae/en/plp/buy/apartment-for-sale-dubai-downtown-dubai-burj-khalifa-area-burj-khalifa-154608004.html",
  "title": "Full Fountain View | Fully Upgraded | Vacant",
  "listingType": "buy",
  "propertyType": "Apartment",
  "price": 5999999,
  "currency": "AED",
  "pricePeriod": "sell",
  "location": "Burj Khalifa, Burj Khalifa Area, Downtown Dubai, Dubai",
  "bedrooms": "2",
  "sizeSqft": 1716,
  "agentName": "Yana Yavorska",
  "brokerName": "Metropolitan Premium Properties",
  "amenities": [
    "AC",
    "BW",
    "SE",
    "CP",
    "PA",
    "SP"
  ],
  "furnished": "YES",
  "completionStatus": "completed",
  "verified": true,
  "imageCount": 23,
  "agentPhone": "+97144286124"
}
```

Download the dataset or use the Apify API. Join runs by `id`; `sourceUrl` identifies the search page. `listedDate` comes from the listing. Images are URL links, not downloaded files.

### How much does it cost?

This Actor is charged per result pushed to the dataset. Each unique property row is charged once. Rows skipped because they are project ads or duplicate property IDs are not charged as results. The current rate and billing details are shown in the Actor's Pricing tab. Set `maxItems` to control the upper bound on returned rows.

The Actor fetches search pages through the proxy selected in `proxyConfiguration`. Search pages can be large, so a wider search or a larger `maxItems` may require more page requests. The output count, not the number of images or optional fields in a record, determines the result event count. Review the Pricing tab for the current terms before scheduling frequent runs.

### Use with AI agents (MCP)

An AI agent can call this Actor through Apify MCP when it needs structured UAE property listings. Configure the Apify MCP server with the Actor tool path:

```text
https://mcp.apify.com?tools=axiomworks/propertyfinder-listings-scraper
```

Give the agent a Property Finder search URL or a clear set of search options and a `maxItems` bound. Ask it to compare prices using the `currency` and `pricePeriod` fields, or to group listings by `location` and `propertyType`. Because listings change, include the run date in any saved analysis and retain the `sourceUrl` and `url` fields for review.

Example prompts for an MCP client:

- “Collect 20 apartment sale listings from this Property Finder search URL and show title, price, location, bedrooms, sizeSqft, and url.”
- “Get 30 rental property records from my search URL and compare price by pricePeriod, propertyType, and location.”
- “Find repeated property IDs across my saved datasets, then show the sourceUrl and reference for each match.”

Agents should treat null fields as unavailable source data. A missing `brokerPhone` or `sizeSqft` does not mean the property has no broker contact or size; it means the embedded listing did not provide a usable value to this Actor.

### Integrations and API

You can call the Actor from an Apify integration, a script, or an API client. Set your Apify token in the APIFY_TOKEN environment variable. The examples use the Actor's Store path and request a bounded set of results. They do not require a Property Finder login.

Python:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("axiomworks/propertyfinder-listings-scraper").call(
    run_input={"mode": "rent", "maxItems": 20}
)
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(len(items))
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/propertyfinder-listings-scraper')
  .call({ mode: 'buy', propertyTypeId: 1, maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
process.stdout.write(String(items.length));
```

cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~propertyfinder-listings-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"buy","propertyTypeId":1,"maxItems":20}'
```

For scheduled monitoring, compare records by `id` and retain `sourceUrl`; changing search order can move listings between pages.

### FAQ

**Can I use a URL with filters already applied?** Yes. Paste a public `/en/search` URL into `startUrls`. Its query parameters determine the search. The Actor changes only the page number as it paginates. This is often the easiest way to target an emirate, neighborhood, or a particular property type.

**Why are there fewer results than `maxItems`?** The search may have fewer property listings, or some entries may be project advertisements. Duplicate property IDs across pages are removed. A blocked or changed search response can also stop pagination early; the run log records that condition.

**Does it visit property pages?** No. The details in a row are taken from the embedded search result record. This keeps the request rate modest and ensures `sourceUrl` points to the page that supplied the values. Some detail-page-only information is outside this Actor's output.

**How are sale and rental prices represented?** The numeric amount is `price`, while `currency` and `pricePeriod` explain its unit and interval. The `listingType` field groups sale as `buy` and rental as `rent`. Compare these fields together.

**Why is a field null?** Property Finder may omit it from the embedded listing, or its value may not be in the expected type. The Actor keeps the row and leaves that field null. The `images` field is always an array and may be empty.

### Is it legal to scrape Property Finder?

This Actor accesses public search pages without logging in. You are responsible for deciding whether your intended use complies with applicable law and Property Finder's terms. Respect rights in listing descriptions and images, protect any personal data you retain, and use the data in a way that fits your purpose. This Actor is an independent tool and is not affiliated with or endorsed by Property Finder.

### Feedback

If a field becomes empty unexpectedly, share the search URL, the affected field name, and the run log through the Actor's feedback channel. If pagination stops early, include the last `sourceUrl` and the requested `maxItems`. Those details help distinguish a site layout change from a search with no more property rows.

# Actor input Schema

## `startUrls` (type: `array`):

List of objects with a url key, e.g. \[{"url":"https://www.propertyfinder.ae/en/search?c=1\&t=1"}]; plain URL strings and detail /en/plp/ URLs are not accepted. Use HTTPS UAE /en/search URLs. Nonempty startUrls override mode and all filters below. Omit or use \[] for the default UAE sale search. Unavailable or blocked targets return no rows and later URLs continue.

## `mode` (type: `string`):

Choose "buy" for sale listings (default) or "rent" for rentals, e.g. "rent". Used only when startUrls is omitted or empty; all UAE property types are searched unless filters below are set.

## `propertyTypeId` (type: `integer`):

Property Finder type ID, e.g. 1 for apartments (t=1 in a search URL). Minimum 1; omit for all property types. Used only when startUrls is omitted or empty.

## `locationId` (type: `string`):

Property Finder location ID as a string, e.g. "41" from l=41 in a working search URL. Omit for all UAE. Accepts IDs, not place names; used only when startUrls is omitted or empty.

## `minPrice` (type: `integer`):

Lowest advertised price in AED, e.g. 500000. Minimum 0; omit for no lower bound. Used only when startUrls is omitted or empty. Rental amounts follow each listing’s advertised period, not a converted annual price.

## `maxPrice` (type: `integer`):

Highest advertised price in AED, e.g. 2000000. Minimum 0; omit for no upper bound. Choose a value at least minPrice. Used only when startUrls is omitted or empty; rental amounts follow the advertised period.

## `bedrooms` (type: `array`):

Bedroom labels as strings, e.g. \["1","2"] or \["studio"], not numeric values. Copy labels from bdr\[] in a working search URL. Omit or use \[] for all bedroom counts. Used only when startUrls is omitted or empty; values become bdr\[] parameters.

## `maxItems` (type: `integer`):

Maximum unique property rows across all startUrls combined, e.g. 7. Integer 1-10000, default 50; prefill 30. Duplicate IDs and project ads do not count. Empty searches or blocked targets may return fewer rows.

## `proxyConfiguration` (type: `object`):

Apify proxy options, e.g. {"useApifyProxy":true,"apifyProxyGroups":\["RESIDENTIAL"],"apifyProxyCountry":"AE"} (default). Property Finder may block direct or datacenter requests. Repeated blocks stop that target; use a residential AE proxy or try another working search URL.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.propertyfinder.ae/en/search?c=1&t=1&fu=0&ob=mr"
    }
  ],
  "mode": "buy",
  "propertyTypeId": 1,
  "locationId": "41",
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AE"
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Structured property listing records.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.propertyfinder.ae/en/search?c=1&t=1&fu=0&ob=mr"
        }
    ],
    "mode": "buy",
    "propertyTypeId": 1,
    "locationId": "41",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/propertyfinder-listings-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.propertyfinder.ae/en/search?c=1&t=1&fu=0&ob=mr" }],
    "mode": "buy",
    "propertyTypeId": 1,
    "locationId": "41",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/propertyfinder-listings-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.propertyfinder.ae/en/search?c=1&t=1&fu=0&ob=mr"
    }
  ],
  "mode": "buy",
  "propertyTypeId": 1,
  "locationId": "41",
  "maxItems": 30
}' |
apify call axiomworks/propertyfinder-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/propertyfinder-listings-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/RibzNyfJJRmOuNypz/builds/6yDsyNLVUXZisVe68/openapi.json
