# EdgeProp.sg Scraper — Singapore Property & Agent Leads (`scrapesage/edgeprop-singapore-scraper`) Actor

Scrape Singapore property listings from EdgeProp.sg — price, PSF, beds, baths, size, project, district, tenure, rental yield and photos, plus the agent's name, CEA reg no, agency and mobile for lead generation. Sale & rent across condo, HDB & landed. Monitor price drops. No login or API key.

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

## Pricing

$4.00 / 1,000 property listing scrapeds

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## EdgeProp.sg Scraper — Singapore Property Listings & Agent Leads

Extract **complete property data from [EdgeProp.sg](https://www.edgeprop.sg)** — one of Singapore's leading property portals. Get every field that matters: **asking price, price-per-sqft (PSF), bedrooms, bathrooms, floor/land area, project, postal district, market segment (CCR/RCR/OCR), tenure, year completed, rental yield and the full photo gallery** — plus, for lead generation, the **listing agent's name, CEA registration number, agency and mobile number** on every listing.

No login, no cookies, no browser, no API key — fast extraction straight from EdgeProp's structured listing data, with **monitor mode** to capture only new listings and **price drops** on a schedule.

### Why this EdgeProp scraper?

Most property scrapers grab the listing card and stop, returning prices without the agent contact or the investment signals that make the data actionable. This actor reads EdgeProp's structured listing data directly and ships the **richest EdgeProp.sg dataset in the category** — every agent turned into a contactable lead, plus EdgeProp's own analytics.

| Data | Typical property scrapers | This actor |
|---|---|---|
| Asking price + PSF + raw price | ✅ | ✅ |
| Beds, baths, floor & land area (sqft + sqm) | partial | ✅ |
| Project, street, postal code, district | partial | ✅ |
| Market segment (CCR / RCR / OCR) | ❌ | ✅ |
| Tenure + year completed | ❌ | ✅ |
| **Agent name + CEA reg no + agency + mobile** | ❌ | ✅ on every listing |
| Rental yield, sales/rental volume, vs-fair-value | ❌ | ✅ when published |
| EdgeProp insights (MRT, malls, lease left, profitability) | ❌ | ✅ |
| Full photo gallery (all images, full-size) | ❌ first photo | ✅ |
| Sale **and** rent, condo / HDB / landed / commercial | partial | ✅ |
| **Monitor mode** — new listings + price drops | ❌ | ✅ |
| No start fee | ❌ | ✅ |

### Use cases

- **Property agent & brokerage lead generation** — every listing carries the agent's name, **CEA registration number**, agency and **mobile number**. Filter by district, price band or property type and build targeted outreach lists of Singapore property agents.
- **Pricing & market intelligence** — track asking prices, PSF and inventory across districts and CCR / RCR / OCR; spot under/over-priced units and segment trends.
- **Rental yield & investment screening** — compare PSF, rental yield and EdgeProp's below-fair-value signal to shortlist deals; filter condo / HDB / landed by tenure, size and price.
- **Listing & price-drop monitoring** — watch a district, project or the whole market for new listings and price reductions with **monitor mode**.
- **Portals & dashboards** — power a Singapore property feed or BI dashboard from scheduled runs.

### 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 **EdgeProp.sg Scraper**, pick the **property types** and **listing type** (or paste EdgeProp category URLs), set any filters, and click **Start**.
3. Watch results stream into the dataset table — one clean row per property.
4. **Export** as JSON, CSV, Excel, XML, or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "propertyTypes": ["condo", "hdb"],
    "listingType": "sale",
    "minPrice": 800000,
    "maxPrice": 2500000,
    "minBedrooms": 2,
    "districts": ["9", "10", "15"],
    "deepScrape": true,
    "maxResults": 500,
    "monitorMode": false
}
````

- **propertyTypes** — any of `condo`, `hdb`, `landed`, `commercial`, `industrial`.
- **listingType** — `sale`, `rent`, or `room` (room rental).
- **startUrls** — optional: paste EdgeProp category URLs (e.g. `https://www.edgeprop.sg/condo-apartment-for-sale`); they override the selectors above.
- **minPrice / maxPrice** — asking-price bounds (sale: total price; rent: monthly rent).
- **minBedrooms / districts** — keep only listings meeting these criteria (districts 1–28).
- **deepScrape** *(default true)* — EdgeProp renders only the top ~20 listings per bare category, so the actor slices each category into asking-price bands to pull thousands of unique listings (deduplicated by listing ID). Turn off for a fast, cheap top-20-per-category run.
- **maxResults / maxResultsPerCategory** *(default 200 / 0)* — caps for test runs or budget control.
- **monitorMode** *(default false)* — emit only new or price-changed listings since the last run (see below).
- **dedupStoreName** *(default `edgeprop-sg-state`)* — named store holding the monitor state.
- **proxyConfiguration** — proxy settings (default Apify datacenter proxy; residential is **not** needed).

### Output

One clean record per listing:

```json
{
    "listingId": "m_2178154",
    "url": "https://www.edgeprop.sg/listing/apartment-condo/condominium/kent-ridge-hill-residences/m_2178154",
    "projectName": "KENT RIDGE HILL RESIDENCES",
    "listingType": "sale",
    "propertyType": "Apartment / Condo",
    "propertySubType": "Condominium",
    "askingPrice": 2288000,
    "pricePsf": 2192,
    "currency": "SGD",
    "bedrooms": 3,
    "bathrooms": 3,
    "floorAreaSqft": 1044,
    "floorAreaSqm": 96.99,
    "tenure": "99 Years",
    "yearCompleted": "2023",
    "district": "5",
    "districtCategory": "Private",
    "marketSegment": "RCR",
    "streetName": "South Buona Vista Road",
    "postalCode": "117293",
    "rentalYield": null,
    "belowFairValuePct": null,
    "rentalVolume": 34.9,
    "insights": ["1 MRT/LRT Currently nearby", "2 Malls nearby", "91 Years of Lease left", "Only 3 Years Old"],
    "imageCount": 9,
    "images": ["https://img.tepcdn.com/.../photo_1.jpg", "..."],
    "thumbnailUrl": "https://img.tepcdn.com/.../photo_1.jpg",
    "hasVirtualTour": true,
    "agentName": "Zola",
    "agentCeaRegNo": "R029291I",
    "agencyName": "PROPNEX REALTY PTE. LTD.",
    "agentPhone": "89423355",
    "agentProfileUrl": "https://www.edgeprop.sg/property-agents/Zola--89423355",
    "updatedAt": "2026-06-12T13:01:33.937Z",
    "sourceCategory": "condo-sale",
    "scrapedAt": "2026-06-12T19:38:56.741Z"
}
```

#### What to expect (field coverage)

EdgeProp is agent-entered data, so some fields appear only when the agent or EdgeProp published them. All prices are in **SGD**.

| Field group | Always present | Present when published |
|---|---|---|
| Identity & price | listingId, url, projectName, askingPrice, pricePsf, propertyType | askingPriceType |
| Size & beds | bedrooms, bathrooms, floorAreaSqft/Sqm | landArea (landed) |
| Location | district, marketSegment, streetName, postalCode | subzone, planningRegion |
| Attributes | tenure | yearCompleted, strataStatus |
| **Agent lead** | agentName, agentCeaRegNo, agencyName, **agentPhone**, agentProfileUrl | agentPhotoUrl |
| Investment | — | rentalYield, belowFairValuePct, salesVolume, rentalVolume |
| Media | imageCount, images, thumbnailUrl | floorplanCount, videoCount, hasVirtualTour |

A blank field means it wasn't published for that listing — never that scraping failed. Nothing is dropped, so you always get the richest record available.

> **Market segment** (CCR / RCR / OCR) is derived from the postal district using the common URA-based mapping; treat it as an approximate classification.

### Monitor only new listings & price drops

Turn on **`monitorMode`** and the actor saves the asking price of every listing it has seen in a **named key-value store** (`dedupStoreName`), then on each later run emits **only listings that are new or whose price changed** — tagged with `monitorStatus`:

- `new` — a listing not seen before.
- `price_drop` — the asking price fell (with `previousPrice`).
- `price_increase` — the asking price rose (with `previousPrice`).

The **first run emits everything** (and seeds the state); subsequent runs emit only the delta. Combined with a daily [Schedule](https://docs.apify.com/platform/schedules), you get a clean feed of *just* the new listings and price reductions for your search — perfect for buyer alerts, agent prospecting and BI ingestion.

- Monitor mode is the actor's own dedupe layer — it **complements**, and does not conflict with, Apify [Schedules](https://docs.apify.com/platform/schedules) (a cron trigger) or the Console [Monitoring](https://docs.apify.com/platform/monitoring) tab (charts & alerts). The Schedule triggers the run; monitor mode decides what's worth saving.
- Use a **distinct `dedupStoreName` per independent monitor** so their states don't mix.
- If you schedule frequent runs, enable the Schedule's *exclusive* option so a new run doesn't start before the previous one finishes writing its state.
- Heads-up: a quiet run legitimately returns **0 items**, which can trip a Console Monitoring "results lower than N" alert — expected behaviour, not an error.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[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 **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it daily to track a district, project or the whole market; pair with `monitorMode` for new-listing and price-drop alerts.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, email sequence) 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/edgeprop-singapore-scraper').call({
    propertyTypes: ['condo'],
    listingType: 'sale',
    districts: ['9', '10', '11'],
    monitorMode: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} new / price-changed 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 district lists a property or drops a price.
- **[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 District 15 under $2.5M and list the agents with their phone numbers" and let it run the scraper for you.

### More scrapers from scrapesage

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

- **[99.co Property Scraper](https://apify.com/scrapesage/99-co-property-scraper)** — Singapore listings and agent leads from 99.co.
- **[SGCarMart Used Car Scraper](https://apify.com/scrapesage/sgcarmart-used-car-scraper)** — Singapore used cars with prices, COE/OMV/ARF and dealer leads.
- **[MyCareersFuture Scraper](https://apify.com/scrapesage/mycareersfuture-scraper)** — Singapore government jobs with salaries and employer UEN.
- **[JobStreet Singapore Scraper](https://apify.com/scrapesage/jobstreet-singapore-scraper)** — jobs, salaries and company data from JobStreet.
- **[Eventbrite Scraper](https://apify.com/scrapesage/eventbrite-scraper)** — events plus organizer leads (ticket prices, emails, socials).
- **[Bark Listing Scraper](https://apify.com/scrapesage/bark-listing-scraper)** — service-provider leads from Bark.
- **[Airbnb Scraper](https://apify.com/scrapesage/airbnb-scraper)** — listings, prices, and availability.
- **[Facebook Ad Library Scraper](https://apify.com/scrapesage/facebook-ad-library-scraper)** — competitor ad intelligence (see which agencies advertise what).

### Tips

- **Deep scrape for volume**: keep `deepScrape` on to pull thousands of listings per category via price-band sharding. Turn it off (and/or set a small `maxResults`) for a quick, cheap top-20-per-category sample.
- **Agent prospecting**: every listing already includes the agent's name, CEA reg no, agency and mobile — no enrichment step needed. Filter by `district` or price band to build a focused outreach list, and dedupe by `agentCeaRegNo`.
- **Investment screening**: sort the dataset by `pricePsf`, `rentalYield` or `belowFairValuePct` to surface value.
- **Recurring monitoring**: combine `monitorMode` with [Schedules](https://docs.apify.com/platform/schedules) and a [webhook](https://docs.apify.com/platform/integrations/webhooks) to push new listings and price drops into your CRM the moment they appear.

### FAQ

**How do I scrape a specific district or price range?** Use `districts`, `minPrice`/`maxPrice` and `minBedrooms`, or paste a filtered EdgeProp category URL into `startUrls`.

**Does it need an EdgeProp API key or login?** No. This actor reads EdgeProp's public structured listing data — no key, cookie or login required.

**Where does the agent's phone number come from?** From the listing's own public agent reference on EdgeProp. Every listing includes the agent's name, CEA registration number, agency and mobile number.

**Why do I only get ~20 listings per category with deep scrape off?** EdgeProp renders only the top ~20 recommended listings for a bare category URL. Turn `deepScrape` on and the actor slices each category into asking-price bands to capture thousands of unique listings.

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

**How do I monitor new listings or price drops automatically?** Turn on `monitorMode` and create a [Schedule](https://docs.apify.com/platform/schedules). Each run outputs only new/changed listings, tagged with `monitorStatus` and `previousPrice`.

**A field is empty — why?** Some agents don't publish every field (e.g. year completed, rental yield). Fields are blank only when the data wasn't published — never because the scraper skipped them.

**Is scraping EdgeProp legal?** This actor collects publicly available data only. You're responsible for using the data in compliance with applicable laws (e.g. Singapore's PDPA for personal data) and EdgeProp'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

## `propertyTypes` (type: `array`):

Which Singapore property segments to scrape. Allowed values: <code>condo</code> (condo/apartment), <code>hdb</code>, <code>landed</code>, <code>commercial</code>, <code>industrial</code>.

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

For sale, for rent, or room rental.

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

Optional: paste EdgeProp.sg category URLs straight from the site, e.g. <code>https://www.edgeprop.sg/condo-apartment-for-sale</code> or <code>https://www.edgeprop.sg/hdb-for-rent</code>. When set, these override the Property types / Listing type selectors above.

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

Only include listings at or above this asking price (sale: total price; rent: monthly rent). 0 = no minimum.

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

Only include listings at or below this asking price. 0 = no maximum.

## `minBedrooms` (type: `integer`):

Only include listings with at least this many bedrooms. 0 = no minimum.

## `districts` (type: `array`):

Optional. Keep only listings in these Singapore postal districts (numbers 1–28), e.g. <code>9</code>, <code>10</code>, <code>15</code>.

## `deepScrape` (type: `boolean`):

EdgeProp renders only the top ~20 listings for a bare category. With this ON the scraper slices each category into asking-price bands to pull thousands of unique listings (deduplicated by listing ID). Turn OFF to grab just the top ~20 recommended listings per category for a fast, cheap run.

## `maxResults` (type: `integer`):

Stop after this many listings across all categories (0 = no limit). Singapore inventory spans tens of thousands of listings, so set a cap for test runs.

## `maxResultsPerCategory` (type: `integer`):

Cap listings per property-type category (0 = no per-category cap).

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

Output only listings that are <b>new</b> or whose <b>price changed</b> since the last run for the same input. Each row is tagged with <code>monitorStatus</code> (<code>new</code>, <code>price\_drop</code>, <code>price\_increase</code>) and, for price changes, <code>previousPrice</code>. The first run emits everything and seeds the state. Pairs perfectly with Apify Schedules — see the README.

## `dedupStoreName` (type: `string`):

Named key-value store that holds the 'seen listings' state for monitor mode. Use a distinct name per independent monitor (e.g. per client or per saved search) so their states don't mix.

## `maxConcurrency` (type: `integer`):

Maximum number of requests made in parallel.

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

Proxy settings. EdgeProp.sg works well over the default Apify datacenter proxy; switch to residential only if you hit persistent challenges.

## Actor input object example

```json
{
  "propertyTypes": [
    "condo"
  ],
  "listingType": "sale",
  "minPrice": 0,
  "maxPrice": 0,
  "minBedrooms": 0,
  "deepScrape": true,
  "maxResults": 200,
  "maxResultsPerCategory": 0,
  "monitorMode": false,
  "dedupStoreName": "edgeprop-sg-state",
  "maxConcurrency": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All scraped listings in the default dataset. One clean row per property.

# 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 = {
    "propertyTypes": [
        "condo"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/edgeprop-singapore-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 = { "propertyTypes": ["condo"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/edgeprop-singapore-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 '{
  "propertyTypes": [
    "condo"
  ]
}' |
apify call scrapesage/edgeprop-singapore-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "EdgeProp.sg Scraper — Singapore Property & Agent Leads",
        "description": "Scrape Singapore property listings from EdgeProp.sg — price, PSF, beds, baths, size, project, district, tenure, rental yield and photos, plus the agent's name, CEA reg no, agency and mobile for lead generation. Sale & rent across condo, HDB & landed. Monitor price drops. No login or API key.",
        "version": "0.1",
        "x-build-id": "JRvYm5yMIMvzu1Pb7"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapesage~edgeprop-singapore-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapesage-edgeprop-singapore-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/scrapesage~edgeprop-singapore-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapesage-edgeprop-singapore-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/scrapesage~edgeprop-singapore-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapesage-edgeprop-singapore-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "propertyTypes": {
                        "title": "Property types",
                        "type": "array",
                        "description": "Which Singapore property segments to scrape. Allowed values: <code>condo</code> (condo/apartment), <code>hdb</code>, <code>landed</code>, <code>commercial</code>, <code>industrial</code>.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "listingType": {
                        "title": "Listing type",
                        "enum": [
                            "sale",
                            "rent",
                            "room"
                        ],
                        "type": "string",
                        "description": "For sale, for rent, or room rental.",
                        "default": "sale"
                    },
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Optional: paste EdgeProp.sg category URLs straight from the site, e.g. <code>https://www.edgeprop.sg/condo-apartment-for-sale</code> or <code>https://www.edgeprop.sg/hdb-for-rent</code>. When set, these override the Property types / Listing type selectors above.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "minPrice": {
                        "title": "Minimum price (SGD)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include listings at or above this asking price (sale: total price; rent: monthly rent). 0 = no minimum.",
                        "default": 0
                    },
                    "maxPrice": {
                        "title": "Maximum price (SGD)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include listings at or below this asking price. 0 = no maximum.",
                        "default": 0
                    },
                    "minBedrooms": {
                        "title": "Minimum bedrooms",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include listings with at least this many bedrooms. 0 = no minimum.",
                        "default": 0
                    },
                    "districts": {
                        "title": "Postal districts",
                        "type": "array",
                        "description": "Optional. Keep only listings in these Singapore postal districts (numbers 1–28), e.g. <code>9</code>, <code>10</code>, <code>15</code>.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "deepScrape": {
                        "title": "Deep scrape (price-band sharding)",
                        "type": "boolean",
                        "description": "EdgeProp renders only the top ~20 listings for a bare category. With this ON the scraper slices each category into asking-price bands to pull thousands of unique listings (deduplicated by listing ID). Turn OFF to grab just the top ~20 recommended listings per category for a fast, cheap run.",
                        "default": true
                    },
                    "maxResults": {
                        "title": "Max results (total)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Stop after this many listings across all categories (0 = no limit). Singapore inventory spans tens of thousands of listings, so set a cap for test runs.",
                        "default": 200
                    },
                    "maxResultsPerCategory": {
                        "title": "Max results per category",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap listings per property-type category (0 = no per-category cap).",
                        "default": 0
                    },
                    "monitorMode": {
                        "title": "Monitor mode — only new & changed listings",
                        "type": "boolean",
                        "description": "Output only listings that are <b>new</b> or whose <b>price changed</b> since the last run for the same input. Each row is tagged with <code>monitorStatus</code> (<code>new</code>, <code>price_drop</code>, <code>price_increase</code>) and, for price changes, <code>previousPrice</code>. The first run emits everything and seeds the state. Pairs perfectly with Apify Schedules — see the README.",
                        "default": false
                    },
                    "dedupStoreName": {
                        "title": "Monitor state store name",
                        "type": "string",
                        "description": "Named key-value store that holds the 'seen listings' state for monitor mode. Use a distinct name per independent monitor (e.g. per client or per saved search) so their states don't mix.",
                        "default": "edgeprop-sg-state"
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Maximum number of requests made in parallel.",
                        "default": 6
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Proxy settings. EdgeProp.sg works well over the default Apify datacenter proxy; switch to residential only if you hit persistent challenges.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
