# URA Private Property Transactions Scraper - Singapore Caveats (`scrapesage/ura-property-transactions-scraper`) Actor

Scrape official URA private residential transactions (caveats) for Singapore: transacted price, $PSF/$PSM, area, tenure, floor, district, market segment & sale type. Filter by period, type & price. No API key. Export to JSON, CSV or Excel.

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

## Pricing

$4.00 / 1,000 transaction 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

## URA Private Property Transactions Scraper — Singapore Caveats

Extract **Singapore's official private residential property transactions** straight from the **[URA](https://www.ura.gov.sg) Property Market Information** portal — the *actual transacted (caveat) prices*, not asking prices. Every record carries the **transacted price, $PSF and $PSM, floor area (sqft & sqm), tenure, floor level, postal district, market segment (CCR/RCR/OCR), property type and sale type**, with the period, district, price and tenure all filterable.

No API key, no login, no browser, **no personal data** — this actor reads URA's own public transaction search and ships a clean, analysis-ready dataset of every caveat in your chosen period.

### Why this URA transactions scraper?

Property portals show **asking** prices. The number that actually matters — what a unit **sold for** — is the caveat lodged with URA. This actor turns that gated, paginated government search into a structured, exportable dataset, with derived fields most tools never compute:

| Data | Portal listings | This actor |
|---|---|---|
| Project & street name | ✅ | ✅ |
| **Transacted price (actual, not asking)** | ❌ | ✅ |
| **Unit price $PSF and $PSM** | partial | ✅ |
| Floor area in **sqft and sqm** | partial | ✅ |
| **Nett price** (developer discounts) | ❌ | ✅ when applicable |
| Sale type (New Sale / Sub Sale / Resale) | partial | ✅ |
| Property type (condo, apartment, EC, landed…) | ✅ | ✅ |
| **Tenure** + derived freehold/leasehold, lease term, **remaining lease years** | ❌ | ✅ |
| **Postal district + locality name** (01–28) | partial | ✅ |
| **Market segment** CCR / RCR / OCR | ❌ | ✅ |
| Floor-level band (+ parsed from/to floors) | ❌ | ✅ |
| Period, price, $PSF, area & tenure filters | ❌ | ✅ |
| Monitor mode — only newly lodged caveats | ❌ | ✅ |
| One clean dataset, no empty columns | ❌ | ✅ |

### Use cases

- **Asking-vs-transacted analysis** — pair this with a listings scraper ([99.co](https://apify.com/scrapesage/99-co-property-scraper), [EdgeProp.sg](https://apify.com/scrapesage/edgeprop-singapore-scraper)) to compare what's *listed* against what actually *sold*.
- **Automated valuation & comparables (X-Value style)** — pull recent caveats for a project, district or street to build comps and price-per-square-foot benchmarks.
- **Investment & market research** — track $PSF trends by market segment (CCR/RCR/OCR), tenure and property type over any period.
- **Agent & developer intelligence** — see transaction volume and pricing by project, district and floor band.
- **Mortgage, proptech & analytics products** — feed standardized, deduplicated transaction records into dashboards, models and data warehouses.
- **Lease-decay analysis** — `remainingLeaseYears` is computed for every leasehold caveat, ready for ageing-leasehold studies.

### 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 **URA Private Property Transactions Scraper**, choose a **period** (`fromMonth` / `toMonth`) and optionally a **property type, postal district, market segment or price band**, then click **Start**.
3. Watch transactions stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

Leave everything on defaults and you get the **last 6 months of all-Singapore private residential transactions**, newest period first.

### Input

```json
{
    "fromMonth": "2026-01",
    "toMonth": "2026-06",
    "propertyTypes": ["Apartments & Condominiums", "Executive Condominiums"],
    "saleTypes": ["Resale"],
    "postalDistricts": ["09", "10", "11"],
    "marketSegments": ["CCR"],
    "minPrice": 1000000,
    "maxResults": 500,
    "monitorMode": false
}
````

- **fromMonth / toMonth** — period as `YYYY-MM`. Leave blank for a rolling last-6-months window ending the current month.
- **propertyTypes** — `Landed (Non-Strata)`, `Strata Landed`, `Apartments & Condominiums`, `Executive Condominiums`. Empty = all.
- **saleTypes** — `New Sale`, `Sub Sale`, `Resale`. Empty = all.
- **postalDistricts** — keep only districts `01`–`28` (e.g. `09` Orchard, `10` Bukit Timah, `15` East Coast, `19` Hougang/Punggol/Sengkang). Empty = all of Singapore.
- **marketSegments** — `CCR` (Core Central), `RCR` (Rest of Central), `OCR` (Outside Central). Empty = all.
- **projectNameContains / streetContains** — case-insensitive substring filters.
- **minPrice / maxPrice / minPsf / maxPsf / minAreaSqft / maxAreaSqft** — numeric range filters (`0` = no bound).
- **tenureFilter** — `Any`, `Freehold` or `Leasehold`.
- **maxResults** *(default 100)* — cap on transaction records. Raise it for a full market pull (URA returns thousands of caveats for a typical multi-month query).
- **resultsPerRequest** *(default 200)* — rows pulled per page request (20–500).
- **monitorMode** *(default false)* — emit only caveats not seen in previous runs (see below).

### Output

One record per transaction (caveat):

```json
{
    "projectName": "QUEENS",
    "streetName": "STIRLING ROAD",
    "propertyType": "Condominium",
    "typeOfArea": "Strata",
    "typeOfSale": "Resale",
    "transactedPrice": 1584000,
    "nettPrice": null,
    "unitPricePsf": 1731,
    "unitPricePsm": 18635,
    "areaSqft": 914.94,
    "areaSqm": 85,
    "numberOfUnits": 1,
    "postalDistrict": "03",
    "districtName": "Queenstown, Tiong Bahru",
    "marketSegment": "Rest of Central Region",
    "region": "RCR",
    "tenure": "99 yrs lease commencing from 1998",
    "tenureType": "Leasehold",
    "leaseTermYears": 99,
    "leaseCommenceYear": 1998,
    "remainingLeaseYears": 71,
    "floorLevel": "11 to 15",
    "floorFrom": 11,
    "floorTo": 15,
    "saleMonth": "2026-06",
    "saleYear": 2026,
    "saleDateRaw": "Jun-26",
    "transactionId": "QUEENS|STIRLING ROAD|2026-06|1584000|914.94|11 to 15|Condominium|Resale",
    "sourceUrl": "https://eservice.ura.gov.sg/property-market-information/pmiResidentialTransactionSearch",
    "scrapedAt": "2026-06-25T12:00:00.000Z"
}
```

Use the **Transactions**, **Pricing & size** and **By location** dataset views to switch between column sets.

#### What to expect (field coverage)

| Field | Coverage |
|---|---|
| project, street, property type, sale type, transacted price, $PSF, $PSM, area (sqft & sqm), units, district, market segment, tenure, sale month | ~100% |
| floor level / floor band | strata apartments, condos & EC (landed houses have no floor band) |
| lease term, lease commence year, **remaining lease years** | all leasehold records (freehold has no lease) |
| nett price | only developer New Sales with a discount/rebate |

A blank field means URA does not record that value for that caveat (e.g. a freehold unit has no lease, a landed house has no floor band) — not that scraping failed. Nothing is dropped, so you always get the richest record URA exposes.

### Monitoring mode — only new transactions

Turn on **monitorMode** to make the actor remember which caveats it has already returned and emit **only transactions not seen in previous runs** — perfect for a daily/weekly feed of newly lodged caveats in a project, district or segment. It stores seen transaction fingerprints in a named key-value store (`monitorStoreName`, one per tracked market).

This **complements [Apify Schedules](https://docs.apify.com/platform/schedules)** and does not conflict with them: Schedules decide *when* the actor runs, monitoring mode decides *what is new* in each run. Use both together to track the market as fresh caveats are lodged.

### Automate & schedule

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, 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/weekly to refresh comps and capture new caveats.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (warehouse load, Slack alert, model refresh) 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/ura-property-transactions-scraper').call({
    fromMonth: '2026-01',
    toMonth: '2026-06',
    propertyTypes: ['Apartments & Condominiums'],
    postalDistricts: ['09', '10'],
    maxResults: 1000,
});

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

### 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 transactions into your tools.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored market records new caveats.
- **[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 "pull every URA condo transaction in district 9 over the last quarter and average the $PSF" and let it run the 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-intelligence stack**:

- **[99.co Property Scraper](https://apify.com/scrapesage/99-co-property-scraper)** — Singapore property listings and agent leads.
- **[EdgeProp.sg Scraper](https://apify.com/scrapesage/edgeprop-singapore-scraper)** — Singapore property listings and agent leads.
- **[Singapore Company Scraper](https://apify.com/scrapesage/singapore-company-scraper)** — UEN, registry and business leads.
- **[SGCarMart Used Car Scraper](https://apify.com/scrapesage/sgcarmart-used-car-scraper)** — used-car prices, COE/OMV/ARF and dealer leads.
- **[JobStreet Singapore Scraper](https://apify.com/scrapesage/jobstreet-singapore-scraper)** — Singapore jobs, salaries and leads.
- **[MyCareersFuture Scraper](https://apify.com/scrapesage/mycareersfuture-scraper)** — Singapore jobs, salaries and leads.
- **[StreetDirectory Scraper](https://apify.com/scrapesage/streetdirectory-business-scraper)** — Singapore business leads.
- **[Google Maps Scraper](https://apify.com/scrapesage/google-maps-scraper)** — local businesses with phone, website and reviews.

### Tips

- **Full market pull**: leave the filters empty, set a wide `fromMonth`/`toMonth` and a high `maxResults` to download every caveat in the period.
- **Comparables for one project**: set `projectNameContains` (e.g. `the sail`) over a 12-month window.
- **Prime vs suburban**: filter `marketSegments` to `CCR` (prime) or `OCR` (suburban) and compare $PSF.
- **Ageing leasehold**: filter `tenureFilter` to `Leasehold` and sort by `remainingLeaseYears`.
- **Recurring monitoring**: combine [Schedules](https://docs.apify.com/platform/schedules) with `monitorMode` to capture only newly lodged caveats.

### FAQ

**Are these asking prices or actual sale prices?** Actual. URA caveats are the transacted prices lodged when a property is bought — the ground-truth the whole market is benchmarked against.

**Does it need a URA account or API key?** No. This actor reads URA's own public Property Market Information transaction search — no AccessKey, login or browser.

**Does it expose any personal data?** No. URA caveats are anonymous — there are no buyer, seller or agent names. The data is purely about the property and the price.

**How far back can I go?** Use `fromMonth`/`toMonth` to set any period the URA portal covers (typically the recent years of caveats). Large windows simply return more records.

**Why is nett price / floor level / lease year sometimes blank?** Because URA doesn't record it for that caveat: nett price exists only for discounted developer sales, landed houses have no floor band, and freehold units have no lease. Nothing is dropped — blanks are honest source gaps.

**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 track new transactions?** Turn on `monitorMode` and create a [Schedule](https://docs.apify.com/platform/schedules); each run returns only caveats not seen before. Add a [webhook](https://docs.apify.com/platform/integrations/webhooks) to push them into your stack.

**Is scraping URA data legal?** This actor collects publicly available, non-personal transaction data. You are responsible for using it in compliance with applicable laws and URA'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

## `fromMonth` (type: `string`):

Start of the transaction period, e.g. "2025-07". Leave blank to default to 6 months before the current month. URA publishes the actual transacted (caveat) prices, so the most recent weeks are still being lodged.

## `toMonth` (type: `string`):

End of the transaction period, e.g. "2026-06". Leave blank to default to the current month.

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

Which private residential property-type groups to include. Leave empty for all four.

## `saleTypes` (type: `array`):

New Sale (developer), Sub Sale (re-assignment before completion) or Resale (secondary market). Leave empty for all.

## `postalDistricts` (type: `array`):

Keep only transactions in these URA postal districts (01–28). Leave empty for all of Singapore. e.g. 09 = Orchard/River Valley, 10 = Bukit Timah/Holland, 15 = Katong/East Coast, 19 = Hougang/Punggol/Sengkang.

## `marketSegments` (type: `array`):

Keep only these URA market segments: CCR = Core Central Region (prime), RCR = Rest of Central Region (city fringe), OCR = Outside Central Region (suburban). Leave empty for all.

## `projectNameContains` (type: `string`):

Keep only transactions whose project name contains this text (case-insensitive), e.g. "the sail", "normanton".

## `streetContains` (type: `string`):

Keep only transactions whose street name contains this text (case-insensitive), e.g. "river valley".

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

Keep only transactions at or above this price. 0 = no minimum.

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

Keep only transactions at or below this price. 0 = no maximum.

## `minPsf` (type: `integer`):

Keep only transactions at or above this $ per square foot. 0 = no minimum.

## `maxPsf` (type: `integer`):

Keep only transactions at or below this $ per square foot. 0 = no maximum.

## `minAreaSqft` (type: `integer`):

Keep only transactions at or above this floor area in square feet. 0 = no minimum.

## `maxAreaSqft` (type: `integer`):

Keep only transactions at or below this floor area in square feet. 0 = no maximum.

## `tenureFilter` (type: `string`):

Keep only Freehold or only Leasehold transactions.

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

Cap on transaction records returned across the run. Set to a large number for a full market pull (URA returns thousands of caveats for a typical multi-month, all-Singapore query).

## `resultsPerRequest` (type: `integer`):

How many transactions to pull per page request (20–500). Higher = fewer requests for big pulls.

## `deduplicate` (type: `boolean`):

Skip identical caveats already emitted earlier in the same run.

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

Remember which caveats were already returned and emit ONLY transactions not seen in previous runs. Pairs with Apify Schedules to track newly lodged caveats over time (it does not conflict with Schedules — Schedules decide when to run, this decides what is new).

## `monitorStoreName` (type: `string`):

Named key-value store that holds the 'already seen' transaction fingerprints for monitoring mode. Use a different name per tracked market to keep histories separate.

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

Proxy settings. The URA portal is a public Singapore government site read over standard Apify Proxy with automatic IP rotation; the default works well. Blocked requests retry automatically on a fresh IP.

## Actor input object example

```json
{
  "fromMonth": "",
  "toMonth": "",
  "propertyTypes": [],
  "saleTypes": [],
  "postalDistricts": [],
  "marketSegments": [],
  "projectNameContains": "",
  "streetContains": "",
  "minPrice": 0,
  "maxPrice": 0,
  "minPsf": 0,
  "maxPsf": 0,
  "minAreaSqft": 0,
  "maxAreaSqft": 0,
  "tenureFilter": "Any",
  "maxResults": 100,
  "resultsPerRequest": 200,
  "deduplicate": true,
  "monitorMode": false,
  "monitorStoreName": "ura-property-transactions-monitor",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All scraped URA transaction records in the default dataset. Switch between the Transactions, Pricing & size and By location views to focus the columns.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/ura-property-transactions-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/ura-property-transactions-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 '{}' |
apify call scrapesage/ura-property-transactions-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "URA Private Property Transactions Scraper - Singapore Caveats",
        "description": "Scrape official URA private residential transactions (caveats) for Singapore: transacted price, $PSF/$PSM, area, tenure, floor, district, market segment & sale type. Filter by period, type & price. No API key. Export to JSON, CSV or Excel.",
        "version": "0.1",
        "x-build-id": "mVM3KPjOlADgTUaWT"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapesage~ura-property-transactions-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapesage-ura-property-transactions-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~ura-property-transactions-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapesage-ura-property-transactions-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~ura-property-transactions-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapesage-ura-property-transactions-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": {
                    "fromMonth": {
                        "title": "From month (YYYY-MM)",
                        "type": "string",
                        "description": "Start of the transaction period, e.g. \"2025-07\". Leave blank to default to 6 months before the current month. URA publishes the actual transacted (caveat) prices, so the most recent weeks are still being lodged.",
                        "default": ""
                    },
                    "toMonth": {
                        "title": "To month (YYYY-MM)",
                        "type": "string",
                        "description": "End of the transaction period, e.g. \"2026-06\". Leave blank to default to the current month.",
                        "default": ""
                    },
                    "propertyTypes": {
                        "title": "Property types",
                        "type": "array",
                        "description": "Which private residential property-type groups to include. Leave empty for all four.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Landed (Non-Strata)",
                                "Strata Landed",
                                "Apartments & Condominiums",
                                "Executive Condominiums"
                            ],
                            "enumTitles": [
                                "Landed (Non-Strata)",
                                "Strata Landed",
                                "Apartments & Condominiums",
                                "Executive Condominiums"
                            ]
                        },
                        "default": []
                    },
                    "saleTypes": {
                        "title": "Sale types",
                        "type": "array",
                        "description": "New Sale (developer), Sub Sale (re-assignment before completion) or Resale (secondary market). Leave empty for all.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "New Sale",
                                "Sub Sale",
                                "Resale"
                            ],
                            "enumTitles": [
                                "New Sale",
                                "Sub Sale",
                                "Resale"
                            ]
                        },
                        "default": []
                    },
                    "postalDistricts": {
                        "title": "Postal districts (optional)",
                        "type": "array",
                        "description": "Keep only transactions in these URA postal districts (01–28). Leave empty for all of Singapore. e.g. 09 = Orchard/River Valley, 10 = Bukit Timah/Holland, 15 = Katong/East Coast, 19 = Hougang/Punggol/Sengkang.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "01",
                                "02",
                                "03",
                                "04",
                                "05",
                                "06",
                                "07",
                                "08",
                                "09",
                                "10",
                                "11",
                                "12",
                                "13",
                                "14",
                                "15",
                                "16",
                                "17",
                                "18",
                                "19",
                                "20",
                                "21",
                                "22",
                                "23",
                                "24",
                                "25",
                                "26",
                                "27",
                                "28"
                            ],
                            "enumTitles": [
                                "01 — Raffles Place / Marina",
                                "02 — Tanjong Pagar / Anson",
                                "03 — Queenstown / Tiong Bahru",
                                "04 — Telok Blangah / Harbourfront",
                                "05 — Pasir Panjang / Clementi",
                                "06 — City Hall / Beach Road",
                                "07 — Bugis / Golden Mile",
                                "08 — Little India / Farrer Park",
                                "09 — Orchard / River Valley",
                                "10 — Bukit Timah / Holland / Tanglin",
                                "11 — Novena / Newton / Thomson",
                                "12 — Balestier / Toa Payoh / Serangoon",
                                "13 — Macpherson / Braddell",
                                "14 — Geylang / Eunos / Paya Lebar",
                                "15 — Katong / East Coast / Marine Parade",
                                "16 — Bedok / Upper East Coast",
                                "17 — Loyang / Changi",
                                "18 — Tampines / Pasir Ris",
                                "19 — Hougang / Punggol / Sengkang",
                                "20 — Bishan / Ang Mo Kio",
                                "21 — Upper Bukit Timah / Clementi Park",
                                "22 — Jurong / Boon Lay",
                                "23 — Bukit Panjang / Choa Chu Kang",
                                "24 — Lim Chu Kang / Tengah",
                                "25 — Kranji / Woodlands",
                                "26 — Upper Thomson / Springleaf",
                                "27 — Yishun / Sembawang",
                                "28 — Seletar / Yio Chu Kang"
                            ]
                        },
                        "default": []
                    },
                    "marketSegments": {
                        "title": "Market segments (optional)",
                        "type": "array",
                        "description": "Keep only these URA market segments: CCR = Core Central Region (prime), RCR = Rest of Central Region (city fringe), OCR = Outside Central Region (suburban). Leave empty for all.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "CCR",
                                "RCR",
                                "OCR"
                            ],
                            "enumTitles": [
                                "CCR — Core Central Region",
                                "RCR — Rest of Central Region",
                                "OCR — Outside Central Region"
                            ]
                        },
                        "default": []
                    },
                    "projectNameContains": {
                        "title": "Project name contains (optional)",
                        "type": "string",
                        "description": "Keep only transactions whose project name contains this text (case-insensitive), e.g. \"the sail\", \"normanton\".",
                        "default": ""
                    },
                    "streetContains": {
                        "title": "Street name contains (optional)",
                        "type": "string",
                        "description": "Keep only transactions whose street name contains this text (case-insensitive), e.g. \"river valley\".",
                        "default": ""
                    },
                    "minPrice": {
                        "title": "Min transacted price (SGD)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only transactions at or above this price. 0 = no minimum.",
                        "default": 0
                    },
                    "maxPrice": {
                        "title": "Max transacted price (SGD)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only transactions at or below this price. 0 = no maximum.",
                        "default": 0
                    },
                    "minPsf": {
                        "title": "Min unit price ($PSF)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only transactions at or above this $ per square foot. 0 = no minimum.",
                        "default": 0
                    },
                    "maxPsf": {
                        "title": "Max unit price ($PSF)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only transactions at or below this $ per square foot. 0 = no maximum.",
                        "default": 0
                    },
                    "minAreaSqft": {
                        "title": "Min area (sqft)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only transactions at or above this floor area in square feet. 0 = no minimum.",
                        "default": 0
                    },
                    "maxAreaSqft": {
                        "title": "Max area (sqft)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only transactions at or below this floor area in square feet. 0 = no maximum.",
                        "default": 0
                    },
                    "tenureFilter": {
                        "title": "Tenure",
                        "enum": [
                            "Any",
                            "Freehold",
                            "Leasehold"
                        ],
                        "type": "string",
                        "description": "Keep only Freehold or only Leasehold transactions.",
                        "default": "Any"
                    },
                    "maxResults": {
                        "title": "Max results (transactions)",
                        "minimum": 1,
                        "maximum": 500000,
                        "type": "integer",
                        "description": "Cap on transaction records returned across the run. Set to a large number for a full market pull (URA returns thousands of caveats for a typical multi-month, all-Singapore query).",
                        "default": 100
                    },
                    "resultsPerRequest": {
                        "title": "Results per request",
                        "minimum": 20,
                        "maximum": 500,
                        "type": "integer",
                        "description": "How many transactions to pull per page request (20–500). Higher = fewer requests for big pulls.",
                        "default": 200
                    },
                    "deduplicate": {
                        "title": "Deduplicate transactions",
                        "type": "boolean",
                        "description": "Skip identical caveats already emitted earlier in the same run.",
                        "default": true
                    },
                    "monitorMode": {
                        "title": "Monitoring mode — only new transactions",
                        "type": "boolean",
                        "description": "Remember which caveats were already returned and emit ONLY transactions not seen in previous runs. Pairs with Apify Schedules to track newly lodged caveats over time (it does not conflict with Schedules — Schedules decide when to run, this decides what is new).",
                        "default": false
                    },
                    "monitorStoreName": {
                        "title": "Monitor store name",
                        "type": "string",
                        "description": "Named key-value store that holds the 'already seen' transaction fingerprints for monitoring mode. Use a different name per tracked market to keep histories separate.",
                        "default": "ura-property-transactions-monitor"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Proxy settings. The URA portal is a public Singapore government site read over standard Apify Proxy with automatic IP rotation; the default works well. Blocked requests retry automatically on a fresh IP.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
