# PropertyGuru Scraper - Singapore Property & Agent Leads (`scrapesage/propertyguru-scraper`) Actor

Scrape PropertyGuru Singapore for-sale & rental listings: prices, PSF, beds/baths, floor area, tenure, build year, district, MRT, photos, plus agent & agency leads with phone numbers. Filter by keyword, price and bedrooms, enrich with descriptions, facilities and geo, and monitor only-new listings.

- **URL**: https://apify.com/scrapesage/propertyguru-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 14 total users, 8 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 property listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## PropertyGuru Scraper — Singapore Property Listings, Prices & Agent Leads

Extract **complete PropertyGuru Singapore data** — for-sale and rental listings with **real asking prices, PSF, bedrooms/bathrooms, floor area, tenure, build year, district, MRT proximity and photos** — plus the **agent and agency behind every listing**, with **phone numbers** when you enrich. Filter by keyword, price and bedrooms, capture full descriptions, condo facilities, geo and price history, and use **monitor mode** to pull only *new* listings on a schedule.

PropertyGuru is Singapore's **#1 property portal** (the widest inventory of condos, HDB resale, landed homes and new launches). This actor reads PropertyGuru's own server-rendered data directly — no login, no API key, no browser — and ships the **richest, most reliable dataset in the category**.

### Why this PropertyGuru scraper?

Most property scrapers grab a title and a price and stop there. This actor pulls the full listing card **and** the agent lead **and** (on demand) the listing detail page — the data that actually drives valuations, market research and outreach.

| Data | Typical scrapers | This actor |
|---|---|---|
| Title / project, price, PSF | ✅ | ✅ |
| Bedrooms, bathrooms, floor area | partial | ✅ |
| Property type, tenure, build year | ❌ | ✅ |
| District + nearest MRT (walk time) | ❌ | ✅ |
| Photo count, official-listing & verified flags | ❌ | ✅ |
| Agent name, **CEA license**, agency | ❌ | ✅ |
| Agent **phone / WhatsApp** | ❌ | ✅ opt-in |
| Full description + condo facilities | ❌ | ✅ opt-in |
| Exact geo (lat/lng) + price history | ❌ | ✅ opt-in |
| **De-duplicated agent lead records** + lead score | ❌ | ✅ opt-in |
| **Monitor mode** — only new listings | ❌ | ✅ |

### Use cases

- **Agent & agency lead generation** — every listing carries the agent (name, CEA license, agency, profile). Turn on `includeListingDetails` + `includeAgentLeads` to build a de-duplicated call list **with phone numbers** for the most active agents in any town or price band.
- **Price & market intelligence** — track asking prices, PSF and supply for condos, HDB resale and landed homes by district, MRT or project; compare against transacted data and rentals.
- **Comparables & valuations** — pull every active listing for a project or district with beds/baths, area, tenure and PSF for instant comp sets.
- **New-launch & inventory monitoring** — watch a project, district or saved search and capture new listings the moment they appear (`monitorMode`).
- **Rental research** — switch `listingType` to `rent` for rental supply, asking rents and landlord/agent contacts.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **PropertyGuru Scraper**, enter search keywords (towns, districts, MRT or project names), choose **For sale / For rent**, and optionally a price range or bedroom count — then click **Start**.
3. Watch listings (and agent leads) stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML or RSS — or pull results via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "searchQueries": ["Tampines", "Bukit Timah"],
    "listingType": "sale",
    "minPrice": 800000,
    "maxPrice": 2500000,
    "bedrooms": ["3"],
    "maxItems": 100,
    "includeListingDetails": true,
    "includeAgentLeads": true
}
```

- **searchQueries** — free-text searches: towns/areas (`Tampines`), districts, MRT stations, or project names (`The Gazania`). Leave empty to browse the latest listings of the chosen type.
- **listingType** — `sale` (default), `rent`, or `new_launch`.
- **startUrls** — paste full PropertyGuru **search** pages (with filters applied in your browser) or individual **listing** pages (`/listing/...`).
- **minPrice / maxPrice / bedrooms** — filters.
- **includeListingDetails** *(default false)* — open each listing for the full description, **agent phone / WhatsApp**, condo facilities, geo, furnishing/completion and price history.
- **includeAgentLeads** *(default false)* — also output one de-duplicated `agent` lead record per unique agent (with lead score).
- **monitorMode / monitorKey** — output only listings not seen on previous runs.
- **maxItems** — cap across all searches.

> **Tip:** PropertyGuru rate-limits deep pagination. For large pulls, add **more keywords** (towns, districts, MRT) rather than relying on many pages of one search — the actor fetches a reliable first page per keyword and paginates as far as the site allows.

### Output

One record per listing (`type: "listing"`), plus optional agent leads (`type: "agent"`):

```json
{
    "type": "listing",
    "listingType": "sale",
    "listingId": "500182802",
    "url": "https://www.propertyguru.com.sg/listing/for-sale-the-gazania-500182802",
    "title": "The Gazania",
    "price": 2498000,
    "pricePretty": "S$ 2,498,000",
    "currency": "SGD",
    "psf": "S$ 2,607.52 psf",
    "propertyType": "Condominium",
    "bedrooms": 3,
    "bathrooms": 3,
    "floorArea": 958,
    "floorAreaText": "958 sqft",
    "tenure": "Freehold",
    "buildYear": 2023,
    "fullAddress": "7 How Sun Drive",
    "district": "Hougang / Punggol / Sengkang, Serangoon / Thomson (D19-20)",
    "mrtNearby": "5 min (390 m) from CC12 Bartley MRT Station",
    "photoCount": 14,
    "isOfficialListing": true,
    "recencyText": "Listed on Jun 26, 2026",
    "agentId": "17258882",
    "agentName": "Chris Ooi",
    "agentLicense": "R070591H",
    "agentProfileUrl": "https://www.propertyguru.com.sg/agent/chris-ooi-17258882",
    "agencyName": "PROPNEX REALTY PTE. LTD.",
    "agentMobile": "+6597348812",
    "description": "The Gazania | District 19 | Top Floor | 958 SQFT | Functional 3 Bedroom Layout…",
    "facilities": ["Swimming Pool", "Gym", "BBQ Pits", "24h Security"],
    "leadScore": 92,
    "scrapedAt": "2026-06-26T01:30:00.000Z"
}
```

An agent lead (`type: "agent"`) carries `agentName`, `agencyName`, `agentLicense`, `agentMobile`, `agentWhatsapp`, `agentProfileUrl`, `listingCountSeen`, a `sampleListingUrl` and a 0–100 `leadScore`.

#### What to expect (field coverage)

PropertyGuru listings are agent-entered, so a handful of fields exist only when the agent filled them in. **Title/project, price, PSF, property type, beds/baths, floor area, district, MRT, agent name, CEA license and agency are present on virtually every listing.** Full descriptions, facilities, geo, price history and **agent phone numbers** come from the listing page and require `includeListingDetails`. A blank field means the agent didn't publish it, never that scraping failed.

### Automate & schedule

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run hourly/daily to watch a town, district or project for new listings; pair with `monitorMode` for clean only-new output.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, price-drop email) the moment a run finishes.

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

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

const run = await client.actor('scrapesage/propertyguru-scraper').call({
    searchQueries: ['Bukit Timah', 'Orchard'],
    listingType: 'sale',
    minPrice: 2000000,
    includeListingDetails: true,
    includeAgentLeads: true,
    maxItems: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} listings & agent leads`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new agent leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored search finds new listings.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "find 3-bedroom condos in Tampines under S$1.8M and list the agents' phone numbers" and let it run this scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **Singapore property, market & lead-gen stack**:

- **[99.co Property Scraper](https://apify.com/scrapesage/99-co-property-scraper)** — Singapore listings & agent leads (asking prices).
- **[EdgeProp.sg Scraper](https://apify.com/scrapesage/edgeprop-singapore-scraper)** — Singapore property & agent leads, investor data.
- **[SGCarMart Used Car Scraper](https://apify.com/scrapesage/sgcarmart-used-car-scraper)** — used-car prices, COE/OMV/ARF & dealer leads.
- **[Singapore Company Scraper](https://apify.com/scrapesage/singapore-company-scraper)** — UEN, registry & business leads.
- **[StreetDirectory Scraper](https://apify.com/scrapesage/streetdirectory-business-scraper)** — Singapore business leads.
- **[MyCareersFuture Scraper](https://apify.com/scrapesage/mycareersfuture-scraper)** — Singapore jobs, salaries & leads.
- **[Rightmove Scraper](https://apify.com/scrapesage/rightmove-scraper)** — UK property for sale & to rent, plus agent leads.
- **[Redfin Scraper](https://apify.com/scrapesage/redfin-scraper)** — US real-estate listings & estimates.
- **[Rent.com Scraper](https://apify.com/scrapesage/rent-com-scraper)** — US rentals & property-manager leads.

### Tips

- **Agent call lists**: turn on `includeListingDetails` + `includeAgentLeads`, search the towns/price bands you sell in, and export the **Agent leads** view straight to your CRM.
- **Exact filters**: apply every filter you want in your browser on propertyguru.com.sg, then paste the resulting search URL into `startUrls` — the actor reproduces it.
- **Breadth over depth**: PropertyGuru limits deep pagination — list several towns/districts/MRT in `searchQueries` rather than paging one search forever.
- **Only new listings**: combine [Schedules](https://docs.apify.com/platform/schedules) with `monitorMode` (and a unique `monitorKey` per saved search) for clean new-listing alerts.
- **Cost control**: leave `includeListingDetails` off for fast, cheap listing-card runs; turn it on only when you need descriptions, facilities and agent phone numbers.

### FAQ

**How do I scrape a specific town, district or project?** Put it in `searchQueries` (e.g. `Tampines`, `District 10`, `The Gazania`), or paste a PropertyGuru search URL into `startUrls`.

**Does it need the PropertyGuru API or a login?** No. This actor reads the same public listing pages a visitor sees — no key or login required.

**Where do agent phone numbers come from?** From the public listing page, when `includeListingDetails` is on. PropertyGuru publishes the listing agent's contact on each listing; the actor reads it there.

**Can I export to Google Sheets, CSV or Excel?** Yes — one click in the dataset view, or automatically every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**How do I monitor new listings automatically?** Turn on `monitorMode`, create a [Schedule](https://docs.apify.com/platform/schedules), and optionally add a [webhook](https://docs.apify.com/platform/integrations/webhooks) or [Zapier zap](https://docs.apify.com/platform/integrations/zapier) to push new listings/leads into your tools as they appear.

**Is scraping PropertyGuru legal?** This actor collects publicly available data only. You are responsible for using the data in compliance with applicable laws (e.g. Singapore's PDPA for personal data) and PropertyGuru's terms.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

## `searchQueries` (type: `array`):

Free-text searches on PropertyGuru — district names, town/area (e.g. `Tampines`, `Bukit Timah`), MRT stations, or project names (e.g. `The Gazania`). Each is combined with the listing type and filters below. Leave empty to browse the latest listings of the chosen type.

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

Whether to scrape properties for sale, for rent, or new launches.

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

Paste full PropertyGuru URLs — search/results pages (with any filters already applied in your browser) or individual listing pages (`/listing/...`). Use this to reproduce an exact filtered search.

## `minPrice` (type: `integer`):

Only return listings at or above this price.

## `maxPrice` (type: `integer`):

Only return listings at or below this price.

## `bedrooms` (type: `array`):

Filter by number of bedrooms (e.g. `2`, `3`). Add multiple to match any of them. Leave empty for all.

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

Maximum number of listings to return across all searches. Pagination stops once this is reached.

## `maxPagesPerQuery` (type: `integer`):

How many result pages to try per keyword (20 listings/page). PropertyGuru rate-limits deep pagination, so the actor stops a search early if pages get blocked — add more keywords for breadth instead.

## `includeListingDetails` (type: `boolean`):

Open each listing's page for the full description, the agent's contact number (mobile/WhatsApp), condo facilities, exact geo, furnishing/completion details and price history. Adds one request per listing.

## `includeAgentLeads` (type: `boolean`):

Also emit one de-duplicated `agent` lead record per unique agent found (name, CEA license, agency, profile, phone when enriched, lead score). Combine with `includeListingDetails` to capture phone numbers.

## `monitorMode` (type: `boolean`):

Remember listings seen on previous runs and output only NEW ones each run. Ideal on a Schedule for new-listing alerts and agent-lead pipelines. Uses a named key-value store so it works alongside Apify Schedules.

## `monitorKey` (type: `string`):

Name for this monitor's memory. Use a distinct key per saved search so their 'seen' lists don't mix.

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

Proxy settings. PropertyGuru blocks datacenter IPs, so the actor defaults to Apify Residential proxy in Singapore — leave this as-is for best results.

## Actor input object example

```json
{
  "searchQueries": [
    "Tampines",
    "Bukit Timah",
    "Punggol"
  ],
  "listingType": "sale",
  "maxItems": 100,
  "maxPagesPerQuery": 10,
  "includeListingDetails": false,
  "includeAgentLeads": false,
  "monitorMode": false,
  "monitorKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "SG"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped records in the default dataset. Each row is tagged with a `type` (listing or agent).

# 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 = {
    "searchQueries": [
        "Tampines",
        "Bukit Timah",
        "Punggol"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/propertyguru-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 = { "searchQueries": [
        "Tampines",
        "Bukit Timah",
        "Punggol",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/propertyguru-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "Tampines",
    "Bukit Timah",
    "Punggol"
  ]
}' |
apify call scrapesage/propertyguru-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/propertyguru-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/F7UAtxjy516b4TTU6/builds/UvZoOyw6JZkLndAVu/openapi.json
