PropertyGuru SG Scraper - Property Listings, Prices & Agents
Pricing
from $0.80 / 1,000 results
PropertyGuru SG Scraper - Property Listings, Prices & Agents
From $0.80/1K. Scrape PropertyGuru.com.sg sale and rental listings with 30+ structured fields, including price, PSF, floor area, tenure, nearby MRT stations, property details, agent information and GPS coordinates. Fast and reliable at scale.
Pricing
from $0.80 / 1,000 results
Rating
3.3
(3)
Developer
Abot API
Maintained by CommunityActor stats
2
Bookmarked
86
Total users
13
Monthly active users
6 days ago
Last modified
Categories
Share
PropertyGuru Singapore Scraper: Sale & Rent Listings with Price, Location and Agent Data
PropertyGuru Singapore Scraper turns PropertyGuru into a clean structured data feed for the Singapore property market. Get sale and rent listings for condos, HDB flats and landed houses with 60+ fields including price, PSF, floor area, tenure, GPS coordinates, nearest MRT, agent and agency details, project facts and nearby schools. Build a search from filters or paste a PropertyGuru search URL, then export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Two ways to build a search. Pick filters (district, property type, price, bedrooms) or paste a PropertyGuru search URL you already refined in your browser. URL mode ignores the filter fields entirely.
- 60+ structured fields per listing. Price, PSF, floor area, tenure, GPS coordinates, nearest MRT stations, agent and agency details, project facts and nearby schools.
- Detail-page enrichment on demand. Switch it on for coordinates, description, project name, TOP year, total units, facilities, floor plans and nearby schools, or switch it off for a lighter search-only run.
- Sale and rent, every residential type. Condo, HDB flat and landed house, both listing types.
- Project-aware. Once a condo project's shared details are captured from one unit, later units in the same project can fall back to them if their own detail page fails to load, so project facts stay populated even when some detail pages fail to load.
- Built for schedules. Incremental mode returns only new, updated and reappeared listings on repeat runs, and Resume continues one interrupted crawl without re-collecting or re-billing what you already have.
- Clear pass or fail. A run that cannot reach the site stops with a clear message instead of quietly returning an empty dataset.
Use Cases
- Real estate agents and agencies: build a live comparison feed of competing listings by district or project for pricing and marketing.
- Property investors and analysts: track price, PSF and tenure across districts and condo projects over time.
- Rental market research: monitor asking rents, availability and price positioning for a district or project.
- Proptech and listing-aggregator products: feed structured Singapore property data into your own search or valuation tool.
- Lead generation: collect agent and agency contact details attached to active listings in a target area.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
id | 25100001 |
title | "The Sample Residences" |
address / short_address | "1 Sample Road, Singapore 238001" / "Orchard / River Valley, Central (D09-10)" |
listing_type | "sale" (also "rent") |
property_type | "Condo" (also "HDB", "Landed") |
price / price_formatted | 2800000 / "S$ 2,800,000" |
price_psf / price_label | "S$ 2,450 psf" / "Negotiable" |
bedrooms / bathrooms | 3 / 2 |
floor_area / land_area | 1140 / null |
tenure | "Freehold" (also "Leasehold") |
district / district_code | "Orchard" / "D09" |
nearby_mrt | "Orchard MRT" |
latitude / longitude | 1.3039 / 103.8318 |
agent_name / agency_name | "Agent Name" / "Sample Realty Pte Ltd" |
is_verified_listing / is_official_listing | true / false |
developer / is_developer_listing | "Sample Developments Pte Ltd" / false |
project_name / top_year / total_units | "The Sample Residences" / 2019 / 250 |
facilities | ["Swimming Pool", "Gym", "BBQ Pits", "24-hour Security"] |
nearby_schools | list of nearby schools with distance and walking time |
images / image_count | list of image URLs / 18 |
posted_date / recency | "3 days ago" / "Listed 3 days ago" |
Detail-page enrichment also adds the full property description, headline, unit floor and unit features, floor plans, virtual tour link and video count, project description and status, tenure detail, reference number and postal code. Agent records also carry license number, verification status, job title and mobile number. Incremental mode runs add changeType, changedFields, firstSeenAt and lastSeenAt.
How to Use
- Pick a mode: Search (build a query from filters) or URL (paste one or more PropertyGuru search URLs already refined in your browser).
- In Search mode, set listing type, property type, location (free-text search or a district code) and any price or bedroom filters. In URL mode, paste your URLs instead; the filter fields are ignored.
- Turn on Fetch Detail Pages for coordinates, description, project facts and nearby schools, and set Max Properties and Max Pages to control run size and cost.
- Click Start. Download the dataset as JSON, CSV or Excel, or read it through the API.
Condos for sale in Orchard:
{"mode": "search","listing_type": "sale","property_type": "condo","search": "Orchard","max_properties": 20}
3-bedroom HDB flats for rent in a district, under a price cap:
{"mode": "search","listing_type": "rent","property_type": "hdb","district": "D19","bedrooms": 3,"max_price": 4000}
Paste a refined search URL:
{"mode": "url","urls": ["https://www.propertyguru.com.sg/property-for-sale?market=residential&property_type=N"],"max_properties": 50}
Landed houses, cheapest first, search-only (no detail pages):
{"mode": "search","listing_type": "sale","property_type": "landed","sort": "price","sort_order": "asc","enable_detail_pages": false}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/propertyguru-sg-scraper").call(run_input={"mode": "search","listing_type": "sale","property_type": "condo","search": "Orchard",})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["title"], listing["price_formatted"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/propertyguru-sg-scraper').call({mode: 'search',listing_type: 'sale',property_type: 'condo',search: 'Orchard',});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
Two distinct workflows, both under the Resume & recurring updates input section:
- Resume (
resumeFromRunId) continues one specific interrupted crawl. Paste the run or dataset ID from the earlier run and this run skips every listing already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for scheduling the same search or URL setup repeatedly, for example daily. The actor remembers what it saw last time (keyed by your filters and URLs, or your ownstateKey) and classifies every listing asNEW,UPDATED,UNCHANGED,REAPPEAREDorEXPIRED. OnlyNEW,UPDATEDandREAPPEAREDare returned by default; turn onemitUnchangedoremitExpiredto also get (and pay for) those rows.EXPIREDrows are only produced once a run reaches the natural end of the tracked search, not whenmax_propertiesormax_pagescut it short.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify β Settings β Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (build a query from the filters below) or url (use the URLs you provide). |
urls | array | (none) | PropertyGuru search or listing URLs (url mode). Ignored in search mode. |
listing_type | string | sale | sale or rent. Search mode only. |
property_type | string | (none) | condo, hdb, or landed. Search mode only. |
search | string | (none) | Free-text location search, e.g. "Orchard", "Tampines". Use this or district, not both. |
district | string | (none) | Singapore district code, D01 to D28. Use this or search, not both. |
min_price | integer | (none) | Minimum price in Singapore Dollars. |
max_price | integer | (none) | Maximum price in Singapore Dollars. |
bedrooms | integer | (none) | Number of bedrooms (0 = Studio). |
sort | string | date | Sort results by date, price, or psf. |
sort_order | string | desc | asc or desc. |
enable_detail_pages | boolean | true | Fetch each listing's detail page for coordinates, full description, project name, TOP year, total units, facilities, floor plans, nearby schools and virtual tours. Applies in both modes. |
max_properties | integer | 10 | Maximum number of properties to scrape (0 = unlimited). |
max_pages | integer | 20 | Maximum number of search result pages to scrape (20 listings per page). |
proxy | object | Apify Residential, Singapore | Connection settings. PropertyGuru is restricted to Singapore IP addresses. |
session_ttl_seconds | integer | 600 | How often the scraper refreshes its connection state. Lower is more conservative; higher runs faster with slightly higher risk of a mid-run interruption. |
reuse_project_cache | boolean | true | Cache project-level fields (project name, TOP year, total units, facilities, nearby schools, coordinates, developer, tenure) from the first listing in a condo project and reuse them as a fallback if a later same-project listing's detail page fails to load. Per-listing fields such as price_label and description are always fetched individually regardless. |
dataset_name | string | (none) | Custom dataset name (leave empty for the default dataset). |
clear_dataset | boolean | false | Clear the dataset before scraping. |
detail_concurrency | integer | 1 | Number of parallel detail-page fetches. Hidden from the input form; still accepted via the API so existing saved inputs and schedules keep working. |
resumeFromRunId | string | (none) | Continue one interrupted run without re-collecting or re-billing listings already gathered there. |
incrementalMode | boolean | false | Track this same search or URL setup run-to-run and return only new, updated and reappeared listings. |
stateKey | string | (none) | Name or share an incremental-mode monitoring campaign. Left empty, a key is derived automatically from your search, filters, URLs and detail-page setting. |
emitUnchanged | boolean | false | Incremental mode only: also return (and bill) listings unchanged since the last run. |
emitExpired | boolean | false | Incremental mode only: also return (and bill) listings no longer found, once a run fully scans the tracked search. |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"id": 25100001,"title": "The Sample Residences","address": "1 Sample Road, Singapore 238001","short_address": "Orchard / River Valley, Central (D09-10)","url": "https://www.propertyguru.com.sg/listing/for-sale-the-sample-residences-25100001","listing_type": "sale","property_type": "Condo","property_type_text": "Condominium","price": 2800000,"price_formatted": "S$ 2,800,000","currency": "SGD","price_psf": "S$ 2,450 psf","price_label": "Negotiable","bedrooms": 3,"bathrooms": 2,"floor_area": 1140,"tenure": "Freehold","developer": "Sample Developments Pte Ltd","is_developer_listing": false,"is_verified_listing": true,"district": "Orchard","district_code": "D09","region": "Central Region","nearby_mrt": "Orchard MRT","latitude": 1.3039,"longitude": 103.8318,"location_source": "detail_page","postal_code": "238001","agent_name": "Agent Name","agent_license": "R012345A","agency_name": "Sample Realty Pte Ltd","account_type_code": "CORPORATE","project_name": "The Sample Residences","top_year": 2019,"total_units": 250,"facilities": ["Swimming Pool", "Gym", "BBQ Pits", "24-hour Security"],"nearby_schools": [{ "name": "Sample Primary School", "distance_km": 0.6, "walking_mins": 8, "subcategory": "Primary" }],"posted_date": "3 days ago","image_count": 18}
Plan Requirement
This actor needs proxy access to reach propertyguru.com.sg, which is restricted to Singapore IP addresses. A Residential proxy group with the country set to Singapore is applied automatically by default; connection rotation is handled automatically. If the account running the actor cannot reach the site through the requested connection, the actor automatically falls back to a slower compatibility path that keeps the run completing but disables detail-page enrichment. Full-speed runs with detail-page enrichment need working residential proxy access on the account.
FAQ
How much does it cost?
You pay per listing returned, with optional detail-page enrichment billed only when it runs. The Pricing tab shows the current rates. Use Max Properties and Max Pages to cap the size, and cost, of any run.
Is it legal to scrape PropertyGuru?
This actor collects only publicly available property listing data. You are responsible for how you use it: follow PropertyGuru's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing photos and agent details may carry their own rights and privacy considerations.
What is the difference between Resume and Incremental mode?
They serve different purposes. Resume (resumeFromRunId) continues one specific interrupted run so you don't re-collect or re-pay for listings it already gathered. Incremental mode (incrementalMode) is for scheduling the same search again and again, for example daily, and getting back only the listings that are new, changed, or reappeared since the last run. Use Resume after an interrupted run; use Incremental mode for ongoing monitoring.
Why did my run fail instead of returning an empty dataset?
The run stops with a clear error only when it cannot proceed at all: no connection could be established, access to the site was lost and could not be restored after retries, url mode was chosen with no URLs, an invalid resumeFromRunId was supplied, or resumeFromRunId was combined with Incremental mode for a search that already has saved state (use a different stateKey instead). If the run completes but your search simply matched zero listings, or Incremental mode finds nothing new or changed since the last run, that is a normal successful run with an empty (or smaller) dataset, not a failure.
Can I track only new or updated listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared listings, and unchanged ones are not billed unless you turn on emitUnchanged.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
π Want more PropertyGuru data?
Pair this actor with these related scrapers from the same team:
| π PropertyGuru MY From $1/1K. Fast, reliable scraper for propertyguru.com.my. Extract sale and rent... | π CommercialGuru SG Property Listings & Agent Contacts Scraper Scrape commercialguru.com.sg Singapore listings at scale. Extract prices, PSF, floor... |
| π DDProperty TH From $1/1K. Extract property listings from ddproperty.com Thailand at scale. Get... | π iProperty MY Scraper Scrape property listings from iProperty.com.my for sale or rent: price, PSF, bedrooms... |
| π Jitty UK AI Property Scraper Scrape residential property listings from jitty.com, extract properties across the UK... | π Rightmove From $1/1K. Fast, reliable Rightmove.co.uk scraper for sale, rent, and sold-price... |
π Browse all abotapi scrapers
π¬ Support & custom scrapers
- π Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- π οΈ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- β Enjoying it? A quick review on the actor page helps other users find it.