99.co Singapore Property Listings Scraper
Under maintenancePricing
from $3.99 / 1,000 results
99.co Singapore Property Listings Scraper
Under maintenanceExtract detailed property listings from 99.co Singapore with comprehensive data including prices, locations, amenities, and agent information. Perfect for real estate analysis, market research, and property investment decisions.
Pricing
from $3.99 / 1,000 results
Rating
0.0
(0)
Developer
Coding Frontned
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
14 days ago
Last modified
Categories
Share
What does 99.co Singapore Property Listings Scraper do?
This Actor searches publicly displayed Singapore sale and rental listings on 99.co. Search by location or provide 99.co search URLs, apply property filters, and enrich selected listings with information shown on their public detail pages. It does not sign in or reveal protected contact information.
Public crawling rules are checked through the selected browser and proxy for search pages, pagination, and detail pages. Unavailable rules, access denial, and redirects to unchecked destinations stop the affected request. A requested proxy that cannot provide a route fails before navigation. Existing real listing results are kept if a later request fails; diagnostic records are never added to the dataset.
Why use this Actor?
Collect listing prices, property details, locations, source labels, images, and public agent and development information in a structured dataset. Use the records for market research, comparable listings, rental monitoring, or investment analysis. Apify scheduling, the API, integrations, run history, and monitoring are available for repeat workflows.
How to scrape 99.co
- Open the Actor's Input tab.
- Search all areas or enter Singapore locations, or paste one or more 99.co search URLs.
- Choose property filters and a result limit. Detail enrichment is enabled by default; turn it off if card data is enough.
- Click Start.
- Open Results for listing records. The Output summary link opens the separate run summary in the default key-value store.
When searchUrls contains URLs, they replace generated location searches. Each URL must use HTTPS on 99.co or www.99.co, point into a Singapore sale or rent search path, and not be a property-detail URL. Each direct URL determines its own sale or rent market. Otherwise, listingType and locations generate the searches; an empty locations list means all areas.
Price, bedroom, bathroom, and floor-area bounds are inclusive. A listing must have the relevant value to pass a bound on that value. Property-type filters are also checked against extracted listing cards. maxItems is the limit across the whole run; maxPages applies to each search URL. With deduplicate enabled, repeated listing URLs are saved once. The website's ordering is retained; there is no separate sort input. URLs prohibited by 99.co's published crawling rules are skipped. Use the input price and area filters with a permitted search URL when needed.
Input
The Input tab shows the full configuration. All fields are optional; omitted values use the defaults below.
Search settings
| Field | Type | Required? | Default | What it does |
|---|---|---|---|---|
listingType | Text: sale or rent | No | sale | Market used to build searches. A direct search URL determines its own market. |
searchUrls | List of text | No | [] | Direct 99.co search URLs. When non-empty, these replace generated location searches. Property-detail URLs are not accepted. |
locations | List of text | No | [] | Singapore locations or districts for generated searches. An empty list searches all areas. |
propertyTypes | List of text | No | [] | Optional property types such as HDB, Condo, Landed, or Room. These are also matched against extracted listing cards. |
Filters
All numeric filters are optional and inclusive. If a bound is set, records without the corresponding parsed value do not pass it. A minimum cannot exceed its matching maximum. minFloorArea and maxFloorArea apply to built-up floor area; land area is reported separately and is not filtered by these inputs.
| Field | Type and range | Required? | Default | What it does |
|---|---|---|---|---|
minPrice | Integer SGD, 0–9,007,199,254,740,991 | No | Not set | Minimum sale price or monthly rent. |
maxPrice | Integer SGD, 0–9,007,199,254,740,991 | No | Not set | Maximum sale price or monthly rent. |
minBedrooms | Integer, 0–20 | No | Not set | Minimum parsed bedroom count. |
maxBedrooms | Integer, 0–20 | No | Not set | Maximum parsed bedroom count. |
minBathrooms | Integer, 0–30 | No | Not set | Minimum parsed bathroom count. |
maxBathrooms | Integer, 0–30 | No | Not set | Maximum parsed bathroom count. |
minFloorArea | Integer sqft, 0–1,000,000 | No | Not set | Minimum built-up floor area. |
maxFloorArea | Integer sqft, 0–1,000,000 | No | Not set | Maximum built-up floor area. |
Result limits and included data
| Field | Type and range | Required? | Default | What it does |
|---|---|---|---|---|
maxItems | Integer, 1–1,000 | No | 50 | Maximum listings saved across the entire run. |
maxPages | Integer, 1–50 | No | 50 | Maximum result pages followed for each search URL. Crawling also stops when 99.co has no next page. |
includeDetails | Boolean | No | true | Open selected public listing pages for description, property and development details, amenities, EV charging, images, and public agent information. |
maxDetailItems | Integer, 0–1,000 | No | 50 | Maximum detail pages to open. The effective limit cannot exceed maxItems; use 0 to skip detail pages. |
includeImages | Boolean | No | true | Include collected image URLs, including detected floor plans and the agent photo. Image counts can still be included when URLs are disabled. |
includeTags | Boolean | No | true | Include available listing labels and description tags. |
Request behavior
| Field | Type and range | Required? | Default | What it does |
|---|---|---|---|---|
deduplicate | Boolean | No | true | Save a listing URL once across pages and search URLs. |
requestDelayMs | Integer milliseconds, 0–30,000 | No | 0 | Wait this long before later page and detail-page navigations. |
maxConcurrency | Integer, 1–5 | No | 1 | Maximum search pages processed at once. Lower values reduce concurrent requests and make the item limit more predictable. |
maxRequestRetries | Integer, 0–5 | No | 3 | Maximum retries for a failed search request. |
navigationTimeoutSecs | Integer seconds, 10–300 | No | 90 | Maximum time allowed for a page navigation. |
requestHandlerTimeoutSecs | Integer seconds, 30–600 | No | 180 | Maximum time allowed to process a search page and its requested detail pages. |
proxyConfiguration | Object | No | Runtime: not set; Console prefill: Apify Proxy with RESIDENTIAL and SG | Optional Apify Proxy or custom HTTP(S) proxy settings. Use either Apify Proxy or proxyUrls, not both. Groups and country require useApifyProxy: true. Proxy use may add account costs and does not bypass site restrictions. |
The optional proxyConfiguration object accepts useApifyProxy (Boolean), apifyProxyGroups (list of text), apifyProxyCountry (text), and proxyUrls (list of HTTP(S) URLs). Callers that omit it use no proxy. Keep proxy credentials private.
Copyable input examples
Search all areas for sale using the defaults, with a small result limit:
{"maxItems": 10,"maxPages": 1}
Filter rental listings by location, property type, price, and bedrooms:
{"listingType": "rent","locations": ["Tampines", "District 10"],"propertyTypes": ["Condo"],"minPrice": 2000,"maxPrice": 6000,"minBedrooms": 2,"maxBathrooms": 3,"maxItems": 25,"maxPages": 2}
Search multiple areas directly and remove repeated listings:
{"searchUrls": ["https://www.99.co/singapore/sale/areas/orchard","https://www.99.co/singapore/rent/areas/tampines"],"maxItems": 20,"maxPages": 2,"deduplicate": true}
Skip detail pages, image URLs, and tags:
{"listingType": "sale","locations": ["Orchard"],"maxItems": 10,"includeDetails": false,"includeImages": false,"includeTags": false}
Output
You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.
Each dataset row is one public property listing. url, listingId, title, and listingType are required; other fields are included when the source provides them. Detail values supplement card values, and missing detail values leave card values intact. A detail page is merged only when its identity matches the selected listing. If detail collection fails or the page does not match, the base listing is saved and the run summary marks the run partial when applicable.
listingPublishedText is the listing's displayed publication text, such as Listed 16 minutes ago; it is not the Actor's scrape time. priceQualifier preserves labels such as NEGO or STARTING PRICE. estimatedMonthlyMortgage and estimatedMortgageFormatted retain the mortgage estimate shown by 99.co; the Actor does not calculate this value. floorArea is built-up floor area; landArea is the land plot area, and each has a separate square-metre conversion. The floor-area filters apply only to built-up area. mrtStationCodes contains only source codes shown within 40 characters before the nearest MRT station label; no code is inferred. photoCount is the number of unique image URLs collected, not a total published by 99.co. floorPlanImageUrls contains unique floor-plan URLs actually detected, and floorPlanCount is emitted only when at least one is detected. videoUrls contains only public video/source URLs or recognized YouTube/Vimeo embeds found in the listing header or tour section, and is omitted when none are available. No video count is inferred. includeImages: false omits image URLs while retaining available counts. Agent phone text is kept as displayed, including masking; the Actor does not use contact or reveal controls.
The following complete example is illustrative; it is not a verified live listing. It shows all 61 supported business fields. Optional fields that do not apply are omitted in real records: lease terms and availability are normally found on rentals, while mortgage estimates are normally shown for sale listings.
{"url": "https://www.99.co/singapore/sale/property/example-landed-home-12345678","listingId": "12345678","title": "Example Landed Home, 3 Bed","listingType": "sale","propertyType": "Landed","price": 2100000,"priceFormatted": "S$2,100,000","estimatedMonthlyMortgage": 2538,"estimatedMortgageFormatted": "S$ 2,538/mo","pricePerSqft": 477,"pricePerSqftFormatted": "S$477 psf","bedrooms": 3,"bedroomsRaw": "3","bathrooms": 2,"bathroomsRaw": "2","floorArea": 4400,"floorAreaSqm": 408.77,"landArea": 6211,"landAreaSqm": 577.02,"address": "10 Example Avenue, Singapore 268000","district": "D10","region": "Central Region","postalCode": "268000","latitude": 1.3187,"longitude": 103.8106,"nearestMrt": "Example MRT","mrtStationCodes": ["DT29"],"mrtDistance": "5 mins (400 m)","tenure": "Freehold","floorLevel": "High floor","builtYear": 2020,"developer": "Example Development Pte Ltd","projectName": "Example Residences","furnishing": "Partially furnished","agentName": "Example Agent","agentPhone": "+65 XXXX XXXX","agencyName": "Example Realty","agentProfileUrl": "https://www.99.co/singapore/agents/example-agent-ExampleAgent","agentCredentials": "CEA: Example Registration","lastUpdated": "7 hours ago","description": "Illustrative description of a three-bedroom apartment near public transport.","imageUrls": ["https://images.example.test/property/example-1.jpg","https://images.example.test/property/example-2.jpg","https://images.example.test/floor-plans/example-1.jpg"],"thumbnailUrl": "https://images.example.test/property/example-1.jpg","photoCount": 3,"floorPlanCount": 1,"tags": ["Near MRT Station", "High Floor"],"unitTypes": "2, 3 and 4 bedroom units","totalUnits": 150,"neighbourhood": "Example District","developmentUrl": "https://www.99.co/singapore/condos-apartments/example-residences","amenities": ["Lap pool", "Gym", "Parking"],"evCharging": [{"operator": "Example Charge","chargingOptions": ["AC 7.4kW · Slow"],"connectorCount": 4}],"facing": "North","overlookingView": "Greenery view","leaseTerm": "Flexible","availableFrom": "01 Nov '26","listingPublishedText": "Listed 16 minutes ago","priceQualifier": "NEGO","agentImageUrl": "https://images.example.test/agents/example-agent.jpg","floorPlanImageUrls": ["https://images.example.test/floor-plans/example-1.jpg"],"videoUrls": ["https://video.example.test/property/example-tour.mp4"]}
Required listing fields
| Field | Type | Meaning |
|---|---|---|
url | HTTPS URL | Public 99.co sale or rent listing URL. The listing ID at the end of the URL must match listingId. |
listingId | Text | Listing identifier parsed from the public listing URL. |
title | Text | Listing title shown on the card or detail page. |
listingType | Text: sale or rent | Whether the listing is offered for sale or rent. |
Optional listing fields
| Field | Type | Meaning |
|---|---|---|
propertyType | Text | Property category, such as Condo or HDB. |
price | Number, SGD | Parsed sale price or monthly rent. |
priceFormatted | Text | Price as rendered by 99.co. |
priceQualifier | Text | Source label such as NEGO or STARTING PRICE, when shown. |
estimatedMonthlyMortgage | Number, SGD/month | Monthly estimate displayed by 99.co; the Actor does not calculate it. |
estimatedMortgageFormatted | Text | Mortgage-estimate price component exactly as displayed by 99.co. |
pricePerSqft | Number | Parsed price per square foot. |
pricePerSqftFormatted | Text | Price-per-square-foot text as displayed. |
bedrooms | Number | Parsed bedroom count. |
bedroomsRaw | Text | Bedroom token as displayed, including layouts such as 3+1. |
bathrooms | Number | Parsed bathroom count. |
bathroomsRaw | Text | Bathroom count as displayed. |
floorArea | Number, sqft | Built-up floor area in square feet; separate from land plot area. |
floorAreaSqm | Number, sqm | Built-up floor area converted to square metres. |
landArea | Number, sqft | Land plot area in square feet; separate from built-up floor area. |
landAreaSqm | Number, sqm | Land plot area converted to square metres. |
address | Text | Address or public location text for the listing. |
district | Text | Singapore district label, when shown or derived from a public postal code. |
region | Text | Public planning-area or region text from the detail page. |
postalCode | Text | Public six-digit Singapore postal code, when shown. |
latitude | Number | Public latitude from structured listing data. |
longitude | Number | Public longitude from structured listing data. |
nearestMrt | Text | Nearest MRT station text shown on the listing card. |
mrtStationCodes | List of text | Source station codes displayed within 40 characters before the nearest MRT label; no codes are inferred. |
mrtDistance | Text | Walking-time and distance text shown for the nearest MRT station. |
tenure | Text | Tenure text such as Freehold or 99-year Leasehold. |
floorLevel | Text | Floor-level description from the detail page. |
builtYear | Integer | Property or development completion year. |
developer | Text | Public development developer name. |
projectName | Text | Project or development name associated with the listing. |
furnishing | Text | Furnishing status shown on the detail page. |
agentName | Text | Public listing agent name. |
agentPhone | Text | Public phone text exactly as displayed, including any masking. Contact or reveal controls are not used. |
agencyName | Text | Public agency or brokerage name associated with the agent. |
agentProfileUrl | HTTPS URL | Public 99.co agent profile URL. |
agentCredentials | Text | Public professional credential text, such as a CEA label. |
agentImageUrl | HTTPS URL | Public agent photo URL, when available. |
lastUpdated | Text | Last-updated text from the listing's property details. |
description | Text | Public listing description collected from the detail page. |
imageUrls | List of HTTPS URLs | Unique public listing image URLs collected from the card or detail page. |
thumbnailUrl | HTTPS URL | First available listing image URL. |
photoCount | Integer | Number of unique image URLs collected; not a source-published total. |
floorPlanImageUrls | List of HTTPS URLs | Unique floor-plan image URLs actually detected on the listing; omitted when none are detected or images are disabled. |
videoUrls | List of HTTPS URLs | Public video/source or recognized YouTube/Vimeo embed URLs from this listing's header or tour section; omitted when none are shown. |
floorPlanCount | Integer | Number of unique detected floor-plan URLs; omitted when none are detected. |
listingPublishedText | Text | Publication text shown on the card, such as Listed 16 minutes ago; not scrape time. |
tags | List of text | Public 99.co labels and descriptive tags. |
unitTypes | Text | Development unit-type summary shown on the detail page. |
totalUnits | Integer | Total development units shown on the detail page. |
neighbourhood | Text | Public neighbourhood or planning-area label. |
developmentUrl | HTTPS URL | Public 99.co development page URL. |
amenities | List of text | Labels in this listing's Amenities section. |
evCharging | List of objects | Operators and published charging options in this development's EV Charging section. |
facing | Text | Facing direction exactly as shown in property details. |
overlookingView | Text | View description exactly as shown in property details. |
leaseTerm | Text | Published rental lease-term text; no duration is inferred. |
availableFrom | Text | Availability date text from the listing header, retaining the source format. |
Each evCharging object has a required operator, plus optional chargingOptions (list of text) and connectorCount (nonnegative integer). A missing connector count is omitted. Published charging options do not establish pricing or exclusive access for the listed unit.
Run summary
The separate Output summary link opens OUTPUT_SUMMARY in the run's default Key-value store. It is not a dataset row and contains exactly these three fields:
| Field | Type | Required? | Meaning |
|---|---|---|---|
status | Text: SUCCEEDED or FAILED | Yes | Whether at least one listing write completed. |
itemsStored | Nonnegative integer | Yes | Number of validated listing records whose dataset writes completed. |
isPartial | Boolean | Yes | true when collection or requested detail enrichment failed after at least one listing was saved. |
Example:
{"status": "SUCCEEDED","itemsStored": 25,"isPartial": false}
A run with no saved listings has status: "FAILED", itemsStored: 0, and isPartial: false. A detail failure can leave usable listings in the dataset and set isPartial to true.
Tips and limitations
Start with small maxItems and maxPages values. Detail pages add browser navigations, so turn off includeDetails when card data is enough. Use maxDetailItems to cap enrichment while retaining the search results. The source may deny or challenge automated access; this Actor does not bypass those controls.
With proxies enabled, robots rules and public pages use the same browser proxy and cookies. The rules are checked before the first search, pagination, and detail pages. If the rules cannot be read, the affected page is skipped. A proxy changes the connection route; it does not guarantee access. Singapore residential proxies are a useful starting option for Singapore listings, and the proxy group and country can be changed using the existing proxyConfiguration input.
Cost, support, and responsible use
Run costs depend on pages visited, browser work, detail requests, retries, concurrency, and proxy use. No fixed cost is promised; check the usage for your run and the Actor's pricing details. For programmatic access, see the Actor's API tab. For questions or feature requests, use the Actor's Issues tab and include a run ID and a short description when possible.
The Actor collects publicly displayed listing and agent information. Results may contain personal data, so use them only for a legitimate purpose and follow applicable privacy rules and local law. Do not use contact information for unlawful or unwanted outreach. This Actor is not affiliated with 99.co. Follow the site's terms, robots guidance, and rate limits.