PropertyGuru / DDProperty Scraper (SG · MY · TH) avatar

PropertyGuru / DDProperty Scraper (SG · MY · TH)

Pricing

from $0.0007 / actor start

Go to Apify Store
PropertyGuru / DDProperty Scraper (SG · MY · TH)

PropertyGuru / DDProperty Scraper (SG · MY · TH)

Scrapes property listings from PropertyGuru Singapore, PropertyGuru Malaysia and DDProperty Thailand — one actor, three SEA markets sharing one platform, 630,000+ listings. Filter by keyword, type, price, bedrooms and size; returns price, beds, baths, size, address, agent, photos and transit info.

Pricing

from $0.0007 / actor start

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Scrapes property listings from PropertyGuru Singapore, PropertyGuru Malaysia and DDProperty Thailand — Southeast Asia's largest property portal group, with over 630,000 listings across the three markets.

One actor, three markets. They run on the same platform, so results share an identical field shape and can be compared directly.

Public data only. No login, no cookies, no browser.

What you get

Two record types share one dataset, told apart by recordType.

PROPERTY — one row per listing

Search rows are already rich (48 fields): price with currency, bedrooms, bathrooms, floor area, full address, property type, agent and agency, photo carousel, listing features, posting date, and transit info (MRT/BTS proximity where the market has it).

Turn on Fetch full listing details for the complete description, full facility list, project data and agent contact — one extra request per listing.

SEARCH_SUMMARY — one row per market

Upstream's own match total, how deep the run paged, the filters you requested, and the platform's own echo of the filters it actually parsed.

Input

FieldWhat it does
MarketsThailand, Singapore, Malaysia — pick any combination
For sale / for rentwhich side of the market
Keyword / locationdistrict or project name: sukhumvit, orchard, mont kiara
Property typeCondo, Apartment, Bungalow, Semi-detached, Land
Min / max pricein each market's own currency (THB / SGD / MYR)
Bedroomsminimum count
Minimum floor areasqm in TH/MY, sqft in SG
Max listings per market0 = unlimited
Fetch full listing detailsoff by default — the search row is already detailed

Example

{
"markets": ["th", "sg", "my"],
"listingType": "sale",
"propertyType": "CONDO",
"minPrice": 1000000,
"bedrooms": 2,
"maxItems": 500
}

The thing this actor protects you from

Property-type codes are market-specific, and an unsupported one is silently ignored. Ask for LAND in Thailand and you get 10,729 plots. Ask for LAND in Singapore and you get all 57,647 listings — no error, no warning, just a search that quietly wasn't filtered.

This actor checks the platform's own echo of what it parsed and tells you:

"filtersRequested": {"property_type_code": "LAND"},
"propertyTypeApplied": false,
"upstreamSearchParams": {"locale": "en", "listingType": "sale", "page": 1}

plus a warning in the log. When the filter does land, the echo proves it:

"upstreamSearchParams": {"propertyTypeGroup": "N", "propertyTypeCode": ["CONDO"],
"minPrice": 1000000, "bedrooms": [2]}
codeThailandSingaporeMalaysia
Condo / Apartment
Bungalow / Semi-detached
Land
Terraced / HDB

Unsupported markets and impossible price ranges are refused before the first request rather than producing a healthy-looking wrong result.

Notes on reliability

  • No bot challenge on search. All three hosts sit behind Cloudflare but serve data cold.
  • Singapore requires a Referer header on paginated URLs (it answers 403 without one), as do Thai detail pages. The actor always sends the right one — you never see this.
  • Runs unattended. No session, no token, nothing to refresh.
  • Failures never vanish. A listing withdrawn mid-crawl degrades that one row (_detailError); every input maps to at least one output row.
  • Residential proxy by default on cloud runs.

Output envelope

Every record carries _input, _source and _scrapedAt. Upstream field names pass through verbatim — no renaming. _source is S1-nextdata-search, or S1-nextdata-search+S2-nextdata-detail once details are attached.

The market you searched is marketQueried (upstream's own fields are left untouched).

See CRAWLING_METHOD.md for the full reverse-engineering trail — the shared-buildId proof, the Referer gate, and the per-market property-type matrix.