apify-propertyguru-sg-client
Singapore property listings from PropertyGuru — price, address, district, agent contact, 40+ fields per listing.
Python client for the rl1987/propertyguru-sg-api-scraper Apify Actor. No local scraping, no proxy management, no anti-bot maintenance — the Actor runs on Apify's infrastructure and this package just starts it, waits, and hands you back the dataset as plain Python dicts.
Install · Quickstart · Getting an API token · Input reference · Output fields · Error handling · Pricing · Async / long-running runs · Links
Install
pip install apify-propertyguru-sg-client
Requires Python 3.9+. Only dependency is requests.
Quickstart
from apify_propertyguru_sg_client import PropertyGuruSGClient
client = PropertyGuruSGClient(api_token="apify_api_...") # see "Getting an API token" below
items = client.run({"location": "Orchard", "listingType": "sale", "maxItems": 20})
for item in items:
print(item)
Real output from the example above (trimmed to a few fields):
{"title": "Well maintained unit", "price": 7999000, "district": "Orchard / River Valley", "listingUrl": "https://www.propertyguru.com.sg/listing/for-sale-orchard-view-60186981"}
run() blocks until the Actor finishes (usually a few seconds to ~30s depending on maxItems) and returns a plain list[dict] — the Actor's dataset, one dict per result row.
Getting an API token
-
Sign up for a free account at console.apify.com.
-
Go to Settings → Integrations and copy your Personal API token.
-
Pass it to the client:
PropertyGuruSGClient(api_token="..."), or read it from an environment variable:import os client = PropertyGuruSGClient(api_token=os.environ["APIFY_TOKEN"])
Never hardcode the token in source control — use an environment variable or secrets manager.
Input reference
run() takes a single dict matching the Actor's input schema. Full/authoritative schema: the Input tab on the Actor's Apify page.
| Field | Type | Default | Description |
|---|---|---|---|
location |
str | — | Area/neighbourhood name, e.g. "Orchard". Ignored when districtCode is set. |
districtCode |
str | — | Precise district, e.g. "D09". Overrides location. |
listingType |
str | "sale" |
"sale" or "rent". |
propertyType |
str | — | e.g. "hdb", "condo", "apartment", "terrace", "semi-detached", "landed". |
minPrice / maxPrice |
int | — | Price range in SGD. |
bedrooms |
int | — | Exact bedroom count. |
maxItems |
int | 100 |
0 = unlimited. |
includeDetails |
bool | False |
Fetch all photos, videos, floor plans, full agent contact per listing. |
Output fields
Each dict in the returned list is one row from the Actor's dataset. Common fields:
title, price, pricePretty, address, district, beds, baths, floorArea, propertyType, tenure, agentName, agentMobile, agencyName, listingUrl, images, postedDate.
Exact field availability can vary by input flags (see table above) — treat unfamiliar/missing keys as optional and use .get() rather than [...] indexing.
Error handling
from apify_propertyguru_sg_client import PropertyGuruSGClient, ApifyActorError
import requests
client = PropertyGuruSGClient(api_token="...")
try:
items = client.run({"location": "Orchard", "listingType": "sale", "maxItems": 20})
except ApifyActorError as e:
# The Actor run itself failed, timed out, or was aborted on the Apify side.
print(f"Actor run did not succeed: {e}")
except requests.HTTPError as e:
# Bad token, malformed input, rate limiting, etc. — an HTTP-level error
# calling the Apify API (not the Actor run).
print(f"Apify API request failed: {e}")
ApifyActorError is raised when the run reaches a terminal non-success status (FAILED, TIMED-OUT, ABORTED) or doesn't finish within timeout_secs (default 300s — raise it for run() calls with a large maxItems, e.g. PropertyGuruSGClient(api_token="...", timeout_secs=900)).
Pricing
Pay-per-event: $0.001/listing row. No subscription — see the Actor's pricing tab for current rates. Apify also includes a free monthly usage tier that covers light use.
Advanced: longer timeouts & polling
client = PropertyGuruSGClient(api_token="...", timeout_secs=900) # allow up to 15 min
items = client.run(actor_input, poll_interval_secs=3.0) # poll less aggressively
Links
- PropertyGuru Singapore API Scraper on Apify — Actor page, input schema, pricing
- PyPI package
- Apify API reference — what this client wraps under the hood
License
MIT
Metadata
Release files for apify-propertyguru-sg-client 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| apify_propertyguru_sg_client-0.1.1.tar.gz | 7.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| apify_propertyguru_sg_client-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.6 kB
Release files / apify_propertyguru_sg_client-0.1.1.tar.gz
| Download URL | apify_propertyguru_sg_client-0.1.1.tar.gz |
|---|---|
| Size | 7.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
02d1c7c5d372e3fa33e31581cb799d9e132ff6a18efed4f904fcf7f436954493
|
|
BLAKE2b-256 checksum How to use checksums |
2715a50745842006422920635e2c1c1844ea33298f5f1f05bf39bdf3256b04d0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.0
|
Release files / apify_propertyguru_sg_client-0.1.1-py3-none-any.whl
| Download URL | apify_propertyguru_sg_client-0.1.1-py3-none-any.whl |
|---|---|
| Size | 7.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5a6250a9267e0936e8ecfbafb07aebb88f159dcd19d9dca9169892ca4f28a1a
|
|
BLAKE2b-256 checksum How to use checksums |
e9bf2264de1ce85d843a4a1d5ef193cd7b847b5b222e5fe6d059457e2cffab8e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.0
|