# Madlan - Israel Real Estate Listings (`swerve/madlan-scraper`) Actor

Scrape Madlan.co.il property listings in Israel. Rent & buy across 127+ cities. Returns prices, rooms, area, photos, amenities, property type, and agent contact info.

- **URL**: https://apify.com/swerve/madlan-scraper.md
- **Developed by:** [Swerve](https://apify.com/swerve) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 208 total users, 35 monthly users, 98.3% runs succeeded, 1 bookmarks
- **User rating**: 3.00 out of 5 stars

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Madlan.co.il Real Estate Scraper

Scrape real estate listings (rent & buy) from [Madlan.co.il](https://www.madlan.co.il), Israel's most data-rich property platform powered by Localize.city.

### Why This Scraper?

Madlan (Localize.city) is Israel's most analytics-heavy real estate platform. Unlike Yad2, Madlan enriches every listing with neighbourhood analytics, price trends, and property condition data. This scraper gives you:

- **Rich property data** - condition, parking spots count, floorplan images, and amenity flags that other platforms lack
- **Image CDN URLs** - direct image links that work without bot protection or cookies
- **127+ Israeli cities** - Hebrew or English names, multi-city in one run
- **Advanced filters** - price, rooms, neighbourhood, amenities, and agent exclusion
- **Agent detection** - each listing tagged with `hasAgent: true/false`
- **Contact info** - phone numbers and names when available

### Use Cases

- **Real estate investors** comparing Madlan listings against transaction history to spot underpriced apartments in Tel Aviv, Herzliya, and Givatayim
- **Property analysts** studying condition data (renovated, new, needs work) and floorplans at scale for flipping or value-add strategies
- **PropTech startups** building Hebrew-language property search apps with richer structured data than Yad2 alone provides
- **Buyer-side agents** sourcing off-Yad2 inventory and exclusive Madlan listings to pitch to client pipelines
- **Bank mortgage teams** validating borrower-stated property details (rooms, sqm, condition) against Madlan's dataset
- **Market researchers** tracking private vs. agent listing ratios and inventory churn across Israeli cities

### Input

| Field | Type | Description |
|-------|------|-------------|
| `city` | string | City name (Hebrew/English), comma-separated, or `"all"` |
| `dealType` | string | `"rent"` or `"buy"` |
| `maxItems` | integer | Optional cap on listings per city. Leave blank to get every matching listing |
| `minPrice` | integer | Min price in ILS (optional) |
| `maxPrice` | integer | Max price in ILS (optional) |
| `minRooms` | number | Min rooms (optional) |
| `maxRooms` | number | Max rooms (optional) |
| `neighbourhood` | string | Filter by neighbourhood or street name in Hebrew (optional) |
| `excludeAgents` | boolean | Only return private-owner listings |
| `requireParking` | boolean | Only listings with parking |
| `requireElevator` | boolean | Only listings with elevator |
| `requireBalcony` | boolean | Only listings with balcony |
| `requireSecureRoom` | boolean | Only listings with safe room (mamad) |
| `includeContactMetadata` | boolean | Off by default. Adds `contactMetadata`: where `contactPhone` came from and when (see [Contact metadata](#contact-metadata-optional)) |

#### Example Input

```json
{
  "city": "Tel Aviv, Haifa",
  "dealType": "rent",
  "maxItems": 100,
  "maxPrice": 8000,
  "minRooms": 2,
  "requireBalcony": true
}
```

### Output

Results are sorted by most recent first. Each listing includes:

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique Madlan listing ID |
| `url` | string | Direct link to the listing on Madlan |
| `dealType` | string | `"rent"` or `"buy"` |
| `city` | string | City name in English |
| `cityHebrew` | string | City name in Hebrew |
| `neighbourhood` | string | Neighbourhood name in Hebrew |
| `address` | string | Full address string |
| `streetName` | string | Street name |
| `streetNumber` | string | Street/house number |
| `price` | integer | Price in ILS |
| `currency` | string | Always `"ILS"` |
| `rooms` | number | Number of rooms |
| `floor` | string | Floor number/description |
| `areaSqm` | number | Area in square meters |
| `condition` | string | Property condition (e.g. renovated, new) |
| `parking` | integer | Number of parking spots |
| `hasElevator` | boolean | Whether building has elevator |
| `hasBalcony` | boolean | Whether unit has balcony |
| `hasSecureRoom` | boolean | Whether unit has safe room (mamad) |
| `images` | array | Image URLs (CDN links, no bot protection) |
| `floorplanImages` | array | Floorplan image URLs |
| `contactName` | string | Contact person name (agent or owner) |
| `contactPhone` | string | The private seller's contact number when Madlan gives one, otherwise the number Madlan displays for the listing. Not necessarily the publisher's direct line |
| `contactType` | string | Contact type (agent, private, etc.) |
| `hasAgent` | boolean | `true` if agent, `false` if private owner |
| `firstSeen` | string | When the listing first appeared on Madlan (ISO date) |
| `scrapedAt` | string | When this data was scraped (ISO date) |
| `contactMetadata` | object | Only with `includeContactMetadata`: where `contactPhone` came from and when; `null` when there is no number |

#### Example Output

```json
{
  "id": "gd93kf2m",
  "url": "https://www.madlan.co.il/listings/gd93kf2m",
  "dealType": "rent",
  "city": "Tel Aviv",
  "cityHebrew": "תל אביב יפו",
  "neighbourhood": "הצפון הישן",
  "address": "דיזנגוף 204, תל אביב יפו",
  "streetName": "דיזנגוף",
  "streetNumber": "204",
  "price": 6500,
  "currency": "ILS",
  "rooms": 3,
  "floor": "4",
  "areaSqm": 72,
  "condition": "משופצת",
  "parking": 1,
  "hasElevator": true,
  "hasBalcony": true,
  "hasSecureRoom": false,
  "images": [
    "https://images2.madlan.co.il/t:nonce:v=2;resize:height=800;convert:type=webp/bulletin/gd93kf2m/img1.webp",
    "https://images2.madlan.co.il/t:nonce:v=2;resize:height=800;convert:type=webp/bulletin/gd93kf2m/img2.webp"
  ],
  "floorplanImages": [
    "https://images2.madlan.co.il/t:nonce:v=2;resize:height=800;convert:type=webp/bulletin/gd93kf2m/floorplan.webp"
  ],
  "contactName": "David",
  "contactPhone": "054-1234567",
  "contactType": "private",
  "hasAgent": false,
  "firstSeen": "2026-03-20T10:30:00.000Z",
  "scrapedAt": "2026-03-26T14:22:05.123Z"
}
```

### Contact metadata (optional)

`contactPhone` is the private seller's contact number when Madlan provides one (`poc.contactInfo.phone`), otherwise the number Madlan displays for the listing (`poc.displayNumber`). Neither is guaranteed to be the publisher's direct line, and a displayed number can be a routing number. The actor does not reveal, and does not try to find, the number behind a routing number.

Set `includeContactMetadata` to `true` to add a `contactMetadata` object to every listing. It makes no extra requests, and with the option off (the default) the output is exactly as before. It is `null` when a listing has no number.

| Field | Description |
|-------|-------------|
| `phone` | Exactly the value in `contactPhone` |
| `source` | `poc.contactInfo.phone` or `poc.displayNumber` (or `unknown` if it could not be traced; not expected) |
| `collectedAt` | When the actor received Madlan's search response that carried the number (UTC) |
| `isVirtualPhoneNumber` | Always `null`: Madlan's response does not say whether a number is a routing number |
| `virtualFlagSource` | Always `null` |

```json
{
  "contactPhone": "054-1234567",
  "contactMetadata": {
    "phone": "054-1234567",
    "source": "poc.contactInfo.phone",
    "collectedAt": "2026-10-12T09:14:03.512Z",
    "isVirtualPhoneNumber": null,
    "virtualFlagSource": null
  }
}
```

### How it works

This scraper reads from Madlan's own structured data API instead of parsing search-result pages, so every field - price, rooms, area, amenities, GPS coordinates, and agent contact details - comes back clean and consistent. Madlan also carries rich neighbourhood context (schools, prices, transport, safety); turn on the insights option to include it per listing.

Results are written to the dataset incrementally as each city is scraped, so a long multi-city run never loses what it already collected. There are no hidden caps: leave `maxItems` blank and it returns every matching listing.

### Also Available

- [Yad2.co.il Real Estate Scraper](https://apify.com/swerve/yad2-scraper) - Israel's #1 classifieds platform, 800+ listings per city
- [Yad2.co.il Vehicle Scraper](https://apify.com/swerve/yad2-vehicles) - scrape vehicle listings from Yad2
- [Yad2.co.il Products Scraper](https://apify.com/swerve/yad2-products) - scrape second-hand product listings from Yad2
- [Israel Zoning Plans](https://apify.com/swerve/israel-zoning-plans) - the zoning plans governing any block or parcel, with the binding regulations.
- [Israel Land Tenders](https://apify.com/swerve/israel-land-tenders) - Israel Land Authority auctions with reserve prices, deadlines and winning bids.
- [Israel Sold Property Prices](https://apify.com/swerve/nadlan-deals) - recorded sale prices from the Tax Authority, searchable by the same block and parcel.
- [Israel Building Permits](https://apify.com/swerve/israel-building-permits) - approved building permits and urban-renewal projects by address, to see what is coming to a street.

### Supported Cities (127+)

Use English or Hebrew names. Partial names work too (e.g. "Pardes Hana" matches "Pardes Hana Karkur"). Use `"all"` to scrape every city.

**Major Cities:** Tel Aviv (תל אביב), Jerusalem (ירושלים), Haifa (חיפה), Beer Sheva (באר שבע), Rishon Lezion (ראשון לציון), Petah Tikva (פתח תקווה), Ashdod (אשדוד), Netanya (נתניה), Ashkelon (אשקלון), Holon (חולון), Ramat Gan (רמת גן), Bat Yam (בת ים), Rehovot (רחובות), Modiin (מודיעין), Bnei Brak (בני ברק)

**Sharon & Center:** Raanana (רעננה), Herzliya (הרצליה), Kfar Saba (כפר סבא), Hod Hasharon (הוד השרון), Ramat Hasharon (רמת השרון), Givatayim (גבעתיים), Nes Ziona (נס ציונה), Rosh Haayin (ראש העין), Givat Shmuel (גבעת שמואל), Kiryat Ono (קרית אונו), Or Yehuda (אור יהודה), Ganei Tikva (גני תקווה), Shoham (שוהם), Yehud Monosson (יהוד מונוסון), Lod (לוד), Ramla (רמלה), Yavne (יבנה), Gedera (גדרה), Beer Yaakov (באר יעקב), Gan Yavne (גן יבנה), Hadera (חדרה), Pardes Hana Karkur (פרדס חנה כרכור), Binyamina (בנימינה), Zichron Yaakov (זכרון יעקב), Kadima Tzoran (קדימה צורן), Even Yehuda (אבן יהודה), Kfar Yona (כפר יונה), Tel Mond (תל מונד)

**North:** Nazareth (נצרת), Nof Hagalil (נוף הגליל), Tiberias (טבריה), Akko (עכו), Nahariya (נהריה), Carmiel (כרמיאל), Afula (עפולה), Kiryat Ata (קרית אתא), Kiryat Bialik (קרית ביאליק), Kiryat Motzkin (קרית מוצקין), Kiryat Yam (קרית ים), Kiryat Shmona (קרית שמונה), Migdal Haemek (מגדל העמק), Yokneam Illit (יוקנעם עילית), Nesher (נשר), Tirat Carmel (טירת הכרמל), Or Akiva (אור עקיבא), Kiryat Tivon (קרית טבעון), Shfaram (שפרעם), Maalot Tarshiha (מעלות תרשיחא), Tzfat (צפת), Beit Shean (בית שאן)

**South:** Eilat (אילת), Kiryat Gat (קרית גת), Arad (ערד), Dimona (דימונה), Sderot (שדרות), Netivot (נתיבות), Ofakim (אופקים), Rahat (רהט), Kiryat Malachi (קרית מלאכי), Yeruham (ירוחם), Mitzpe Ramon (מצפה רמון), Meitar (מיתר), Lehavim (להבים), Omer (עומר)

**Jerusalem Area:** Beit Shemesh (בית שמש), Mevaseret Zion (מבשרת ציון), Maale Adumim (מעלה אדומים), Efrat (אפרת), Givat Zeev (גבעת זאב), Modiin Illit (מודיעין עילית), Beitar Illit (ביתר עילית), Kiryat Yearim (קרית יערים), Tzur Hadassah (צור הדסה)

**Other:** Ariel (אריאל), Harish (חריש), Elad (אלעד), Karnei Shomron (קרני שומרון), Alfei Menashe (אלפי מנשה), Oranit (אורנית), Katzrin (קצרין), and 20+ more

### Keywords

Madlan scraper, Madlan API, Localize.city API, Israeli real estate data, Tel Aviv apartment listings, Jerusalem property data, Israel property scraper, Hebrew real estate API, Israeli real estate market, floorplan data Israel, madlan.co.il scraper, Israel housing market data

# Actor input Schema

## `city` (type: `string`):

City name in Hebrew or English (e.g. 'Tel Aviv', 'תל אביב', 'Haifa', 'Jerusalem'). Comma-separated for multiple cities, or 'all' for all 127+ cities. Common cities: Tel Aviv, Jerusalem, Haifa, Beer Sheva, Raanana, Herzliya, Netanya, Ashdod, Rishon Lezion, Petah Tikva, Ramat Gan, Holon, Bat Yam, Rehovot, Modiin, Ashkelon, Kfar Saba, Hadera, Bnei Brak, Eilat

## `dealType` (type: `string`):

Type of listing to scrape

## `maxItems` (type: `integer`):

Optional cost cap on listings per city. Leave it blank to get EVERY matching listing (there is no default limit). Big cities like Tel Aviv can have thousands of listings, and you pay per result, so set a number (e.g. 200) if you only need a sample.

## `minPrice` (type: `integer`):

Minimum price filter in ILS (optional)

## `maxPrice` (type: `integer`):

Maximum price filter in ILS (optional)

## `minRooms` (type: `number`):

Minimum number of rooms (optional)

## `maxRooms` (type: `number`):

Maximum number of rooms (optional)

## `publishedAfter` (type: `string`):

Only include listings first published on or after this date. Drastically reduces cost for daily monitoring. Accepts ISO (YYYY-MM-DD) or full ISO timestamps.

## `neighbourhood` (type: `string`):

Filter by neighbourhood or street name in Hebrew (e.g. נווה זמר, הצפון הישן). Matches against neighbourhood, street name, and address fields.

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

Filter by property type. Leave empty for all types.

## `excludeAgents` (type: `boolean`):

Only return listings from private owners (exclude agent/broker listings)

## `requireParking` (type: `boolean`):

Only return listings that have parking

## `requireElevator` (type: `boolean`):

Only return listings with an elevator in the building

## `requireBalcony` (type: `boolean`):

Only return listings that have a balcony

## `requireSecureRoom` (type: `boolean`):

Only return listings that have a secure room (safe room / mamad)

## `enrichInsights` (type: `boolean`):

Adds a 'locationInsights' array to each listing with categorized neighborhood data (planning, safety, livability, transportation, prices) in Hebrew. Costs 1 extra GraphQL call per scan.

## `includeContactMetadata` (type: `boolean`):

OFF by default. Adds a contactMetadata object to every listing that explains the number in contactPhone: whether Madlan gave it as the private seller's contact number (poc.contactInfo.phone) or as the number it displays for the listing (poc.displayNumber), and when the actor received it. Madlan does not say whether a number is a routing number, so isVirtualPhoneNumber is always null. Makes no extra requests; leaving it off keeps the output exactly as before. contactPhone is not guaranteed to be the publisher's direct line, and the actor does not reveal or try to find the number behind a routing number.

## Actor input object example

```json
{
  "city": "Tel Aviv",
  "dealType": "rent",
  "excludeAgents": false,
  "requireParking": false,
  "requireElevator": false,
  "requireBalcony": false,
  "requireSecureRoom": false,
  "enrichInsights": false,
  "includeContactMetadata": false
}
```

# 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 = {
    "city": "Tel Aviv"
};

// Run the Actor and wait for it to finish
const run = await client.actor("swerve/madlan-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 = { "city": "Tel Aviv" }

# Run the Actor and wait for it to finish
run = client.actor("swerve/madlan-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 '{
  "city": "Tel Aviv"
}' |
apify call swerve/madlan-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,swerve/madlan-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/OdZazcftQ9ouI628C/builds/aneaHiTebsgyTrbVM/openapi.json
