99.co Scraper - Singapore & Indonesia Property Listings avatar

99.co Scraper - Singapore & Indonesia Property Listings

Pricing

from $2.50 / 1,000 listings

Go to Apify Store
99.co Scraper - Singapore & Indonesia Property Listings

99.co Scraper - Singapore & Indonesia Property Listings

Extract 99.co property listings in Singapore and Indonesia: prices, floor areas, photos and available agent contacts. Pay per delivered listing row plus a start fee; platform usage is separate.

Pricing

from $2.50 / 1,000 listings

Rating

0.0

(0)

Developer

kane liu

kane liu

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

0

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

99.co Scraper

Extract property listings from 99.co in Singapore and Indonesia as structured rows you can export and compare.

  • Sale and rental listings for homes, rooms and commercial property.
  • Asking prices, floor areas, bedrooms, bathrooms and listing links.
  • Available agent contacts, agency details, photos and Singapore MRT information.
  • Search by market and property type, use Singapore locations, or supply 99.co URLs.
  • Pay $2.50 per 1,000 delivered rows plus a small start fee; platform usage is separate under the current configuration.

What does 99.co Scraper do?

99.co Scraper collects listings from www.99.co/singapore and www.99.co/id. It has one search mode, selected automatically from the target fields you fill. Each row represents one property listing with rowType: "listing"; agent information enriches that row rather than creating another billed row.

  • Singapore: HDB flats, condos, executive condos, landed homes, room rentals, offices, retail and industrial property.
  • Indonesia: houses (rumah), apartments (apartemen), shop-houses (ruko), land (tanah) and other categories in the input form.
  • URL input: search pages, individual listings and supported project pages.
  • Optional details: scrapeDetails is off by default. scrapeAgentProfile is on by default and adds available Singapore agent email and agency information to listing rows.

What data can you extract from 99.co?

The table describes listing rows. Examples are illustrative, not a live sample. Availability varies by market, listing and detail settings.

FieldDescriptionExample
idListing identifierexample-SG-001
urlLink to the listinghttps://www.99.co/singapore/sale/property/example-SG-001
sourceCountryMarket codeSG
channelSale or rental selectionBUY
propertyTypeProperty category returned by the sourcecondo
titleListing headlineExample condominium
descriptionListing description when collectedTwo-bedroom apartment
priceNumeric asking price when available1500000
priceCurrencyCurrency of the asking priceSGD
pricePeriodPrice periodtotal
pricePsfPrice per square foot when shown1500
bedroomsBedroom count or source display label2
bathroomsBathroom count when available2
floorAreaSqftFloor area in square feet1000
floorAreaSqmFloor area in square metres92.9
tenureOwnership tenure when shownFreehold
builtYearCompletion year when available2015
furnishingStatusFurnishing information when shownFully furnished
mrtSingapore station, walking time and distance{"name":"Newton MRT","walkMinutes":8}
addressAvailable property address components{"full":"123 Example Street"}
geoCoordinates when available{"lat":1.30,"lng":103.83}
personAgent identity{"name":"Jane Doe","role":"agent"}
orgAgency information{"name":"Example Agency"}
phonesAvailable phone numbers and types[{"value":"+1 555 0100","type":"mobile"}]
emailsAvailable contact emails[{"value":"name@example.com","type":"email"}]
webAvailable website and social links{"website":null,"socials":[]}
media.photosUp to 20 photo URLs[]
listingTagsTags shown on the listing[]
leadAbsencesReasons for missing contact fields{}
scrapedAtCollection timestamp2026-10-24T08:00:00+00:00

Room counts can retain display strings such as 3+; do not assume every value is an integer. leadAbsences uses source-supported reason codes: 本站无 means unavailable on the site, 闸门锁 means access is restricted, and 未验证 means not verified.

How to scrape 99.co

  1. Open 99.co Scraper in Apify Console.
  2. Fill a target such as market, location or startUrls.
  3. Set maxItems to a small number such as 3.
  4. Click Start and wait for completion.
  5. Download the dataset or read it through the Apify API.

An empty input starts the form's Singapore condo-sale example with up to 3 rows. This is a billed example, not a free preview. Filling only filters such as channel or price also invokes the example when no target is present. Filling one target selects the search mode automatically.

Search with markets and filters

Use market: "SG" or market: "ID", then select a property type and channel. Non-empty markets and propertyTypes replace their singular counterparts. In Singapore, propertyType: "all" searches residential homes, not every commercial category. In Indonesia, all searches the available categories within the row allowance.

Use query for Singapore text search or location for an area such as bedok. locations accepts several areas and combines with location; a resolved location takes precedence over the text query. These location and text filters do not apply to Indonesia.

Search with URLs

Put 99.co search, listing or project URLs in startUrls. They replace the searches built from market and category selections. Prefer canonical www.99.co URLs. For Singapore price, room and location filtering, use the input fields rather than assuming every search-URL query parameter is preserved.

What to fill in

FieldWhat to enterDefault
startUrls99.co page URLs, as strings or objects with urlEmpty; example URL in form
marketSG, ID or allSG when omitted
marketsSeveral market codes; replaces marketEmpty
propertyTypeA category such as condo, hdb, rooms or rumahcondo when omitted
propertyTypesSeveral categories; replaces propertyTypeEmpty
channelBUY or RENTBUY
querySingapore place, project or keywordEmpty
locationSingapore area or region, such as bedok or east-regionEmpty
locationsSeveral Singapore areas; combines with locationEmpty
maxItemsRows per URL or selected market, from 1 to 5,00070; form example 3
roomsSingapore bedroom count, from 0 to 20Unset
priceMinMinimum Singapore asking price in SGDUnset
priceMaxMaximum Singapore asking price in SGDUnset
floorAreaMinMinimum Singapore floor area in square feetUnset
floorAreaMaxMaximum Singapore floor area in square feetUnset
tenureSingapore freehold or 99-year tenureUnset
furnishingSingapore fully, partial or unfurnishedUnset
sortSingapore relevance, price,asc, price,desc or floorarea,descUnset
supplyModeLeave as search; URL type determines collectionsearch
scrapeDetailsAdd available listing details to each rowfalse
scrapeAgentProfileAdd available Singapore agent email and agencytrue
maxPagesAdvanced page setting; not a reliable run-wide cap; use maxItems1
requestDelayMillisDelay between applicable page loads, in milliseconds2000

Singapore HDB rental search:

{
"market": "SG",
"channel": "RENT",
"propertyType": "hdb",
"location": "bedok",
"maxItems": 3
}

Indonesia apartment search:

{
"market": "ID",
"channel": "BUY",
"propertyType": "apartemen",
"maxItems": 3
}

URL search:

{
"startUrls": [{"url": "https://www.99.co/singapore/sale/condos-apartments"}],
"maxItems": 3
}

maxItems is the canonical row limit. maxResults and limit are aliases; an alias wins when maxItems is absent or still 70. An explicit non-default maxItems wins instead.

Unknown fields do not fail the run: close misspellings can be corrected, and other unknown fields are ignored with a note. Unsupported filter values can also be ignored. Check the default key-value store's INPUT_REPORT record for corrections, ignored fields and example-run selection.

Input rejected before collection produces a field-specific message such as INVALID_INPUT: startUrls — use 99.co page URLs. No listing rows are charged in that case; the start event still applies. Not every collection error is an input error.

Output example

This illustrative Singapore row uses placeholder identifiers and contact information.

{
"rowType": "listing",
"id": "example-SG-001",
"url": "https://www.99.co/singapore/sale/property/example-SG-001",
"source": "99.co",
"sourceCountry": "SG",
"channel": "BUY",
"propertyType": "condo",
"title": "Example condominium",
"price": 1500000,
"priceCurrency": "SGD",
"pricePeriod": "total",
"bedrooms": 2,
"bathrooms": 2,
"floorAreaSqft": 1000,
"phones": [{"value": "+1 555 0100", "type": "mobile"}],
"emails": [{"value": "name@example.com", "type": "email"}],
"person": {"name": "Jane Doe", "role": "agent"},
"org": {"name": "Example Agency", "type": "agency"},
"geo": null,
"media": {"photos": []},
"scrapedAt": "2026-10-24T08:00:00+00:00"
}

Export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table. OUTPUT and RUN_SUMMARY provide counts and warnings; ERROR_SUMMARY records failures when available.

Why use this 99.co scraper?

  • Row-based charges: listing charges apply to delivered rows, not attempted pages.
  • Usable partial output: rows already written to the dataset remain available after a stop or timeout. Stopping before delivery can leave an empty dataset.
  • Missing values stay missing: absent contact details or property attributes are not invented.
  • Several inputs: combine URLs or markets, with a row limit for each and a spending cap for the run.
  • No proxy setup: you do not need to set up proxies.

How much does it cost to scrape 99.co?

The start event costs $0.005 per GB of run memory, with a minimum of one event. At the default 512 MB, one start costs $0.005. Each delivered listing row costs $0.0025.

Apify planStart at 512 MBPrice per rowPrice per 1,000 rows
Free$0.005$0.0025$2.50
Starter$0.005$0.0025$2.50
Scale$0.005$0.0025$2.50
Business$0.005$0.0025$2.50

These are event charges. Platform usage is billed separately under the current Actor pricing configuration.

  • maxItems applies to each start URL, or each selected market without URLs. Property types and locations share that input's allowance.
  • The default is 70 rows per input; larger allowances are collected in parts of 70.
  • Free-plan runs are capped at 200 rows in total and 10 runs of this Actor. These limits are set by the publisher.
  • Set Maximum cost per run (maxTotalChargeUsd in the API) to cap event charges across the whole run. It is not an additional row allowance for each category.

Example: two URLs delivering 3 rows each produce 6 rows. At 512 MB, event charges are 6 × $0.0025 + $0.005 = $0.020, plus platform usage. Fewer delivered rows mean fewer row charges.

What happens when the run timeout is too short

Some 99.co collections, such as several startUrls or markets with scrapeDetails: true or a large maxItems, can take longer than the run timeout you chose. In that case the run does not fail. It ends early with the status message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." and shows as ABORTED for a while.

When the results are ready, the same run starts again by itself, reports "Resumed: delivering N rows.", writes the rows to the same dataset and finishes as SUCCEEDED. Rows that were already delivered are skipped, so no row is delivered or charged twice. You do not need to start another run.

  • This can happen at most 3 times per run. To avoid it, keep the default timeout of 3600 seconds.
  • The synchronous API endpoints (run-sync, run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset while the run is paused. For larger jobs, start the run asynchronously and read the dataset after the run reaches SUCCEEDED, or use a webhook on the "succeeded" event.

Use with AI agents and the API

Apify MCP server

Add this Actor to a remote MCP client such as Claude, ChatGPT, Cursor or VS Code:

https://mcp.apify.com?tools=lentic_clockss/ninetynine-co-sg-scraper

Sign in with Apify through OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns run and dataset IDs; the agent can read the rows with get-dataset-items.

For clients without remote MCP support, run npx @apify/actors-mcp-server --tools lentic_clockss/ninetynine-co-sg-scraper with APIFY_TOKEN set.

Example prompt: “Collect up to 3 Singapore HDB rental listings in Bedok using market: SG, channel: RENT, propertyType: hdb, location: bedok and maxItems: 3.”

Apify API

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lentic_clockss/ninetynine-co-sg-scraper").call(
run_input={"market": "SG", "propertyType": "hdb", "maxItems": 3}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row)
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('lentic_clockss/ninetynine-co-sg-scraper')
.call({ market: 'SG', propertyType: 'hdb', maxItems: 3 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

For HTTP, send JSON input to POST https://api.apify.com/v2/acts/lentic_clockss~ninetynine-co-sg-scraper/runs with an Authorization: Bearer <YOUR_APIFY_TOKEN> header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.

Integrations

Use the Actor's Integrations tab to connect results to Google Sheets, Make, Zapier, n8n, Slack, Airtable or a webhook. Use Apify Schedules for recurring runs.

FAQ

Public availability is not blanket permission to reuse data. You are responsible for the site's terms and applicable data protection law. Processing personal contact information requires a lawful basis; obtain legal advice for your use case if needed.

Why did my run end as ABORTED?

The run was stopped before normal completion. Check its status message and log for the reason; the status alone does not establish whether any rows were delivered. Inspect the dataset before rerunning. Do not assume it will restart automatically.

How many results can I get?

maxItems accepts 1–5,000 rows per input, subject to available listings, spending limits and the free-plan cap. It is a ceiling, not a promise that the site has that many matching listings.

Why are some fields empty?

Not every listing exposes every field. Details are off by default, public agent profiles may omit email, and Indonesia phone numbers may be masked. Inspect leadAbsences where provided.

How do I scrape room rentals or commercial property?

For Singapore rooms, use channel: "RENT" and propertyType: "rooms". For commercial searches, choose offices, retail, industrial, warehouse, shophouse or commercial. The categories rooms and Indonesia's kios are rental-only.

Why did my free-plan run stop after 10 runs?

The publisher limits free-plan users to 10 runs of this Actor. RUN_SUMMARY reports FREE_TIER_LIMIT when the allowance is exhausted. Paid plans are not subject to that publisher run-count limit.

What if a search returns zero rows?

Check the market, category and URL, then inspect OUTPUT or RUN_SUMMARY for warnings. A confirmed empty search can succeed; a collection failure is not proof that no listings exist.

Do I need a 99.co API key?

No 99.co API key is an input. Use an Apify account for Console runs and an Apify token for API access.

Limitations

  • Only 99.co Singapore and Indonesia are covered, not sister brands on other domains.
  • Singapore text, location, price, bedroom, area, tenure, furnishing and sort filters are not applied to Indonesia searches.
  • maxPages does not reliably limit current Actor pagination; use maxItems and a spending cap.
  • Unresolved Singapore locations are skipped with a warning, so review the summary before treating results as location-filtered.
  • Not every URL query parameter is retained; contact availability and project inventory are not guaranteed.
  • Singapore warehouse shares the industrial filter; shophouse shares the retail filter. The rooms selection can include broader residential rental inventory; check listings when you need a narrow category.
  • Masked Indonesia phone numbers are not revealed. Unit numbers, coordinates, agency names and contact emails can be missing.
  • Photo lists are capped at 20 URLs per row. Source display values and missing fields may differ between markets.

More real estate and property data scrapers from the same publisher:

Browse all of our scrapers at apify.com/lentic_clockss.

Support

Report a problem or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.