# Property24 Scraper - SA Property Listings & Agent Data (`haketa/property24-scraper`) Actor

Scrape Property24 SA real estate: for-sale, to-rent, sold properties with price, beds, baths, floor size, location, agent data. SA property data, market research and lead gen.

- **URL**: https://apify.com/haketa/property24-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 8 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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

## Property24 Scraper — South Africa Real Estate Listings, Prices & Agent Data

> **Extract structured property listings from [Property24.com](https://www.property24.com) — South Africa's #1 real estate portal — without login or coding.** Scrape **For Sale, To Rent, and Sold** properties across all 9 South African provinces, major metros, and suburbs: **price in ZAR, formatted price, title, description, suburb/location, bedrooms, bathrooms, parking spaces, floor/erf size (m²), listing URL, photo, and agency branding**.
>
> Export clean, de-duplicated South African property data to **JSON, CSV, Excel, or API** in seconds.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-00C853?logo=apify\&logoColor=white)](https://apify.com/haketa/property24-scraper)
[![Market](https://img.shields.io/badge/Market-South%20Africa%20Real%20Estate-007ec6)]()
[![Listings](https://img.shields.io/badge/Listings-For%20Sale%20%7C%20To%20Rent%20%7C%20Sold-2da44e)]()
[![Scale](https://img.shields.io/badge/Scale-1%2C000%2B%20Properties%20Pagination-8A2BE2)]()
[![No Auth](https://img.shields.io/badge/Authentication-None%20Required-success)]()
[![Export](https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel%20%7C%20API-fb8500)]()

> **Built for** South African property investors, real estate analysts, estate agencies, bond originators, proptech platforms, valuation & CMA teams, and B2B lead-generation agencies.

***

### ⚡ At a glance

| Feature | Details |
|---|---|
| **Target Portal** | [Property24.com](https://www.property24.com) — South Africa's largest property marketplace |
| **Listing Types** | `for-sale` (For Sale), `to-rent` (To Rent), and `sold` (Sold Properties archive) |
| **Location Coverage** | All **9 SA provinces** (`Gauteng`, `Western Cape`, `KwaZulu-Natal`, `Eastern Cape`, `Free State`, `Limpopo`, `Mpumalanga`, `North West`, `Northern Cape`), 22+ built-in cities/suburbs, plus **any custom Property24 URL** via `startUrls` |
| **Pagination & Scale** | Automatic `/p2`, `/p3`… deep pagination (~20 properties per page) — scales cleanly to **1,000+ listings per run** |
| **Card Layout Support** | Parses both standard listing tiles and boosted/premium development tiles (~100% title & price coverage) |
| **De-duplication** | Automatic in-memory de-duplication by `listingNumber` / `propertyId` across all pages and locations (`0 duplicates`) |
| **Speed & Cost** | Lightweight HTTP extraction with datacenter proxies — 100 properties in ~10–20 seconds |
| **Export Formats** | JSON, CSV, Excel (XLSX), HTML, XML, RSS, and Apify API |

***

### 🔎 Why scrape Property24?

**Property24** is the undisputed leader in South African real estate classifieds, hosting hundreds of thousands of residential and commercial properties for sale and rent across Johannesburg, Cape Town, Pretoria, Durban, Sandton, Centurion, Umhlanga, Stellenbosch, and every province in the country. For anyone analyzing the **South African housing market**, Property24 is the primary source of asking prices, rental yields, erf/floor sizes, and estate agency inventory.

However, Property24 provides **no public API and no CSV export**, and listings are split across thousands of paginated `/p2`, `/p3` result pages that mix standard property cards with boosted development banners. Manually copying listings into Excel is slow and error-prone. This **Property24 scraper** automates the entire process: it resolves your selected provinces and cities, paginates automatically through search results up to **1,000+ properties**, handles both standard and premium card layouts, de-duplicates every listing by `listingNumber`, and outputs a clean dataset ready for analysis.

#### Common reasons teams use this Property24 data extractor:

- 📈 **South African real estate market research** — monitor asking prices, price per m², and active inventory across Gauteng, Western Cape, KwaZulu-Natal, and all nine provinces.
- 💰 **Rental yield & investment screening** — compare `for-sale` prices against `to-rent` monthly rents across suburbs like Sandton, Midrand, Centurion, Rosebank, and Somerset West.
- 🏘️ **Comparative Market Analysis (CMA) & automated valuation (AVM)** — combine active listings with `sold` property records to benchmark valuations by bedroom count and floor/erf size.
- 🧑‍💼 **Estate agency & competitor intelligence** — track which agencies (`agentTitle`) dominate featured inventory in target suburbs.
- 🔔 **Automated price-drop & new-listing alerts** — schedule daily or weekly runs and diff on `listingNumber` + `price` to spot motivated sellers and newly listed stock.
- 🗄️ **Proptech & BI pipeline ingestion** — feed normalized ZAR property data directly into Snowflake, BigQuery, PostgreSQL, Power BI, or Google Sheets.

***

### ✨ What this Property24 scraper does

- ✅ **Scrape For Sale, To Rent, or Sold listings (`listingType`)** — switch between active sales (`for-sale`), rentals (`to-rent`), and historical sold records (`sold`).
- ✅ **Built-in SA Province, City & Suburb Selector (`locations`)** — choose from all 9 provinces and major metros/suburbs:
  - **Provinces**: `gauteng`, `western-cape`, `kwazulu-natal`, `eastern-cape`, `free-state`, `limpopo`, `mpumalanga`, `north-west`, `northern-cape`
  - **Metros & Suburbs**: `cape-town`, `johannesburg`, `pretoria`, `durban`, `port-elizabeth` (`gqeberha`), `bloemfontein`, `east-london`, `polokwane`, `nelspruit` (`mbombela`), `sandton`, `alberton`, `centurion`, `midrand`, `roodepoort`, `kibler-park`, `umhlanga`, `stellenbosch`, `somerset-west`, `paarl`, `george`, `krugersdorp`, `randburg`
- ✅ **Custom Filtered Search URLs (`startUrls`)** — paste any URL from property24.com (pre-filtered by suburb, property type, min/max price, bedrooms, or pet-friendly status) and the scraper paginates `/p2`, `/p3`… automatically while preserving your exact query parameters.
- ✅ **Unlocked 1,000+ Deep Pagination** — with `maxPages: 0` (the default), the scraper continues queuing `/p{N}` pages until your `maxItems` target is reached or the location has no further pages.
- ✅ **Standard + Boosted/Development Tile Parsing** — extracts numeric `price` (including starting price on `"From R 2 388 000 To R ..."` development cards), `priceFormatted`, `title`, and lazy-loaded high-resolution `image` URLs across all card templates.
- ✅ **Resilient Session & Retry Handling** — automatically retries transient 503 responses (up to 8 attempts with session/IP rotation) so deep multi-page crawls never stop prematurely.

***

### 🎯 Use cases & B2B workflows

#### 1. Property Investors & Buy-to-Let Funds

Run two automated jobs per target suburb (e.g., `centurion`, `midrand`, `sandton`, `umhlanga`): one with `listingType: "for-sale"` and one with `listingType: "to-rent"`. Join on `location` and `bedrooms` to calculate gross rental yields and price-per-square-meter (`price / floorSizeM2`) across thousands of properties.

#### 2. Estate Agencies, Valuers & Bond Originators

Track market supply, days-on-market (by scheduling daily snapshots), and competitor promotion share (`agentTitle`, `agentLogo`). Pull `sold` listings to anchor client listing presentations with verifiable local comparables.

#### 3. Proptech Portals, Relocation Firms & Data Analysts

Use `startUrls` to monitor niche segments — such as sectional-title apartments under R 1,500,000 in Cape Town or industrial/commercial properties in Johannesburg — and stream the results via webhook or REST API into your application.

#### 4. Mortgage Originators, Banks & Insurance Underwriters

Analyze regional housing stock by province and suburb (`floorSizeM2`, `bedrooms`, `price`) to calibrate home-loan risk models, replacement-cost estimates, and regional affordability indices across South Africa.

***

### 🌍 Built-in South African provinces, cities & suburbs

| Category | Supported `locations` Values |
|---|---|
| **All 9 SA Provinces** | `gauteng`, `western-cape`, `kwazulu-natal`, `eastern-cape`, `free-state`, `limpopo`, `mpumalanga`, `north-west`, `northern-cape` |
| **Gauteng Metros & Suburbs** | `johannesburg`, `pretoria`, `sandton`, `centurion`, `midrand`, `randburg`, `roodepoort`, `alberton`, `krugersdorp`, `kibler-park` |
| **Western Cape Cities & Winelands** | `cape-town`, `stellenbosch`, `somerset-west`, `paarl`, `george` |
| **KwaZulu-Natal & Coastal Metros** | `durban`, `umhlanga`, `port-elizabeth` (`gqeberha`), `east-london` |
| **Inland Provincial Capitals** | `bloemfontein`, `polokwane`, `nelspruit` (`mbombela`) |
| **Any Other Suburb / Estate** | Paste any Property24 search URL into `startUrls` (e.g., Sea Point, Camps Bay, Ballito, Bryanston, Waterfall, Fourways) |

***

### 📥 Input configuration

All fields are optional (`required: []`). Leave `locations` and `startUrls` empty to collect a nationwide sample across South Africa's largest provinces and metros.

| Parameter | Type | Default / Prefill | Description |
|---|---|---|---|
| `listingType` | `string` | `"for-sale"` | Type of listings to scrape: `"for-sale"`, `"to-rent"`, or `"sold"`. |
| `locations` | `array<string>` | Prefill: `["gauteng"]` | One or more SA provinces, cities, or suburbs from the dropdown. Leave empty for a nationwide multi-location sweep. |
| `maxItems` | `integer` | Default: `0` (Prefill: `100`) | Maximum total properties to collect across all locations (`0` = unlimited). Set `1000`+ for large regional datasets. |
| `maxPages` | `integer` | `0` | Maximum search result pages per location (~20 properties per page). `0` = automatic pagination governed by `maxItems`. |
| `includeDetails` | `boolean` | `false` | Reserved for future detail enrichment. Keep `false` for fast listing extraction. |
| `startUrls` | `array` | `[]` | Optional Property24 search result URLs (with any custom price, bedroom, or suburb filters). Paginates `/p2`, `/p3`… automatically. |
| `proxyConfiguration` | `object` | Apify Proxy | Proxy configuration. Default Apify datacenter proxy (`{ "useApifyProxy": true }`) works fast and reliably. |

#### Example 1 — 1,000+ For-Sale listings across Gauteng, Western Cape & KwaZulu-Natal

```json
{
  "listingType": "for-sale",
  "locations": ["gauteng", "western-cape", "kwazulu-natal"],
  "maxItems": 1000,
  "maxPages": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

#### Example 2 — Rental market sweep across Cape Town, Sandton & Umhlanga

```json
{
  "listingType": "to-rent",
  "locations": ["cape-town", "sandton", "umhlanga", "stellenbosch"],
  "maxItems": 400,
  "maxPages": 0
}
```

#### Example 3 — Custom filtered Property24 Search URL (`startUrls`)

```json
{
  "startUrls": [
    { "url": "https://www.property24.com/for-sale/sea-point/cape-town/western-cape/11021" },
    { "url": "https://www.property24.com/for-sale/green-point/cape-town/western-cape/11017" }
  ],
  "maxItems": 300,
  "maxPages": 0
}
```

***

### 📤 Output schema & field reference

Each property is saved as a structured JSON object. Below is a real record from a live `for-sale` run in Gauteng:

```json
{
  "propertyId": "117212365",
  "listingNumber": "117212365",
  "title": "3 Bedroom Apartment / Flat for sale in Blyde Riverwalk Estate",
  "description": "3 Bedroom Apartment in Blyde Riverwalk Estate",
  "price": 1699900,
  "priceFormatted": "R 1 699 900",
  "location": "Blyde Riverwalk Estate",
  "bedrooms": 3,
  "bathrooms": 2,
  "parkingSpaces": 2,
  "floorSizeM2": 105,
  "listingUrl": "https://www.property24.com/for-sale/blyde-riverwalk-estate/pretoria/gauteng/33014/117212365?plId=2681220",
  "image": "https://images.prop24.com/387509815/Crop526x328",
  "agentTitle": "Pam Golding Properties",
  "agentLogo": "https://images.prop24.com/21849123/Crop120x60",
  "availableBadge": null,
  "availableDate": null,
  "listingType": "for-sale",
  "searchLocation": "gauteng",
  "scrapedAt": "2026-11-10T02:55:00.000Z"
}
```

#### 🏠 Property Identity & Pricing

| Field | Type | Coverage | Description |
|---|---|---|---|
| `propertyId` | `string\|null` | 🟢 High (100%) | Numeric Property24 ID parsed from the canonical listing path. |
| `listingNumber` | `string\|null` | 🟢 High (100%) | Official Property24 listing number (`data-listing-number`). Primary de-duplication key. |
| `title` | `string\|null` | 🟢 High (100%) | Full listing headline (e.g., `"3 Bedroom House for sale in Sandton"`). |
| `description` | `string\|null` | 🟢 High (~98%) | Summary description / excerpt displayed on the search card. |
| `price` | `number\|null` | 🟢 High (~98%) | Numeric price in South African Rand (`ZAR`). `null` only on `"POA"` (Price on Application) listings. |
| `priceFormatted` | `string` | 🟢 High (100%) | Display price string as shown on Property24 (`"R 1 699 900"`, `"POA"`, or `"From R 2 388 000 To ..."`). |
| `listingType` | `string` | 🟢 High (100%) | Market type scraped: `"for-sale"`, `"to-rent"`, or `"sold"`. |

#### 📐 Property Attributes & Location

| Field | Type | Coverage | Description |
|---|---|---|---|
| `location` | `string\|null` | 🟢 High (100%) | Suburb, estate, or area name displayed on the listing tile. |
| `searchLocation` | `string` | 🟢 High (100%) | Input location slug or start-URL label that produced this record. |
| `bedrooms` | `number\|null` | 🟢 High (~92%) | Number of bedrooms (present on houses/apartments; `null` on vacant land/plots). |
| `bathrooms` | `number\|null` | 🟢 High (~92%) | Number of bathrooms (present when specified on the listing). |
| `parkingSpaces` | `number\|null` | 🟢 High (~80%) | Number of garages / parking bays when specified. |
| `floorSizeM2` | `number\|null` | 🟢 High (~85%) | Floor area or erf (land) size in square meters (`m²`). |

#### 🖼️ Media, Agency Branding & Rental Availability

| Field | Type | Coverage | Description |
|---|---|---|---|
| `listingUrl` | `string\|null` | 🟢 High (100%) | Direct URL to the property's detail page on Property24.com. |
| `image` | `string\|null` | 🟢 High (~99%) | Primary property photo URL (resolved from lazy-load attributes). |
| `agentTitle` | `string\|null` | 🟡 Conditional | Real estate agency / branch name when displayed on the listing card. |
| `agentLogo` | `string\|null` | 🟡 Conditional | Agency logo URL when displayed on featured/boosted cards. |
| `availableBadge` | `string\|null` | 🟡 Rentals | Availability status badge (e.g., `"Available Now"`, common on `to-rent` listings). |
| `availableDate` | `string\|null` | 🟡 Rentals | Move-in availability date when shown on rental cards. |
| `scrapedAt` | `string` | 🟢 High (100%) | ISO 8601 UTC timestamp of extraction. |

***

### 🔁 Pagination, scale & 1,000+ property crawls

Property24 serves **~20 listings per result page** at `/for-sale/{slug}/{id}/p2`, `/p3`, `/p4`…:

- **Automatic deep pagination (`maxPages: 0`)**: As long as a page returns listings and `totalSaved < maxItems`, the scraper automatically queues the next `/p{N}` page (up to 1,000 pages / ~20,000 properties per location).
- **1,000+ properties on any run**: Whether you select one province (`["gauteng"]`), multiple cities, or leave `locations` empty with `maxItems: 1000`, the actor honors your requested `maxItems` without clamping down to 100.
- **Transient 503 resilience**: Property24 occasionally returns HTTP 503 under load. The scraper uses an 8-retry budget with automatic session/IP rotation so linear pagination chains never break mid-crawl.

***

### ⚙️ How to use

1. **Open the Actor** in the Apify Console.
2. **Pick `listingType`**: choose **For Sale**, **To Rent**, or **Sold Properties**.
3. **Select `locations`**: pick one or more South African provinces, cities, or suburbs (or paste custom filtered URLs into `startUrls`).
4. **Set `maxItems`**: keep `100` for a fast 15-second run, or set `1000`+ for bulk market extraction.
5. **Click Start** and export your dataset as **JSON, CSV, Excel, or HTML**, or fetch it via the Apify API.

#### API Example (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("haketa/property24-scraper").call(run_input={
    "listingType": "for-sale",
    "locations": ["cape-town", "sandton", "umhlanga"],
    "maxItems": 600,
    "maxPages": 0,
})

for prop in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{prop['listingNumber']} | {prop['priceFormatted']} | {prop['bedrooms']} bed | {prop['location']} | {prop['listingUrl']}")
```

#### API Example (Node.js)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('haketa/property24-scraper').call({
    listingType: 'to-rent',
    locations: ['gauteng'],
    maxItems: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Collected ${items.length} South African rental listings`);
```

#### API Example (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~property24-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "listingType": "for-sale",
    "locations": ["gauteng", "western-cape"],
    "maxItems": 1000,
    "maxPages": 0
  }'
```

***

### 🔄 Automation & integration workflows

| Integration | Workflow Example |
|---|---|
| **Google Sheets / Excel** | Export ZAR prices, bedroom/bathroom counts, floor/erf sizes (`m²`), and suburb names directly into investment screening models. |
| **Make.com / Zapier / n8n** | Schedule daily runs on target suburbs (`sandton`, `cape-town`, `umhlanga`) and trigger Slack/WhatsApp/email alerts when new properties appear below target price per m². |
| **PostgreSQL / BigQuery / Power BI** | Ingest multi-province datasets via the Apify Dataset API, using `listingNumber` as the primary key to track price history and time-on-market. |

***

### 💡 Pro tips for best results

- **Scrape any suburb in South Africa via `startUrls`**: If your target suburb isn't in the 31-item `locations` dropdown, simply search for that suburb on [property24.com](https://www.property24.com), copy the URL from your browser, and paste it into `startUrls`.
- **Combine `for-sale` and `sold` runs**: Compare active asking prices (`for-sale`) with historical (`sold`) records in the same suburb to identify over-priced vs. fairly priced listings.
- **Keep default datacenter proxies**: Property24 does not require costly residential proxies — standard Apify datacenter proxies run fast and cost-effectively.

***

### ⚠️ Honest limitations

- **POA listings**: High-end luxury properties listed as `"POA"` (Price On Application) have `priceFormatted: "POA"` and `price: null`.
- **Plot & vacant land attributes**: Vacant land, farms, and commercial plots often do not have `bedrooms`, `bathrooms`, or `parkingSpaces`; those fields are returned as `null` while `floorSizeM2` captures the erf size.

***

### ❓ FAQ

#### Does Property24 have a public API?

No. Property24 does not offer a public API for downloading listings. This scraper provides a clean, automated JSON/CSV/Excel interface to live Property24 data.

#### How many listings can I scrape in a single run?

You can scrape **1,000 to 50,000+ listings** in a single run. With `maxPages: 0`, pagination continues automatically across `/p2`, `/p3`… until `maxItems` is reached.

#### Can I apply price or bedroom filters?

Yes — apply any filter combination on property24.com (price min/max, property type, bedrooms, bathrooms) and paste the resulting URL into `startUrls`.

#### Do I need an account or residential proxy?

No account is required, and standard Apify datacenter proxies work out of the box.

#### How does the scraper handle new-development range prices?

New-development cards on Property24 often display a price range such as `"From R 2 388 000 To R 26 938 250"`. The scraper sets `price` to the numeric starting amount (`2388000`) for clean sorting/filtering and preserves the full text in `priceFormatted`.

#### What happens if I run the actor with empty input (`{}`)?

If both `locations` and `startUrls` are empty, the scraper automatically samples across South Africa's 9 provinces and top metros so you get a clean 100-property dataset (or your requested `maxItems`).

#### How are duplicates prevented when scraping overlapping locations?

For example, if you select both `"gauteng"` and `"sandton"` in the same run, every property is de-duplicated in memory by `listingNumber` (with fallback to `propertyId`), ensuring `0` duplicate rows in the output dataset.

#### Can I scrape commercial, industrial, or agricultural properties on Property24?

Yes! Navigate to the Commercial, Industrial, or Farm/Agricultural search results on [property24.com](https://www.property24.com), copy the search URL from your browser's address bar, and paste it into `startUrls`. The scraper will extract and paginate all matching cards automatically.

#### What is the difference between `propertyId` and `listingNumber`?

`listingNumber` is the official reference code displayed on the Property24 listing card (`data-listing-number`), while `propertyId` is the numeric identifier extracted from the canonical property URL path. Both uniquely identify the listing.

#### Can I schedule daily or weekly South African market snapshots?

Yes. Use **Apify Schedules** to run your saved location configuration automatically on a daily, weekly, or monthly cadence and connect a webhook, Google Sheets, or database integration to track price movements over time.

***

### 📊 Sample analysis metrics you can compute from the output

| Metric | Formula / Fields Used | Business Use Case |
|---|---|---|
| **Price per m² (ZAR)** | `price / floorSizeM2` | Identify undervalued homes or apartments within a specific suburb (`location`). |
| **Gross Rental Yield (%)** | `(annual_rent / sale_price) * 100` | Compare `to-rent` vs. `for-sale` median prices by `location` and `bedrooms`. |
| **Suburb Inventory Depth** | `COUNT(listingNumber)` grouped by `location` | Measure active housing supply and seller competition per neighbourhood. |
| **Agency Market Share** | `COUNT(listingNumber)` grouped by `agentTitle` | Benchmark real-estate agency footprint across featured listings. |

***

### 🔗 Related scrapers

Explore our other international real-estate scrapers:

- [Centris.ca Scraper](https://apify.com/haketa/centris-scraper) — Quebec (Canada) MLS real estate listings, prices, GPS, and brokers.
- [Realtor.ca Scraper](https://apify.com/haketa/realtor-ca-scraper) — Canada-wide MLS property listings and agent data.
- [Yad2 Scraper](https://apify.com/haketa/yad2-scraper) — Israel real estate and classifieds portal.
- [ZAP Imóveis Scraper](https://apify.com/haketa/zapimoveis-scraper) — Brazil property listings and prices.
- [Domain.com.au Scraper](https://apify.com/haketa/domain-com-au-scraper) — Australian real estate listings and auction results.

***

### 📋 Changelog

#### v1.2 (2026-11)

- **Unlocked 1,000+ Deep Pagination**: Added configurable `maxPages` (`default: 0` = auto up to 1,000 pages per location) and removed the 100-item clamp when `maxItems > 100` is requested with default/empty locations.
- **Expanded Nationwide Default Locations**: Expanded fallback coverage across all 9 SA provinces and 12 major metros (`gqeberha` and `mbombela` aliases added).
- **Enhanced Status Reporting & Documentation**: Added final run summary status messages and comprehensive field coverage tables.

#### v1.1 (2026-10)

- Added support for boosted/premium development card layouts, range price parsing (`"From R ..."`), and lazy-loaded image extraction.

#### v1.0 (2026-08)

- Initial release supporting `for-sale`, `to-rent`, and `sold` listings across South African provinces and cities.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/property24-scraper/changelog.md

# Actor input Schema

## `listingType` (type: `string`):

Choose which kind of property listings you want to collect.

## `locations` (type: `array`):

Pick one or more South African provinces, cities or suburbs to search. Leave empty to get a broad nationwide sample across the biggest metros.

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

Maximum number of properties to collect across all selected locations. Use 0 for no limit.

## `maxPages` (type: `integer`):

Maximum search result pages to paginate per location (~20 properties per page). Set 0 for automatic pagination governed by maxItems.

## `includeDetails` (type: `boolean`):

Reserved for future full-detail enrichment. Leave off for the fast listing scrape.

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

Power users only: paste specific Property24 search result URLs to scrape exactly those pages. Most users can ignore this and just pick locations above.

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

Proxy is recommended for larger runs to keep collection fast and reliable. The default Apify proxy works well.

## Actor input object example

```json
{
  "listingType": "for-sale",
  "locations": [
    "gauteng"
  ],
  "maxItems": 100,
  "maxPages": 0,
  "includeDetails": false,
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Open to view, filter and export all scraped results from this run (JSON, CSV, Excel).

# 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 = {
    "listingType": "for-sale",
    "locations": [
        "gauteng"
    ],
    "maxItems": 100,
    "includeDetails": false,
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/property24-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 = {
    "listingType": "for-sale",
    "locations": ["gauteng"],
    "maxItems": 100,
    "includeDetails": False,
    "startUrls": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/property24-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 '{
  "listingType": "for-sale",
  "locations": [
    "gauteng"
  ],
  "maxItems": 100,
  "includeDetails": false,
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/property24-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/property24-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/jLOOdMZwNdanqGQvX/builds/PKaZIwJZ6Rt0IDH4n/openapi.json
