Private Property Scraper - South Africa Listings & API avatar

Private Property Scraper - South Africa Listings & API

Pricing

from $0.89 / 1,000 area searches

Go to Apify Store
Private Property Scraper - South Africa Listings & API

Private Property Scraper - South Africa Listings & API

Scrape privateproperty.co.za for sale and to rent across all 9 South African provinces: price, beds, baths, erf and floor size, levies, rates, suburb, agent, on-show and repossessed stock. JSON, CSV or Excel.

Pricing

from $0.89 / 1,000 area searches

Rating

0.0

(0)

Developer

SIÁN OÜ

SIÁN OÜ

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Private Property Scraper — South Africa Listings & Real Estate API 🏘️

SIÁN Agency Store Property24 Scraper Rightmove Scraper Smart Idealista Scraper

🎉 Every South African listing as a typed row — price, erf size, levies, rates and the agency, in one export

Built for property analysts, buy-to-let investors, estate agencies and anyone tired of copying asking prices out of a browser tab


🔎 What is the Private Property South Africa Scraper — and when should you use it?

The Private Property South Africa Scraper turns public privateproperty.co.za listings from anywhere in South Africa into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

Use it when you need: South African sale and rental listings as rows: asking price or monthly rent in rands, bedrooms, bathrooms, parking, erf and floor size in square metres, the suburb, city and province, a photo, and the agency holding the mandate. Every row is also flagged new, price-reduced, under offer, sold or on show, and says whether the owner listed it themselves rather than an agency. Switch on the full record and each row additionally carries the listing text, the complete photo set, the listing date, the property type and — on for-sale stock — the levies and the rates and taxes.

Use something else when: the property is not in South Africa, or you want the other South African portal. Use Property24 Scraper for the other South African portal, plus Namibia, Botswana, Zambia, Zimbabwe, Mozambique and Kenya, with the same column names so the two exports merge. Use Rightmove Scraper for the UK, including sold prices. Use Smart Idealista Scraper for Spain, Italy and Portugal. This actor covers the surfaces privateproperty.co.za publishes to a visitor: residential for sale and to rent, houses, apartments, townhouses, land and garden cottages, plus farms, commercial premises and the on-show list. Agent phone numbers are not on those pages, so they are not returned, and the portal publishes asking prices only — what a property actually sold for comes from the deeds office, not from here.

🤖 Use with AI agents

Already connected to the Apify MCP server? Just ask for this Actor by name: sian.agency/privateproperty-property-scraper

Your agent can pay for its own runs. This Actor is eligible for agentic payments, so an agent can discover it, run it and settle the bill over x402 (USDC on Base) or Skyfire — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

I want property listings and asking prices from privateproperty.co.za using the Apify Actor `sian.agency/privateproperty-property-scraper`.
Use it when I need: South African sale and rental listings as rows: asking price or monthly rent in rands, bedrooms, bathrooms, parking, erf and floor size in square metres, the suburb, city and province, a photo, and the agency holding the mandate. Every row is also flagged new, price-reduced, under offer, sold or on show, and says whether the owner listed it themselves rather than an agency. Switch on the full record and each row additionally carries the listing text, the complete photo set, the listing date, the property type and — on for-sale stock — the levies and the rates and taxes.
Don't use it when: the property is not in South Africa, or you want the other South African portal — use property24-property-scraper or rightmove-property-scraper or smart-idealista-scraper instead.
How to call it: give `locations` a list of South African places written as the portal writes them — a suburb ("Sea Point", "Midstream Estate"), a city ("Cape Town", "Durban"), a region ("Atlantic Seaboard") or a province ("Western Cape"). Names are matched against the portal's own published area index while the run starts, so there is no area id to look up, and a name that cannot be matched comes back with the nearest ones that were actually seen. Set `listingType` to `for-sale` or `to-rent`, or to `on-show`, `farms-for-sale`, `farms-to-rent`, `commercial-sales` or `commercial-rentals` for those sections. `propertyType` narrows the two residential sides to houses, apartments, townhouses, land or garden cottages. Narrow further with `minPrice`, `maxPrice`, `minBedrooms`, `minBathrooms` and `minParkingSpaces` — each goes to the portal's own filter, so anything excluded is never saved and never billed, and on the rental side the price bounds are monthly rent. `includeDetails` opens every listing for its full text, photo set, listing date, levies and rates, at an extra charge per listing. To expand listings you already have, set `operation` to `listing` and pass `listingUrls`; to run a search you built in your browser, paste it into `searchUrls` and it runs exactly as given.
Start with this input:
{
"operation": "search",
"locations": [
"Sea Point",
"Sandton"
],
"listingType": "for-sale",
"minPrice": 2000000,
"maxPrice": 6000000,
"maxResults": 200
}
Ask me which South African areas to cover, whether I want listings for sale or to rent, and whether the full listing text, photo set, levies and rates are worth the extra per-listing charge, then run the Actor and summarise the results as a table.

Things you can ask your agent for:

  • Pull apartments for sale in Sea Point between R3 million and R8 million and rank the buildings by price per square metre.
  • Find three-bedroom houses to rent in Sandton under R35,000 a month, with the agency on every row.
  • Give me this week's on-show listings in Cape Town and Pretoria with the suburb, asking price and a photo.

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at apify.com/sian.agency/privateproperty-property-scraper.md.

📋 Overview

Two portals carry most of South Africa's residential stock, and this one covers the second of them properly. It reads privateproperty.co.za the way a visitor does and writes every listing out as a row, with the numbers typed as numbers.

What you get:

  • Place names, not area ids: type "Sea Point" or "Western Cape". Names resolve against the portal's own published area index while the run starts, so nothing is hard-coded and nothing rots.
  • All nine provinces, at four grains: province, city, region or suburb — plus the whole country if you leave the area list empty.
  • 🎯 Numbers that are numbers: R 3 950 000 becomes 3950000, and "735 m²" becomes 735. No parsing project at the other end.
  • 💰 Charged per listing returned: a search that matched nothing, and any input that could not be read, cost you nothing.
  • 💎 Levies, rates and map coordinates: published on the for-sale side and returned on the full record, which most exports of this portal simply do not carry.
  • Column-for-column parity with our Property24 Scraper: run both, stack the exports, and you have the South African market in one table.

✨ Features

  • 🔍 Area search: sweep a suburb, city, region, province or the whole country and page through every result.
  • 🏠 Full listing record: description, every photo, listing date, property type, levies, rates and taxes, and map coordinates where the portal publishes them.
  • 📍 Name-based areas: 7,600-plus areas resolved from the portal's own index. A name that misses comes back with the nearest ones actually seen, not a bare failure.
  • 🎚️ Five filters that genuinely filter: minimum and maximum price, minimum bedrooms, bathrooms and parking. Each was checked against the portal's own result count and against the rows it returns.
  • 🏷️ Seven sections: for sale, to rent, on show this weekend, farms for sale, farms to rent, commercial for sale and commercial to rent.
  • 🏘️ Five property types: houses, apartments and flats, townhouses, land and plots, and garden cottages.
  • 🚩 Status flags on every row: new, price-reduced, under offer, sold or let, on show, and listed by the owner rather than an agency.
  • 🔗 Paste your own search: a results page URL you built in the browser runs exactly as given, filters and all.
  • 📤 Export anywhere: JSON, CSV or Excel straight out of the dataset, plus an HTML run report.

🎬 Quick Start

Pick your areas, pick for sale or to rent, press Start. The run tells you how many listings the portal holds for that search before it reads a single extra page, and stops at the row budget you set.

curl -X POST "https://api.apify.com/v2/acts/sian.agency~privateproperty-property-scraper/runs?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"operation": "search", "locations": ["Sea Point"], "listingType": "for-sale"}'

🚀 Getting Started (3 Simple Steps)

Step 1: Name your areas

Type the places as Private Property writes them: "Sea Point", "Cape Town", "Western Cape". Leave the field empty to sweep the whole country.

Step 2: Pick the section and narrow it

Choose for sale, to rent, on show, farms or commercial. Add a price band, a bedroom minimum or a parking minimum if you want a shortlist rather than the market.

Step 3: Press Start

Rows land in the dataset as they are found. Open the run report for a summary and one-click copy of every listing link.

That's it! In under a minute, you'll have:

  • Every matching listing as a typed row
  • Asking prices, sizes and room counts ready to sort and chart
  • An export in JSON, CSV or Excel

📥 Input Configuration

FieldTypeRequiredDescription
operationstringNosearch (default) or listing
locationsarrayNoPlace names — suburb, city, region or province. Empty means the whole country
listingTypestringNofor-sale, to-rent, on-show, farms-for-sale, farms-to-rent, commercial-sales, commercial-rentals
propertyTypestringNohouses, apartments, townhouses, land, garden-cottages, or empty for any
maxResultsintegerNoRow budget for the run. Default 100
includeDetailsbooleanNoOpen each listing for the full record. Charged per listing
minPrice / maxPriceintegerNoIn rands; monthly rent on the to-rent side. 0 means no bound
minBedroomsintegerNoAt least this many bedrooms
minBathroomsintegerNoAt least this many bathrooms
minParkingSpacesintegerNoAt least this many parking spaces or garages
searchUrlsarrayNoResults pages to read exactly as given. Overrides the area and filter fields
listingUrlsarrayNoIndividual listing pages. Switches the run to Listing Detail

Example:

{
"operation": "search",
"locations": ["Sea Point"],
"listingType": "for-sale",
"minPrice": 3000000,
"maxPrice": 8000000,
"minBedrooms": 2,
"maxResults": 200
}

Full record for listings you already have:

{
"operation": "listing",
"listingUrls": [
{ "url": "https://www.privateproperty.co.za/for-sale/western-cape/cape-town/atlantic-seaboard/sea-point/T5613080" }
]
}

📤 Output

Results are saved to the Apify dataset with 33 fields. Search rows carry the first group; the full record adds the second.

FieldTypeDescription
referencestringThe portal's listing reference: T… for sale, RR… for rentals
urlstringThe listing page
listingTitlestringe.g. "2 Bedroom Apartment"
priceintegerAsking price in rands, or the monthly rent on the to-rent side
suburb / city / provincestringWhere it is
bedrooms / bathroomsnumberHalves are real; a studio is 0.5
parkingSpacesnumberParking spaces or garages
floorSizeSqm / landSizeSqmnumberFloor area and erf size in square metres
agencyNamestringThe agency holding the mandate
listedPrivatelybooleanListed by the owner rather than an agency
isNew / isPriceReduced / isUnderOffer / isSold / isOnShowbooleanStatus flags
listingDescriptionstringThe listing text (full record)
imageUrlsarrayEvery photo (full record)
listingDate / propertyTypestringWhen it was listed, and how the portal classifies it (full record)
levies / ratesAndTaxesintegerMonthly levies and municipal rates, for-sale listings only (full record)
latitude / longitudenumberMap coordinates, where the portal publishes them (full record)

Example:

{
"reference": "T5613080",
"listingId": 12057791,
"url": "https://www.privateproperty.co.za/for-sale/western-cape/cape-town/atlantic-seaboard/sea-point/T5613080",
"listingType": "for-sale",
"listingTitle": "2 Bedroom Apartment in Sea Point",
"price": 8750000,
"priceText": "R 8 750 000",
"suburb": "Sea Point",
"city": "Cape Town",
"province": "Western Cape",
"streetAddress": "243 Strand beach, 243 High level road",
"bedrooms": 2,
"bathrooms": 2,
"parkingSpaces": 2,
"floorSizeSqm": 74,
"landSizeSqm": 1728,
"propertyType": "Apartment",
"listingDate": "7 Sep 2026",
"levies": 5500,
"ratesAndTaxes": 3000,
"latitude": -33.9159991,
"longitude": 18.3934994,
"agencyName": "SAProperty.com",
"isUnderOffer": false
}

💼 Use Cases & Examples

1. Suburb price tracking

A property analyst wants the movement in asking prices in one suburb, week over week.

Input: the suburb name and a for-sale search Output: every listing with price, erf size, floor size and room counts as numbers Use: run it on a schedule and the change is a subtraction, not a parsing project

2. Buy-to-let and rental yield screening

An investor is comparing gross yield across three suburbs.

Input: the same areas run twice, once for sale and once to rent, with the full record on Output: for-sale rows with levies and rates, rental rows with the monthly asking rent Use: gross and net yield fall out of the two exports side by side

3. Estate agency market share

An agency principal wants to know who is carrying stock in their patch.

Input: a city or region, a price band Output: every listing with the agency holding the mandate, plus the owner-listed ones Use: count listings by agency to see share, and spot the private sellers worth approaching

4. On-show and new-listing monitoring

A buyer's agent wants only what changed this week.

Input: the on-show section for two or three cities Output: the smaller, fresher set of listings with a scheduled show day, each flagged new or price-reduced Use: a weekly shortlist that arrives without anyone refreshing a results page

5. Relocation shortlists

Someone moving to Cape Town wants a filtered list, not a browser full of tabs.

Input: a suburb or region, a price band, a bedroom count, a parking minimum Output: a clean shortlist with a photo, the suburb and, on the full record, map coordinates Use: hand it to a spreadsheet or a map tool and pick

6. Farm and commercial sourcing

A commercial broker wants land and premises rather than homes.

Input: the farms or commercial section, a province, a price ceiling Output: the same row shape, with erf size and asking price Use: the two verticals most residential exports of this portal simply skip

7. Building a national dataset

A data team wants the South African market in one table.

Input: no area at all, a generous row budget, run alongside our Property24 Scraper Output: two exports with the same column names Use: stack them and deduplicate on address rather than reconciling two schemas by hand


🔗 Integration Examples

JavaScript/Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('sian.agency/privateproperty-property-scraper').call({
operation: 'search',
locations: ['Sea Point'],
listingType: 'for-sale',
maxResults: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);

Python

from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('sian.agency/privateproperty-property-scraper').call(
run_input={
'operation': 'search',
'locations': ['Sandton'],
'listingType': 'to-rent',
'maxPrice': 35000,
}
)
for item in client.dataset(run['defaultDatasetId']).iterate_items():
print(item)

cURL

curl -X POST 'https://api.apify.com/v2/acts/sian.agency~privateproperty-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation": "search", "locations": ["Durban"], "listingType": "for-sale"}'

Automation Workflows (N8N / Zapier / Make)

  1. Trigger: a weekly schedule, or a webhook from your own system
  2. HTTP Request: call the Actor's run-sync endpoint
  3. Process: filter the rows on price, suburb or the status flags
  4. Action: write to Sheets or Airtable, or post the new listings to Slack

📊 Performance & Pricing

FREE Tier (Try It Now)

  • 25 listings per run — every field, every section, same quality
  • No credit card required
  • Enough to see the row shape before you commit
  • Unlimited listings per run
  • Pay per listing actually returned — errors and empty searches cost nothing
  • The full record is a separate, optional charge, so a search-only run never pays for it

💰 Priced where the market clears: the same rate per row as our Property24 Scraper, so taking both South African portals costs the same per listing either way.

🔗 View current pricing


❓ Frequently Asked Questions

Q: Do I need to find the portal's area id? A: No. Type the place name and it is matched against the portal's own published area index while the run starts. A name that cannot be matched comes back with the nearest ones actually seen.

Q: How many listings can I get? A: FREE tier: 25 per run. PAID tier: unlimited, capped by the row budget you set.

Q: Does it return agent phone numbers? A: No. The pages this Actor reads carry the agency name and sometimes the agent's name, not a number. That column is not offered rather than shipped empty.

Q: Why are levies and rates empty on my rental rows? A: The portal publishes them on for-sale listings only. The same applies to map coordinates, which appear on roughly half of for-sale listings and far fewer rentals. A null means the portal does not publish it, not that the read failed.

Q: Can I paste a search I built in my browser? A: Yes. Put the results page URL in Search URLs and it runs exactly as given, with whatever filters you set on the site. That overrides the area and filter fields.

Q: What output formats are available? A: JSON, CSV and Excel, exported straight from the Apify dataset.

Q: Does it cover sold prices? A: No. The portal publishes asking prices. What a property actually sold for comes from the deeds office.

Q: Is this legal? A: Yes — only publicly available listing data is extracted. See the legal section below.


🐛 Troubleshooting

"None of those places are areas on Private Property"

  • Use the place name as the portal writes it: a suburb, city, region or province.
  • If a name exists twice, add the parent: "Hibberdene, KZN South Coast".
  • The run log prints the nearest names it did see.

The run returned no listings

  • Widen the price band, or lower the bedroom, bathroom and parking minimums.
  • Some combinations do not exist: garden cottages are a rental category only.
  • Try a larger area; a small suburb genuinely may hold nothing this week.

Fewer rows than I expected

  • Check the row budget in maxResults, and the FREE tier's 25-row cap.
  • The number the run prints first is the portal's own total for that search; if the budget is lower, that is where it stopped.

A pasted search URL was skipped

  • It must be a privateproperty.co.za results page, not a listing page. A listing page belongs in Listing URLs.

Levies, rates or coordinates are empty

  • Turn on the full record — those fields only come from the listing page.
  • Even then they are for-sale only, and coordinates are partial. That is what the portal publishes.

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union, by POPIA in South Africa, and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the legality of web scraping.

Private Property is a trademark of Private Property South Africa (Pty) Ltd. This Actor is not affiliated with, endorsed by, or sponsored by Private Property.


🤝 Support

Join our active support community


Built by SIÁN Agency | More Tools