Dataspryva

Southeast Asia Property Listings by Country & Bedroom Count

Search PropertyGuru for-sale and for-rent listings across Singapore, Malaysia, Thailand and Indonesia by property type, bedrooms and price, with agent details, area and photos per listing.

Input schema

Input fields, types, required flags, descriptions, defaults, and prefills come from the published definition. Prefill examples are distinct from defaults.

FieldTypeRequiredDescription
modestringrequiredSearch listings by filters, or scrape specific search, listing and project URLs.
countrystringoptionalMarket to search (mode=search). Singapore and Malaysia use PropertyGuru; Thailand uses DDProperty.
listingTypestringoptionalSale or rental listings (mode=search).
Show all input fields
FieldTypeRequiredDescription
modestringrequiredSearch listings by filters, or scrape specific search, listing and project URLs.
countrystringoptionalMarket to search (mode=search). Singapore and Malaysia use PropertyGuru; Thailand uses DDProperty.
listingTypestringoptionalSale or rental listings (mode=search).
searchQuerystringoptionalFree-text area, project, MRT station or keyword, for example 'Thomson', 'Mont Kiara' or 'Sukhumvit' (mode=search).
propertyTypestringoptionalFilter by property type (mode=search). Types a market does not have are ignored with a status note.
districtstringoptionalFilter by Singapore district D01-D28 (mode=search). Ignored for Malaysia and Thailand.
minPriceintegeroptionalMinimum asking price in the market's local currency (SGD, MYR or THB).
maxPriceintegeroptionalMaximum asking price in the market's local currency (SGD, MYR or THB).
bedroomsarrayoptionalReturn any of these exact bedroom counts. 0 means studio. Leave empty for all.
bathroomsarrayoptionalReturn any of these exact bathroom counts. Leave empty for all.
minSizeintegeroptionalMinimum floor area in square feet for Singapore and Malaysia, square metres for Thailand.
maxSizeintegeroptionalMaximum floor area in square feet for Singapore and Malaysia, square metres for Thailand.
tenurestringoptionalFreehold or leasehold (mode=search, sale only).
furnishingstringoptionalFurnishing level of the property (mode=search).
floorLevelstringoptionalFloor level of the unit (mode=search).
availabilitystringoptionalMove-in availability (mode=search, rent only).
maxDistanceToMrtstringoptionalMaximum walking distance to an MRT/LRT station (Singapore and Thailand).
sortstringoptionalOrder of the results (mode=search).
maxItemsintegeroptionalStop after this many listings.
maxPagesintegeroptionalStop after this many search-result pages. The site's own last page also stops the run.
includeDetailsbooleanoptionalOpen each listing page for description, agent mobile, coordinates, transit, schools, amenities and media. One extra request per listing.
startUrlsarrayoptionalPaste PropertyGuru SG/MY or DDProperty TH search-result, listing or project URLs (mode=byUrl).

Download the published input schema

View complete JSON
{
  "description": "Search Singapore, Malaysia and Thailand property listings, or paste search, listing and project URLs. Filters, detail enrichment and listing limits are controlled here.",
  "properties": {
    "availability": {
      "default": "any",
      "description": "Move-in availability (mode=search, rent only).",
      "editor": "select",
      "enum": [
        "any",
        "immediate",
        "within1Month",
        "oneToTwoMonths",
        "twoToThreeMonths",
        "afterThreeMonths"
      ],
      "enumTitles": [
        "Any availability",
        "Immediately",
        "Within 1 month",
        "1-2 months",
        "2-3 months",
        "After 3 months"
      ],
      "prefill": "any",
      "title": "Available from",
      "type": "string"
    },
    "bathrooms": {
      "default": [],
      "description": "Return any of these exact bathroom counts. Leave empty for all.",
      "editor": "select",
      "items": {
        "enum": [
          "1",
          "2",
          "3",
          "4",
          "5"
        ],
        "enumTitles": [
          "1 bathroom",
          "2 bathrooms",
          "3 bathrooms",
          "4 bathrooms",
          "5+ bathrooms"
        ],
        "type": "string"
      },
      "prefill": [],
      "title": "Bathrooms",
      "type": "array"
    },
    "bedrooms": {
      "default": [],
      "description": "Return any of these exact bedroom counts. 0 means studio. Leave empty for all.",
      "editor": "select",
      "items": {
        "enum": [
          "0",
          "1",
          "2",
          "3",
          "4",
          "5"
        ],
        "enumTitles": [
          "Studio",
          "1 bedroom",
          "2 bedrooms",
          "3 bedrooms",
          "4 bedrooms",
          "5+ bedrooms"
        ],
        "type": "string"
      },
      "prefill": [],
      "title": "Bedrooms",
      "type": "array"
    },
    "country": {
      "default": "SG",
      "description": "Market to search (mode=search). Singapore and Malaysia use PropertyGuru; Thailand uses DDProperty.",
      "editor": "select",
      "enum": [
        "SG",
        "MY",
        "TH"
      ],
      "enumTitles": [
        "Singapore (PropertyGuru)",
        "Malaysia (PropertyGuru)",
        "Thailand (DDProperty)"
      ],
      "prefill": "SG",
      "title": "Country",
      "type": "string"
    },
    "district": {
      "default": "any",
      "description": "Filter by Singapore district D01-D28 (mode=search). Ignored for Malaysia and Thailand.",
      "editor": "select",
      "enum": [
        "any",
        "D01",
        "D02",
        "D03",
        "D04",
        "D05",
        "D06",
        "D07",
        "D08",
        "D09",
        "D10",
        "D11",
        "D12",
        "D13",
        "D14",
        "D15",
        "D16",
        "D17",
        "D18",
        "D19",
        "D20",
        "D21",
        "D22",
        "D23",
        "D24",
        "D25",
        "D26",
        "D27",
        "D28"
      ],
      "enumTitles": [
        "Any district",
        "D01 Boat Quay / Raffles Place / Marina",
        "D02 Chinatown / Tanjong Pagar",
        "D03 Alexandra / Commonwealth",
        "D04 Harbourfront / Telok Blangah",
        "D05 Buona Vista / West Coast / Clementi",
        "D06 City Hall / Clarke Quay",
        "D07 Beach Road / Bugis / Rochor",
        "D08 Farrer Park / Serangoon Road",
        "D09 Orchard / River Valley",
        "D10 Tanglin / Holland / Bukit Timah",
        "D11 Newton / Novena",
        "D12 Balestier / Toa Payoh",
        "D13 Macpherson / Potong Pasir",
        "D14 Eunos / Geylang / Paya Lebar",
        "D15 East Coast / Marine Parade",
        "D16 Bedok / Upper East Coast",
        "D17 Changi Airport / Changi Village",
        "D18 Pasir Ris / Tampines",
        "D19 Hougang / Punggol / Sengkang",
        "D20 Ang Mo Kio / Bishan / Thomson",
        "D21 Clementi Park / Upper Bukit Timah",
        "D22 Boon Lay / Jurong / Tuas",
        "D23 Dairy Farm / Bukit Panjang / Choa Chu Kang",
        "D24 Lim Chu Kang / Tengah",
        "D25 Admiralty / Woodlands",
        "D26 Mandai / Upper Thomson",
        "D27 Sembawang / Yishun",
        "D28 Seletar / Yio Chu Kang"
      ],
      "prefill": "any",
      "title": "Singapore district",
      "type": "string"
    },
    "floorLevel": {
      "default": "any",
      "description": "Floor level of the unit (mode=search).",
      "editor": "select",
      "enum": [
        "any",
        "ground",
        "low",
        "mid",
        "high",
        "penthouse"
      ],
      "enumTitles": [
        "Any floor",
        "Ground floor",
        "Low floor",
        "Mid floor",
        "High floor",
        "Penthouse"
      ],
      "prefill": "any",
      "title": "Floor level",
      "type": "string"
    },
    "furnishing": {
      "default": "any",
      "description": "Furnishing level of the property (mode=search).",
      "editor": "select",
      "enum": [
        "any",
        "unfurnished",
        "partially",
        "fully"
      ],
      "enumTitles": [
        "Any furnishing",
        "Unfurnished",
        "Partially furnished",
        "Fully furnished"
      ],
      "prefill": "any",
      "title": "Furnishing",
      "type": "string"
    },
    "includeDetails": {
      "default": true,
      "description": "Open each listing page for description, agent mobile, coordinates, transit, schools, amenities and media. One extra request per listing.",
      "prefill": false,
      "title": "Include detail enrichment",
      "type": "boolean"
    },
    "listingType": {
      "default": "sale",
      "description": "Sale or rental listings (mode=search).",
      "editor": "select",
      "enum": [
        "sale",
        "rent"
      ],
      "enumTitles": [
        "For sale",
        "For rent"
      ],
      "prefill": "sale",
      "title": "Listing type",
      "type": "string"
    },
    "maxDistanceToMrt": {
      "default": "any",
      "description": "Maximum walking distance to an MRT/LRT station (Singapore and Thailand).",
      "editor": "select",
      "enum": [
        "any",
        "250m",
        "500m",
        "750m",
        "1km",
        "1.5km"
      ],
      "enumTitles": [
        "Any distance",
        "Under 250 m",
        "Under 500 m",
        "Under 750 m",
        "Under 1 km",
        "Under 1.5 km"
      ],
      "prefill": "any",
      "title": "Maximum distance to MRT",
      "type": "string"
    },
    "maxItems": {
      "default": 100,
      "description": "Stop after this many listings.",
      "maximum": 100000,
      "minimum": 1,
      "prefill": 2,
      "title": "Maximum listings",
      "type": "integer"
    },
    "maxPages": {
      "default": 50,
      "description": "Stop after this many search-result pages. The site's own last page also stops the run.",
      "maximum": 10000,
      "minimum": 1,
      "prefill": 1,
      "title": "Maximum search pages",
      "type": "integer"
    },
    "maxPrice": {
      "description": "Maximum asking price in the market's local currency (SGD, MYR or THB).",
      "maximum": 1000000000,
      "minimum": 0,
      "title": "Maximum price",
      "type": "integer"
    },
    "maxSize": {
      "description": "Maximum floor area in square feet for Singapore and Malaysia, square metres for Thailand.",
      "maximum": 1000000,
      "minimum": 0,
      "title": "Maximum floor area",
      "type": "integer"
    },
    "minPrice": {
      "description": "Minimum asking price in the market's local currency (SGD, MYR or THB).",
      "maximum": 1000000000,
      "minimum": 0,
      "title": "Minimum price",
      "type": "integer"
    },
    "minSize": {
      "description": "Minimum floor area in square feet for Singapore and Malaysia, square metres for Thailand.",
      "maximum": 1000000,
      "minimum": 0,
      "title": "Minimum floor area",
      "type": "integer"
    },
    "mode": {
      "default": "search",
      "description": "Search listings by filters, or scrape specific search, listing and project URLs.",
      "editor": "select",
      "enum": [
        "search",
        "byUrl"
      ],
      "enumTitles": [
        "Search listings by filters",
        "Scrape these URLs"
      ],
      "prefill": "search",
      "title": "Mode",
      "type": "string"
    },
    "propertyType": {
      "default": "any",
      "description": "Filter by property type (mode=search). Types a market does not have are ignored with a status note.",
      "editor": "select",
      "enum": [
        "any",
        "condo",
        "apartment",
        "hdb",
        "landed",
        "bungalow",
        "semiDetached",
        "terrace",
        "land",
        "commercial"
      ],
      "enumTitles": [
        "Any type",
        "Condominium",
        "Apartment",
        "HDB flat (Singapore)",
        "Landed house",
        "Bungalow",
        "Semi-detached house",
        "Terrace house",
        "Land",
        "Commercial"
      ],
      "prefill": "any",
      "title": "Property type",
      "type": "string"
    },
    "searchQuery": {
      "description": "Free-text area, project, MRT station or keyword, for example 'Thomson', 'Mont Kiara' or 'Sukhumvit' (mode=search).",
      "editor": "textfield",
      "title": "Keyword or area",
      "type": "string"
    },
    "sort": {
      "default": "recommended",
      "description": "Order of the results (mode=search).",
      "editor": "select",
      "enum": [
        "recommended",
        "newest",
        "priceAsc",
        "priceDesc",
        "psfAsc",
        "psfDesc",
        "sizeAsc",
        "sizeDesc"
      ],
      "enumTitles": [
        "Recommended",
        "Newest first",
        "Price: low to high",
        "Price: high to low",
        "Price per area: low to high",
        "Price per area: high to low",
        "Size: low to high",
        "Size: high to low"
      ],
      "prefill": "recommended",
      "title": "Sort order",
      "type": "string"
    },
    "startUrls": {
      "default": [],
      "description": "Paste PropertyGuru SG/MY or DDProperty TH search-result, listing or project URLs (mode=byUrl).",
      "editor": "requestListSources",
      "items": {
        "properties": {
          "url": {
            "description": "PropertyGuru or DDProperty URL.",
            "title": "URL",
            "type": "string"
          }
        },
        "type": "object"
      },
      "prefill": [],
      "title": "Search, listing or project URLs",
      "type": "array"
    },
    "tenure": {
      "default": "any",
      "description": "Freehold or leasehold (mode=search, sale only).",
      "editor": "select",
      "enum": [
        "any",
        "freehold",
        "leasehold"
      ],
      "enumTitles": [
        "Any tenure",
        "Freehold",
        "Leasehold"
      ],
      "prefill": "any",
      "title": "Tenure",
      "type": "string"
    }
  },
  "required": [
    "mode"
  ],
  "schemaVersion": 1,
  "title": "PropertyGuru & DDProperty Scraper Input",
  "type": "object"
}

Output schema

Published result links and storage locations. This schema is not an exhaustive contract for every field in a dataset record.

FieldTypeRequiredDescription
listingsstringoptionalDataset containing all scraped property listings, including enriched detail fields when enabled.

Download the published output schema

View complete JSON
{
  "actorOutputSchemaVersion": 1,
  "description": "Property listings from Singapore, Malaysia and Thailand with prices, property details, agent or developer contact, transit, schools, project unit types and media.",
  "properties": {
    "listings": {
      "description": "Dataset containing all scraped property listings, including enriched detail fields when enabled.",
      "template": "{{links.apiDefaultDatasetUrl}}/items",
      "title": "Property listings",
      "type": "string"
    }
  },
  "title": "PropertyGuru & DDProperty Listings Scraper Output"
}

Dataset schema

Published dataset views and any declared field definitions. A view can select only a subset of the returned record fields.

Download the published dataset schema

View complete JSON
{
  "actorSpecification": 1,
  "views": {
    "overview": {
      "display": {
        "component": "table",
        "properties": {}
      },
      "title": "Listings",
      "transformation": {
        "fields": [
          "listingId",
          "title",
          "price",
          "priceText",
          "currency",
          "propertyType",
          "bedrooms",
          "bathrooms",
          "floorArea",
          "floorAreaUnit",
          "address",
          "district",
          "country",
          "agentName",
          "agentMobile",
          "projectName",
          "listingUrl"
        ]
      }
    }
  }
}

Key-value schema

Published key-value store definitions, when provided by this build.

This definition is not present in the default published build. See the published README for available documentation.

Published README

Read the full published documentation

PropertyGuru & DDProperty Listings Scraper

Collect property listings from Singapore and Malaysia on PropertyGuru and from Thailand on DDProperty. Search by keyword, property type, district, price, bedrooms, bathrooms, size, tenure, furnishing, floor level, availability, MRT distance and sort order, or paste search, listing and project URLs. Every record keeps the source's price label, area unit and contact details instead of flattening them.

What it does

  • Three live markets — Singapore (propertyguru.com.sg), Malaysia (propertyguru.com.my) and Thailand (ddproperty.com/en) with local currencies and area units.
  • Filter-first search — keyword or area, sale or rent, property type, Singapore district D01-D28, price, exact bedroom and bathroom chips, floor size, tenure, furnishing, floor level, move-in availability, MRT distance and eight sort orders.
  • Paste any URL — search-result URLs paginate, listing URLs return one detailed record, project URLs include the project's unit types. The market is inferred from the host.
  • Optional detail enrichment — opens each listing page for the description, agent mobile, licence, rating, agency, coordinates, nearby transit and schools, amenities, facilities, floor plans, videos and virtual tours.
  • Project and new-launch aware — reads unit-level prices, bedroom and bathroom counts, floor-area ranges and floor plans; development contact replaces agent contact where the source publishes a developer instead of an agent.
  • Deep pagination with deduplication — follows the site's own page count until your item or page limit, and removes repeated promoted cards.

Output per listing

Group Fields
Identity recordType, listingId, title, listingUrl, transactionType, country, sourceDomain, sourceUrl, sourcePage, statusCode, listerType, accountType
Price price, priceText, priceType, priceMin, priceMax, currency, pricePerSqft, pricePerSqm, pricePerArea, pricePerAreaUnit
Property propertyType, propertyTypeCode, propertyTypeGroup, bedrooms, bathrooms, floorArea, floorAreaUnit, floorAreaSqft, floorAreaSqm, landArea, landAreaUnit, landAreaSqft, landAreaSqm, tenure, tenureCode, completionYear, furnishing, floorLevel, availability, isNewProject, isVerified, isOfficialListing, isDeveloperListing
Project projectName, projectId, projectUrl, developer, developerUrl, developerWhatsapp, unitTypes
Location address, fullAddress, shortAddress, streetName, district, districtCode, region, regionCode, postalCode, latitude, longitude
Nearby nearbyMrt, nearestTransit, nearbySchools
Contact agentId, agentName, agentProfileUrl, agentLicense, agentVerified, agentJobTitle, agentMobile, agentRating, agentReviewCount, agencyName, agencyId
Media imageUrls, imageCount, thumbnailUrl, floorPlanUrls, videoUrls, virtualTourUrls
Detail headline, description, amenities, facilities, highlights
Dates postedOn, postedOnUnix, recency, scrapedAt

Empty fields are omitted from each record instead of being returned as null. area is kept as an alias of floorArea for compatibility with older datasets.

Input

Field Type Default Description
mode select, required search Search by filters, or scrape pasted URLs.
country select SG SG, MY or TH (mode=search).
listingType select sale Sale or rent.
searchQuery text – Area, project, station or keyword.
propertyType select any Condo, apartment, HDB, landed, bungalow, semi-detached, terrace, land or commercial.
district select any Singapore district D01-D28.
minPrice / maxPrice integer – Price range in SGD, MYR or THB.
bedrooms multi-select – Studio (0) through 5+.
bathrooms multi-select – 1 through 5+.
minSize / maxSize integer – Floor area in sqft (SG/MY) or sqm (TH).
tenure select any Freehold or leasehold (sale only).
furnishing select any Unfurnished, partially or fully furnished.
floorLevel select any Ground, low, mid, high or penthouse.
availability select any Immediate to after three months (rent only).
maxDistanceToMrt select any 250 m to 1.5 km (SG/TH).
sort select recommended Newest, price, price per area or size.
maxItems integer 100 Stop after this many listings.
maxPages integer 50 Stop after this many search pages.
includeDetails boolean true Enrich each listing with detail-page fields.
startUrls URL list – Search, listing or project URLs (mode=byUrl).

Example: two-bedroom condos in Singapore District 20

{
  "mode": "search",
  "country": "SG",
  "listingType": "sale",
  "propertyType": "condo",
  "district": "D20",
  "bedrooms": ["2"],
  "maxItems": 20,
  "includeDetails": true
}

Example: rentals in Kuala Lumpur

{
  "mode": "search",
  "country": "MY",
  "listingType": "rent",
  "searchQuery": "Mont Kiara",
  "minPrice": 2000,
  "maxPrice": 6000,
  "furnishing": "fully",
  "maxItems": 30
}

Example: Bangkok condos near the MRT

{
  "mode": "search",
  "country": "TH",
  "listingType": "sale",
  "propertyType": "condo",
  "searchQuery": "Sukhumvit",
  "maxDistanceToMrt": "500m",
  "sort": "priceAsc",
  "maxItems": 20
}

Example: paste a search page and a project page

{
  "mode": "byUrl",
  "startUrls": [
    { "url": "https://www.propertyguru.com.sg/property-for-sale?district_code=D09" },
    { "url": "https://www.propertyguru.com.my/property-listing/project/enlace-suite-ii-for-sale-by-amona-development-sdn-bhd-501086101" }
  ],
  "maxItems": 50
}

Use cases

  • Market comparison — compare asking prices and price per area across Singapore, Malaysia and Thailand in one dataset.
  • Lead research — collect the public agent name, mobile, licence and agency for non-project listings, or the developer contact for project listings.
  • Investment screening — combine district, price, size, tenure and MRT filters to shortlist candidates.
  • New-launch tracking — follow project pages with unit-level prices, layouts and floor plans.
  • Listing audits — re-scrape a saved set of URLs to spot price or availability changes.

Notes and limitations

  • Indonesia is not available. The PropertyGuru Indonesia marketplace closed on 2023-11-30, so the actor reports that closure instead of returning empty data.
  • Thailand uses DDProperty's English site. That is the live Thai marketplace for this listing data; the old PropertyGuru Thailand domain no longer serves listings.
  • Agent email is not published. The actor returns the public agent mobile, licence, profile and rating where the source shows them; it does not invent an email address.
  • Project pricing is a range or a "from" price. When the source only gives unit ranges, the record carries priceMin and priceMax plus the source label rather than a made-up single price.
  • Short links are not supported. Paste canonical search, listing or project URLs.
  • Pasted detail pages can be protected. If a Thai listing or project page is blocked but the same id still appears in search, the record is rebuilt from search-card data. Detail-only fields such as the description, amenities and coordinates are then omitted, and the run status reports how many records used this fallback.

FAQ

Is this affiliated with PropertyGuru or DDProperty? No. This is an independent, third-party actor that reads publicly visible listing pages. It is not operated by or affiliated with either marketplace.

Do I need an account, cookie or API key? No. The actor works without credentials or a proxy setup.

Why is the agent mobile missing on some records? Mobile numbers are only published on some listing pages. Project and new-launch listings usually show a developer contact instead, so those records carry developer fields rather than agent fields. Email addresses are not published at all.

Why does one listing have price and another only priceMin/priceMax? A fixed asking price becomes price; a range or a project with several unit prices becomes priceMin/priceMax. priceText always keeps the label shown by the source, including "Price on ask" or "Starting From".

Why is floorAreaUnit sometimes sqft and sometimes sqm? Singapore and Malaysia publish square feet; Thailand publishes square metres. Both floorAreaSqft and floorAreaSqm are provided so records from different markets can be compared directly.

What happens when a filter is not available in a market? The actor ignores that filter and says so in the run's status message. Singapore districts, for example, do not apply to Malaysia or Thailand.

How many requests does a run make? One request per search page. With detail enrichment on, it also makes one request per emitted listing. Turning enrichment off gives the fastest and smallest run.

Can I scrape more than a few thousand listings? Yes. Pagination follows the site's own last page and stops at maxItems or maxPages; duplicate promoted cards are removed. Very large runs take longer because pages are read at a polite pace.

Are images and media links usable? Yes. Image, floor-plan, video and virtual-tour URLs are absolute links to the source's public media host.

Who is responsible for how the contact data is used? Agent and developer contact details are personal or business data. You are responsible for using them lawfully in your jurisdiction and for respecting the marketplace's terms.

Python quickstart

Use a schema-derived input and the Python standard library to start a run. An Apify account and token are required for execution.

Open the step-by-step Python guide →

Source build nYkOHZZmevFgyM1O5. Documentation is regenerated from the default published build; private drafts are not included.