99.co Singapore Property Listings Scraper
Pricing
from $2.00 / 1,000 property listings
99.co Singapore Property Listings Scraper
Scrape Singapore property from 99.co — HDB, condo, landed and commercial, for sale or rent. Price, PSF, floor area, beds, baths, tenure, TOP year, coordinates, nearest MRT, photos and agent phone/WhatsApp. Breaks past 99.co's 10,000-result cap to reach all 48,000+ listings. No proxy needed.
Pricing
from $2.00 / 1,000 property listings
Rating
0.0
(0)
Developer
Elena Vance
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Scrape Singapore property listings from 99.co — HDB flats, condos, landed homes and commercial space, for sale or for rent. Every row carries price, price per square foot, floor area, bedrooms, bathrooms, tenure, completion year, coordinates, nearest MRT with walking time, photos, and the listing agent's phone and WhatsApp.
It reaches listings other 99.co scrapers cannot. 99.co refuses to serve more than 10,000 results for any one search, so a conventional scraper tops out at 10,000 of the 48,000+ sale listings — and cannot tell that it stopped short. This one splits the search by postal district automatically and retrieves all of them.
No API key, no login, no residential proxy, no browser.
What you get
One row per listing. A real sample, from a District 15 condo run:
| projectName | district | price | psf | sqft | beds | tenure | nearest MRT | walk | agent | phone |
|---|---|---|---|---|---|---|---|---|---|---|
| Tembusu Grand | 15 | 7,888,000 | 2,931 | 2,691 | 5 | 99 yrs | Tanjong Katong MRT | 10 min | Paramjit Kaur | +6590091172 |
| The Waterside | 15 | 6,500,000 | 2,709 | 2,399 | 4 | Freehold | Katong Park MRT | 5 min | Vivien | +6593859960 |
| The Line @ Tanjong Rhu | 15 | 5,000,000 | 1,689 | 2,960 | 3 | Freehold | Katong Park MRT | 3 min | Jamie Yoeng | +6589893212 |
Plus, on every row: postal code, street number and name, both address lines, latitude/longitude, floor area in sqm, HDB flat model, photo count, floor-plan count, video tour URL, virtual-tour flag, 99.co's verification badges, posting time, and the cluster id that joins to 99.co's project data.
Export as JSON, CSV, Excel or XML.
Why this is cheap to run
99.co's Cloudflare wall is a TLS-stack gate, not a JavaScript challenge. Presenting Chrome's TLS fingerprint clears it outright — which means this Actor needs no browser and no residential proxy:
| This Actor | Typical 99.co scraper | |
|---|---|---|
| Runtime | Plain HTTP client | Headless browser, or residential proxy |
| Memory | 256 MB | 2,048–4,096 MB |
| Start fee | $0.00005 | up to $0.10 |
| Proxy cost | none | ~$8/GB residential |
apify-actor-start is billed once per gigabyte, so a 4 GB Actor charges its
start fee four times before returning a single row. This one charges it once.
A default 100-listing run finishes in under 3 seconds using one HTTP request. A 3,000-listing run takes 21 seconds and peaks at 103 MB.
What makes this different
It gets past the 10,000-result cap. page_num × page_size must be ≤ 10,000
or 99.co answers HTTP 400. That 400 looks exactly like a transient error, so a
naive scraper reports success having collected 21% of the market. Ask this
Actor for more than the cap allows and it partitions the search by postal
district — 28 disjoint queries whose counts sum to the full corpus — then by
property type and price band if a district ever outgrows the window too. On
smaller runs nothing is split, so you never pay for the machinery you don't need.
It separates room rentals from whole units. 99.co's rental feed mixes them,
and rooms are 46% of it (10,364 of 22,570). Averaging a S$900 room in with
S$5,000 condos makes rent and PSF figures meaningless. rentalType picks one,
and every row states which it is.
It never charges you twice for the same listing. Listing ids are de-duplicated across the entire run, before billing, not after — a live marketplace re-orders itself between requests, and a 6,000-listing test run suppressed 204 duplicates that a naive pager would have billed for.
It tells you when it could not finish. If a search genuinely cannot be narrowed below the cap, the run says so in its status message instead of quietly returning a short dataset.
Input
Everything is optional — running with no input at all returns 100 listings for sale across Singapore.
| Field | Description |
|---|---|
listingType | sale or rent. Default sale. |
propertyType | all, condo, hdb or landed. |
districts | Postal districts, e.g. ["D9", "D10", "D11"]. Empty means all of Singapore. |
searchUrl | Paste a 99.co search URL and its filters are read out of it. |
maxItems | How many listings to return. Default 100. |
minPrice / maxPrice | Total price for sale, monthly rent for rentals. |
bedrooms | Multi-select, 0 (studio) to 7. |
bathrooms | Minimum bathroom count. |
tenure | freehold, 999, 99. |
furnishing | fully, partial, unfurnished. |
rentalType | whole_unit or room. Rentals only. |
propertySegment | residential or commercial (offices, retail, industrial). |
minFloorAreaSqft / maxFloorAreaSqft | Applied locally — 99.co has no floor-area filter. |
newLaunchOnly | Restrict to new-launch projects. |
includeAgentContacts | Agent name, phone, WhatsApp. Default on. |
includePhotoGallery | Every photo with caption and room category. Default off. |
completeCoverage | Split past the 10,000 cap. Default on. |
maxRunSecs | Time budget. The run stops cleanly and keeps what it has. |
Example runs
Every 3-bedroom condo in the prime districts over S$3M
{"listingType": "sale","propertyType": "condo","districts": ["D9", "D10", "D11"],"bedrooms": ["3"],"minPrice": 3000000,"maxItems": 500}
Whole-unit rentals only, fully furnished, near an MRT
{"listingType": "rent","rentalType": "whole_unit","furnishing": ["fully"],"maxItems": 300}
The entire sale market — all 48,000+ listings
{ "listingType": "sale", "maxItems": 50000, "maxRunSecs": 3600 }
This is the run that needs district partitioning; it happens automatically.
Agent lead list for one district
{ "districts": ["D19"], "includeAgentContacts": true, "maxItems": 2000 }
What this Actor does NOT return
Said plainly, because competing 99.co Actors advertise some of it:
- Agent agency name, CEA licence number, email or transaction counts. 99.co's agent endpoint exists but will not resolve the agent ids its search results carry, and the agent profile pages are behind the Cloudflare wall that the JSON API is not. Rather than guess, these fields are absent. You get the agent's name, phone, WhatsApp and 99.co's badge flags.
- Sorted results. 99.co accepts no sort parameter at all — eleven spellings were tested and every one was ignored. Results arrive in 99.co's own relevance order. Sort the dataset yourself; because coverage is complete, sorting it is meaningful.
- Server-side floor-area filtering. There is no such parameter, so
minFloorAreaSqft/maxFloorAreaSqftare applied after fetching. Listings that state no floor area are kept, not dropped — an absent area is not evidence of not matching. - Price history or past transactions. 99.co's search API carries only the current asking price.
- Indonesia and Malaysia. Singapore only.
Notes on the data
posted_atis converted from 99.co's microsecond epoch to ISO-8601 UTC.tenureandcompletedYearare routinelynullon landed property. That is 99.co's data, not a parsing failure.subCategoryis sometimes the literal string"unknown". It is passed through rather than nulled, so you can tell "99.co says unknown" from "99.co said nothing".marketSegment(CCR/RCR/OCR) anddistrictNameare derived from the district number using URA's convention; 99.co does not return them.- Totals drift by a few listings over the course of a long run. It is a live marketplace.
Related
clusterId on every row is the join key to 99.co's project data — feed it to
the 99.co Project & Condo Profile Scraper for building specifications,
price ranges per bedroom type, and nearby amenities with walking and driving
times.
Legal
This Actor collects publicly available listing data. Agent phone and WhatsApp numbers are business contact details that agents publish on their own listings so that buyers can contact them. You are responsible for using the data in compliance with applicable law, including Singapore's PDPA and the GDPR where it applies, and with 99.co's terms. Do not use it for unsolicited bulk messaging where that is prohibited.