# Lamudi Indonesia Property Scraper (`solidcode/lamudi-co-id-scraper`) Actor

\[💰 $1.0 / 1K] Extract property listings from Lamudi Indonesia (lamudi.co.id) — houses, apartments, land, and commercial for sale or rent, with prices in IDR, beds, baths, area, photos, geolocation, and agent and agency details. Search by city and filters, or paste Lamudi URLs directly.

- **URL**: https://apify.com/solidcode/lamudi-co-id-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** Real estate, Automation, Developer tools
- **Stats:** 5 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Lamudi Indonesia Property Scraper

Pull property listings from Lamudi Indonesia (lamudi.co.id) at scale — IDR prices, bedrooms and bathrooms, building and land area in m², map coordinates, full photo galleries, and agent contacts for every house, apartment, villa, land plot, and commercial space for sale or rent across Indonesia. Built for Indonesian real-estate investors, buyer's agents, and proptech teams who need clean, structured Lamudi data without copy-pasting listings by hand.

### Why This Scraper?

- **Guided search with no URL crafting** — pick Buy or Rent, type a city like Jakarta, Bandung, Surabaya, or Bali, choose a property type, and run. No need to hand-build a Lamudi search link.
- **Nine property categories, matched leaf-for-leaf** — House, Townhouse, Villa, Boarding House (kos), Apartment, Land / Lot, Commercial, Office Space, or Any. Lamudi files townhouses, villas and kos under its "House" heading, so a plain House search here returns standalone houses only; pick the combined category when you want all four.
- **Prices in IDR, both ways** — a parsed numeric `price` for sorting and math, plus the original `priceText` exactly as shown; rentals also carry a `pricePeriod` of `month` or `year` so a monthly rent is never mistaken for an annual one. "Request details" / hidden-price listings are kept with a null price instead of being dropped.
- **Map coordinates that admit what they are** — `latitude` and `longitude` ready to plot without geocoding, each stamped `exact` or `approximate` in a `coordinatesAccuracy` column. About 1 listing in 5 is pinned to the surrounding area rather than the building, and most property feeds hand you both mixed together; here you can drop or down-weight them before you measure a single distance. Alongside them, `postedAt`, the timestamp Lamudi recorded when the listing went live. It comes back on roughly 9 out of 10 for-sale listings straight from the search results. Rental stock is much older on Lamudi, so on Rent searches turn on Fetch Full Details and `postedAt` reaches the same 9 in 10 there. Sort by genuinely new inventory instead of trusting a "Just Listed" badge.
- **Advertiser contacts on every row** — `agencyName` plus the WhatsApp/phone number, pulled straight from the search results so a 300-listing outreach list costs one pass, not 300 page opens.
- **Buy and rent in one actor** — flip a single Buy-or-Rent dropdown; no separate run or second tool for the rental market.
- **Precision price, bedroom, and bathroom filters** — set an exact IDR range and minimum beds/baths; on Rent searches the range is matched against the advertised rent, not the property's sale value, so a rental budget behaves the way you expect.
- **Full photo gallery on demand** — turn on Fetch Full Details for every image URL, duplicate-free and matched by `photoCount`, plus the land area and the direct phone number.
- **Direct Lamudi URLs or guided fields** — paste one or many filtered Lamudi search URLs as Start URLs when you already have the exact search ready in your browser.

### Use Cases

**Market Research**

- Map for-sale and for-rent inventory across Jakarta, Bandung, Surabaya, and Bali
- Compare asking prices per m² between districts and cities
- Track property-type mix (houses vs. apartments vs. land) by region
- Benchmark new developments and named projects with the keyword filter

**Investment Analysis**

- Pull every listing in a target IDR price band for underwriting
- Plot listings on a map using built-in latitude and longitude
- Compare building area vs. land area to spot value on land-heavy lots
- Monitor newest-first listings to catch fresh stock early

**Lead Generation for Agents**

- Build agent and agency contact lists with names and phone numbers
- Identify the most active agencies in a city or property type
- Source comparable listings to support a client pitch or valuation

**Proptech & App Data**

- Feed a property search app or dashboard with structured Indonesian listings
- Enrich an existing database with IDR pricing, geo, and photos
- Power alerting tools that watch for new listings in a target area

**Price Monitoring**

- Track rental and sale price ranges over time in a specific district
- Watch how a single development's pricing shifts across runs
- Compare lowest-price-first and highest-price-first views of a market

### Getting Started

#### Simple city search

```json
{
  "purpose": "for-sale",
  "location": "jakarta"
}
```

#### Filtered buy search with price and bedrooms

```json
{
  "purpose": "for-sale",
  "location": "bandung",
  "propertyType": "house",
  "priceMin": 1000000000,
  "priceMax": 5000000000,
  "bedroomsMin": 3,
  "bathroomsMin": 2,
  "maxResults": 200
}
```

#### For-rent search with sort and full details

```json
{
  "purpose": "for-rent",
  "location": "bali",
  "propertyType": "villa",
  "sort": "newest",
  "fetchDetails": true,
  "maxResults": 100
}
```

#### Power-user Start URLs

```json
{
  "startUrls": [
    "https://www.lamudi.co.id/en/for-sale/jakarta/apartment/",
    "https://www.lamudi.co.id/en/for-rent/surabaya/house/"
  ],
  "maxResults": 300
}
```

### Input Reference

#### Search

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `purpose` | string | `"for-sale"` | Buy or rent: `For Sale (Buy)` or `For Rent`. Ignored when Start URLs are provided. |
| `location` | string | `"jakarta"` | City or region to search, e.g. Jakarta, Bandung, Surabaya, Bali, Tangerang. Use `Indonesia` to search the whole country. |
| `propertyType` | string | `"any"` | Property category: `Any`, `House`, `Townhouse`, `Villa`, `Boarding House / Kos`, `House, Townhouse, Villa & Kos (all four)`, `Apartment`, `Land / Lot`, `Commercial`, or `Office Space`. |
| `searchQuery` | string | `""` | Optional keyword — area, project, or development name, e.g. "BSD City", "Kemang", "Pantai Indah Kapuk". |

#### Filters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `priceMin` | integer | — | Only include listings at or above this price in IDR (e.g. 1000000000 for 1 billion). |
| `priceMax` | integer | — | Only include listings at or below this price in IDR. |
| `bedroomsMin` | integer | — | Minimum bedrooms (0 = studio). Ignored for Land and most Commercial searches. |
| `bathroomsMin` | integer | — | Minimum bathrooms. |
| `areaMin` | integer | — | Minimum floor or land area in m². |
| `areaMax` | integer | — | Maximum area in m². |
| `sort` | string | `"most-relevant"` | Result order: `Most relevant (default)`, `Newest first`, `Lowest price first`, or `Highest price first`. |

#### Advanced Search & Options

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `startUrls` | array | `[]` | Paste Lamudi search-result or single-property URLs. When provided, these override Buy/Rent, City, Property Type, Keyword, and Filters above. |
| `maxResults` | integer | `50` | Maximum number of properties to collect across all searches and URLs. Set 0 for unlimited. |
| `fetchDetails` | boolean | `false` | Open each listing's own page to collect the full photo gallery, land area, and the agent's phone number. Adds one extra page visit per property. |

### Output

Each property is returned as one flat record. Every field below is always present (null when Lamudi does not provide it).

```json
{
  "id": "019ea661-7c41-750f-bae4-f643443e71a4",
  "url": "https://www.lamudi.co.id/en/property/41032-73-6750520c712f-528a-19ff69a-a4fd-780e",
  "title": "Dijual Rumah Siap Huni @Menteng Jakarta Pusat Luas Tanah 586 m2",
  "purpose": "for-sale",
  "propertyType": "house",
  "price": 39000000000,
  "priceText": "Rp 39M",
  "pricePeriod": null,
  "priceCurrency": "IDR",
  "bedrooms": 5,
  "bathrooms": 4,
  "carSpaces": 2,
  "area": 586,
  "areaText": "586 m²",
  "landArea": 720,
  "location": "Pondok Indah, Jakarta Selatan",
  "region": "DKI Jakarta",
  "city": "Jakarta Selatan",
  "area_district": "Pondok Indah",
  "latitude": -6.1937297,
  "longitude": 106.7831,
  "coordinatesAccuracy": "exact",
  "photoCount": 10,
  "coverPhotoUrl": "https://img.lamudi.com/.../cover.jpg",
  "imageUrls": ["https://img.lamudi.com/.../1.jpg", "https://img.lamudi.com/.../2.jpg"],
  "description": "Spacious family home in a prime South Jakarta neighborhood...",
  "agentPhone": "+6281234567890",
  "agencyName": "Premier Property Indonesia",
  "tagLabels": ["Premium", "Featured"],
  "postedAt": "2026-06-08T04:15:00Z",
  "scrapedAt": "2026-06-11T08:30:00Z"
}
```

#### Listing Core

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Lamudi listing identifier, the same value whether the property came from a search or from a URL you pasted |
| `url` | string | Full listing URL |
| `title` | string | The headline the seller wrote, keywords and all — not an auto-generated label |
| `purpose` | string | `for-sale` or `for-rent` |
| `propertyType` | string | The listing's own category, normalized — e.g. house, apartment, villa, townhouse, condo, room, land, office, commercial, warehouse |
| `description` | string | Listing description text |
| `tagLabels` | array | Badges shown on the listing, e.g. Premium, Featured |
| `postedAt` | string | When the listing went live on Lamudi, to the second. Roughly 9 in 10 for-sale listings carry it in search results; for-rent listings are older stock, so turn on Fetch Full Details to reach the same coverage on rentals |
| `scrapedAt` | string | ISO timestamp of collection |

#### Pricing & Specs

| Field | Type | Description |
|-------|------|-------------|
| `price` | number | Numeric price in IDR — the sale price on a Buy search, the advertised rent on a Rent search (null when Lamudi hides the price) |
| `priceText` | string | Original formatted price text as shown, e.g. `Rp 3,80M` or `Rp 152Jt /month` |
| `pricePeriod` | string | Rental period the price covers: `month`, `year`, or null on sales |
| `priceCurrency` | string | Currency code, usually `IDR` (a few listings are quoted in `USD`) |
| `bedrooms` | number | Bedroom count |
| `bathrooms` | number | Bathroom count |
| `carSpaces` | number | Car / garage spaces |
| `area` | number | Building / floor area in m² |
| `areaText` | string | Raw area text as shown |
| `landArea` | number | Land area in m² (filled when Fetch Full Details is on) |

#### Location & Geo

| Field | Type | Description |
|-------|------|-------------|
| `location` | string | Human-readable location string |
| `region` | string | Province / region |
| `city` | string | City |
| `area_district` | string | District or sub-area within the city |
| `latitude` | number | Latitude for mapping |
| `longitude` | number | Longitude for mapping |
| `coordinatesAccuracy` | string | Whether the pin is the property itself (`exact`) or the area it is advertised in (`approximate`). About 1 in 5 listings are pinned to an area; this column tells you which, so you can filter them out before measuring distances |

#### Advertiser & Media

| Field | Type | Description |
|-------|------|-------------|
| `agencyName` | string | The advertiser Lamudi shows on the listing: an agency, or a solo broker's own name |
| `agentPhone` | string | Contact phone number where Lamudi exposes it |
| `photoCount` | number | Number of photos, matching the length of `imageUrls` when Fetch Full Details is on |
| `coverPhotoUrl` | string | Cover image URL |
| `imageUrls` | array | All gallery image URLs (filled when Fetch Full Details is on) |

### Tips for Best Results

- Use Start URLs when you already have a filtered search open in your browser — copy the Lamudi URL straight in and it fully overrides the guided fields, so the exact result set is reproduced.
- Enable Fetch Full Details when you need the complete photo gallery, land area, or the agent's direct phone — it visits one extra page per property, so leave it off for fast runs that still include the cover photo, price, beds, baths, area, location, and agency.
- Turn Fetch Full Details on for Rent searches if `postedAt` matters to you. Jakarta's rental inventory is largely older listings whose publication date only appears on the listing's own page, so search-only coverage thins out the deeper you sweep, down to about a third on a 300-listing rental run. With the toggle on it stays above 9 in 10 at any depth.
- Price filters are applied to every retrieved listing for precision (Lamudi has no price field in its URL), so for very tight IDR ranges raise Max Results to keep enough matches on each page.
- Set `location` to `Indonesia` to sweep the whole country, or name a specific city slug like `jakarta-selatan` for a tighter, faster search.
- Filter on `coordinatesAccuracy` before any distance, radius, or commute calculation. Roughly one listing in five is pinned to its neighbourhood instead of its address, and those points can sit hundreds of metres from the real property — fine for a heat map, misleading for "within 2 km of this office".
- Use `Newest first` sort to catch fresh stock and `Lowest price first` to build comps from the bottom of a market upward.
- Skip `bedroomsMin` / `bathroomsMin` for Land and Commercial searches — those listings rarely report rooms, and the minimums can thin out otherwise valid results.
- Keep `maxResults` at 0 for a full market sweep, but start with a small cap when dialing in a new city or filter combination to verify the result shape first.

### Pricing

**From $1.00 per 1,000 results** — pay only for the property listings you collect, with no charge for compute time or run duration. Bronze, Silver, and Gold subscribers pay progressively less; the table below shows total cost at each discount tier.

| Results | No discount | Bronze | Silver | Gold |
|---------|-------------|--------|--------|------|
| 100 | $0.12 | $0.115 | $0.105 | $0.10 |
| 1,000 | $1.20 | $1.15 | $1.05 | $1.00 |
| 10,000 | $12.00 | $11.50 | $10.50 | $10.00 |
| 100,000 | $120.00 | $115.00 | $105.00 | $100.00 |

A "result" is one property listing record in your dataset. No compute or time-based charges — you pay per result, plus a small fixed per-run start fee. Apify platform fees are additional.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on new results
- **Webhooks** — Trigger custom APIs on run completion
- **Apify API** — Full programmatic access

### Legal & Ethical Use

This actor collects publicly available property listing data for legitimate business purposes such as market research, investment analysis, and lead generation. You are responsible for using the collected data in compliance with Lamudi's terms of service, applicable data-protection laws, and any local regulations governing personal data and real-estate information. Do not use contact details for unsolicited spam, and respect the rights of listing owners and agents. </content> </invoke>

# Actor input Schema

## `purpose` (type: `string`):

Are you looking for properties for sale or for rent? Ignored when Start URLs are provided.

## `location` (type: `string`):

City or region to search, e.g. "Jakarta", "Bandung", "Surabaya", "Bali", "Tangerang". Provinces work too, e.g. "Jawa Barat", "Sulawesi Selatan". Type "Indonesia" to search the whole country. Ignored when Start URLs are provided.

## `propertyType` (type: `string`):

Filter by property category. 'House' returns standalone houses only. Townhouses, villas and boarding houses (kos) are separate categories on Lamudi, so pick 'House, Townhouse, Villa & Kos' if you want all four together. Choose 'Any' to include every category.

## `searchQuery` (type: `string`):

Optional keyword — area, project, or development name, e.g. "BSD City", "Kemang", "Pantai Indah Kapuk". Leave empty for no keyword filter.

## `startUrls` (type: `array`):

Power-user input. Paste Lamudi search-result URLs (e.g. https://www.lamudi.co.id/en/for-sale/jakarta/house/) or individual property URLs directly. When provided, these override the Buy/Rent, City, Property Type, Keyword, and Filters settings above.

## `priceMin` (type: `integer`):

Only include listings at or above this price in Indonesian Rupiah (e.g. 1000000000 for 1 billion IDR). Leave empty for no minimum. On Rent searches this is matched against the advertised rent for the period shown in the pricePeriod column (month or year), not the property's sale value. Note: the price range is applied after listings are retrieved (Lamudi has no price filter in the URL), so a very tight range makes the run read through more pages to fill your Max Results — the run log says how many pages held no match. Listings where Lamudi publishes no price at all are kept, and the run log says how many.

## `priceMax` (type: `integer`):

Only include listings at or below this price in Indonesian Rupiah. Leave empty for no maximum. On Rent searches this is matched against the advertised rent (see the Minimum Price note). Applied after listings are retrieved.

## `bedroomsMin` (type: `integer`):

Only include properties with at least this many bedrooms (0 = studio). Leave empty for any. Ignored for Land and most Commercial searches.

## `bathroomsMin` (type: `integer`):

Only include properties with at least this many bathrooms. Leave empty for any.

## `areaMin` (type: `integer`):

Only include properties at or above this floor or land area in square meters. Leave empty for no minimum.

## `areaMax` (type: `integer`):

Only include properties at or below this area in square meters. Leave empty for no maximum.

## `sort` (type: `string`):

How Lamudi orders results before we collect them.

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

Maximum number of properties to collect across all searches and URLs. Set 0 for unlimited. Results are collected in full pages, so the final page may overshoot this cap by a few records. Very large or unlimited runs are bounded by a built-in safety ceiling of roughly 60,000 properties per search, well above any normal search's inventory.

## `fetchDetails` (type: `boolean`):

Open each listing's own page to collect the full photo gallery, land area, the agent's phone number, and the publication date for older listings that do not show one in search results (common on Rent searches). This visits one extra page per property, so runs take longer. Leave off for faster runs that still include the cover photo, price, beds, baths, area, location, and agency.

## Actor input object example

```json
{
  "purpose": "for-sale",
  "location": "jakarta",
  "propertyType": "any",
  "startUrls": [],
  "sort": "most-relevant",
  "maxResults": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

Table of scraped property listings with key fields — price, beds, baths, area, location, and URL.

## `details` (type: `string`):

Full per-listing fields including photos, map coordinates with a pin-accuracy label (exact or approximate), description, agency and contact details, and publication timestamps.

# 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 = {
    "purpose": "for-sale",
    "location": "jakarta",
    "propertyType": "any",
    "searchQuery": "",
    "startUrls": [],
    "sort": "most-relevant",
    "maxResults": 50,
    "fetchDetails": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/lamudi-co-id-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 = {
    "purpose": "for-sale",
    "location": "jakarta",
    "propertyType": "any",
    "searchQuery": "",
    "startUrls": [],
    "sort": "most-relevant",
    "maxResults": 50,
    "fetchDetails": False,
}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/lamudi-co-id-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "purpose": "for-sale",
  "location": "jakarta",
  "propertyType": "any",
  "searchQuery": "",
  "startUrls": [],
  "sort": "most-relevant",
  "maxResults": 50,
  "fetchDetails": false
}' |
apify call solidcode/lamudi-co-id-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,solidcode/lamudi-co-id-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4IlDwbTRZxStIIrjN/builds/8RFPrm10nvVM5mRVu/openapi.json
