# Yad2 Real Estate - Israel Property Listings (`swerve/yad2-scraper`) Actor

Scrape Yad2.co.il real estate listings across 127+ Israeli cities. Get prices, rooms, area, amenities, photos, descriptions, and agent contact info for rent and buy. Pay per result.

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

## Pricing

from $5.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

## Yad2.co.il Real Estate Scraper

Scrape real estate listings (rent & buy) from [Yad2.co.il](https://www.yad2.co.il), Israel's #1 classifieds platform. Fast, reliable, and feature-rich.

### Why This Scraper?

- **Blazing fast** - most queries return in under 5 seconds thanks to smart caching
- **800+ listings per city** - combines multiple data sources for maximum coverage
- **Advanced filters** - price range, rooms, neighbourhood, amenities (parking, elevator, balcony, safe room)
- **Contact info** - real phone numbers and seller names (optional)
- **Agent detection** - each listing tagged with `hasAgent: true/false`
- **127+ Israeli cities** - Hebrew or English names, multi-city in one run
- **Rent & Buy** - both deal types supported

### Use Cases

- **Real estate investors** tracking new Tel Aviv, Jerusalem, and Ramat Gan listings daily to spot underpriced deals before agents do
- **Relocation agencies** helping olim and expats find apartments in cities like Raanana, Herzliya, and Modiin with specific filters (safe room, elevator, parking)
- **Data scientists** building Israeli property price indexes, rental yield models, and neighbourhood-level ML forecasts from the country's largest listing inventory
- **Property managers** benchmarking rents across their Israeli portfolio cities and tracking agent vs. private-owner supply shifts
- **Lead generation tools** extracting agent phone numbers and seller contact info for CRM outreach and broker prospecting
- **Real estate tech founders** powering alert apps, AVMs, and comparables tools with fresh Yad2 inventory

### Input

| Field | Type | Description |
|-------|------|-------------|
| `city` | string | City name (Hebrew/English) or Yad2 code. Comma-separated or `"all"` |
| `dealType` | string | `"rent"` or `"buy"` |
| `maxItems` | integer | Optional cap on listings per city. Leave blank to scrape all matching listings |
| `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) |
| `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) |
| `enrichListings` | boolean | Fetch detail metadata, contact info, full description, amenities, and agent detection |
| `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",
  "dealType": "rent",
  "maxItems": 50,
  "maxPrice": 8000,
  "requireSecureRoom": true,
  "enrichListings": true
}
```

### Output

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

| Field | Type | Description |
|-------|------|-------------|
| `listingId` | string | Unique Yad2 listing ID |
| `url` | string | Direct link to the listing on Yad2 |
| `dealType` | string | `"rent"` or `"buy"` |
| `adType` | string | `"private"` (owner) or `"commercial"` (agent) |
| `hasAgent` | boolean | `true` if agent, `false` if private owner, `null` if unknown |
| `propertyType` | string | apartment, penthouse, duplex, cottage, etc. |
| `city` | string | City name in English |
| `cityHebrew` | string | City name in Hebrew |
| `neighbourhood` | string | Neighbourhood name |
| `address` | string | Street and house number |
| `streetName` | string | Street name |
| `price` | integer | Price in ILS |
| `currency` | string | Always `"ILS"` |
| `rooms` | number | Number of rooms |
| `floor` | string | Floor number |
| `areaSqm` | number | Area in square meters |
| `parking` | integer | Number of parking spaces |
| `hasElevator` | boolean | Building has elevator |
| `hasParking` | boolean | Has parking |
| `hasBalcony` | boolean | Unit has balcony |
| `hasSecureRoom` | boolean | Unit has safe room (mamad) |
| `images` | array | Array of image URLs |
| `coverImage` | string | Main listing image URL |
| `listingDescription` | string | Full listing description text |
| `contactPhone` | string | Phone number shown for the listing (from Yad2's contact details with `enrichListings`, otherwise a number written in the listing text). Can be a Yad2 routing number, not necessarily the publisher's direct line |
| `contactName` | string | Seller name (requires `enrichListings`) |
| `isRoommates` | boolean | Listing is for a shared apartment (requires `enrichListings`) |
| `publishedAt` | string | When the listing was first published on Yad2 (authoritative with `enrichListings`) |
| `isExclusive` | boolean | Structured property/agent exclusivity reported by Yad2, not platform exclusivity (requires `enrichListings`; `null` if unknown) |
| `agencyName` | string | Agency shown for the listing, when present |
| `licenceNo` | string | Contact's real-estate licence number, preserved as a string |
| `updatedAt` | string | When listing was last updated on Yad2 |
| `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
{
  "listingId": "g2v7x84n",
  "url": "https://www.yad2.co.il/item/g2v7x84n",
  "dealType": "rent",
  "adType": "private",
  "hasAgent": false,
  "propertyType": "apartment",
  "city": "Tel Aviv",
  "cityHebrew": "תל אביב יפו",
  "neighbourhood": "הצפון הישן - ככר המדינה",
  "address": "ארלוזורוב 78",
  "streetName": "ארלוזורוב",
  "price": 7200,
  "currency": "ILS",
  "rooms": 3,
  "floor": "4",
  "areaSqm": 72,
  "parking": 1,
  "hasElevator": true,
  "hasParking": true,
  "hasBalcony": true,
  "hasSecureRoom": true,
  "images": [
    "https://img.yad2.co.il/Pic/202503/24/2_4/o/y2_1a_033848_20250324.jpg",
    "https://img.yad2.co.il/Pic/202503/24/2_4/o/y2_1a_033849_20250324.jpg",
    "https://img.yad2.co.il/Pic/202503/24/2_4/o/y2_1a_033850_20250324.jpg"
  ],
  "coverImage": "https://img.yad2.co.il/Pic/202503/24/2_4/o/y2_1a_033848_20250324.jpg",
  "listingDescription": "דירת 3 חדרים מוארת ומרווחת בקומה 4 עם מעלית. סלון גדול, מטבח משופץ, מרפסת שמש פונה לדרום. ממ\"ד, חניה בטאבו. קרוב לפארק הירקון ולתחבורה ציבורית. כניסה מיידית.",
  "contactPhone": "054-8839217",
  "contactName": "מיכל",
  "isRoommates": false,
  "publishedAt": "2025-03-20T10:00:00.000Z",
  "isExclusive": false,
  "agencyName": null,
  "licenceNo": null,
  "updatedAt": "2025-03-24T08:15:00.000Z",
  "scrapedAt": "2025-03-24T14:32:11.000Z"
}
```

### Contact metadata (optional)

`contactPhone` is the number Yad2 shows for a listing. It is not guaranteed to be the publisher's direct line: Yad2 can show a virtual number that forwards calls. 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` | `contact-info:data.phone` (Yad2's show-number response), `realestate-item:data.customer.phone` (the listing's detail response, used only when the first had no number), `search-results:searchText` (a number written in the listing text, kept when enrichment is off or found no number), or `unknown` (could not be traced; not expected) |
| `collectedAt` | When the actor received the response the number came from (UTC). For `search-results:searchText`, when the search results were received (the same time as `fetchedAt`) |
| `isVirtualPhoneNumber` | Yad2's own statement about this same number: `true`, `false`, or `null` when Yad2 said nothing about it. `false` is Yad2's statement, not a check by the actor. Never guessed from the prefix or the publisher type |
| `virtualFlagSource` | Where that statement was read, or `null` |

What Yad2 returns today: its show-number response carries the number but says nothing about whether it is virtual, so `isVirtualPhoneNumber` is `null` for those numbers. Yad2's listing detail does carry an `isVirtualPhoneNumber` flag, but on the publisher's record, which has no number in it, so the actor does not attach that flag to the number it outputs.

```json
{
  "contactPhone": "055-1234567",
  "contactMetadata": {
    "phone": "055-1234567",
    "source": "contact-info:data.phone",
    "collectedAt": "2026-10-12T09:14:03.512Z",
    "isVirtualPhoneNumber": null,
    "virtualFlagSource": null
  }
}
```

### How it works

This scraper pulls listings straight from Yad2's own data feed and merges several feed sources, so you get far more of a city's live inventory than a single page of search results. Yad2 blocks datacenter traffic, so every request goes through Israeli residential IPs with a real browser fingerprint and a fresh session per retry - runs stay reliable even during traffic spikes.

Results are written to the dataset incrementally as each feed page is scraped, so a long multi-city run never loses what it already collected. When `enrichListings` is on, the scraper calls Yad2's item-detail and contact endpoints for each listing to add authoritative publication/update dates, exact structured exclusivity, agency and licence metadata, phone number, seller name, full description, amenities, and agent detection, with automatic retries so coverage stays near-complete. It does not infer exclusivity from page copy. There are no hidden caps: leave `maxItems` blank and it scrapes every matching listing.

### Also Available

- [Madlan.co.il Real Estate Scraper](https://apify.com/swerve/madlan-scraper) - Israel's largest property data platform with transaction history
- [Yad2.co.il Vehicle Scraper](https://apify.com/swerve/yad2-vehicles) - cars, motorcycles, and commercial vehicles from Yad2
- [Yad2.co.il Products Scraper](https://apify.com/swerve/yad2-products) - second-hand goods and electronics from Yad2
- [Israel Zoning Plans](https://apify.com/swerve/israel-zoning-plans) - what may actually be built on a block or parcel: plan status, approval date and the official documents.
- [Israel Land Tenders](https://apify.com/swerve/israel-land-tenders) - state land auctions, including the winning bidder and the amount paid.
- [Israel Sold Property Prices](https://apify.com/swerve/nadlan-deals) - recorded sale prices, for comps against the asking prices here.
- [Israel Building Permits](https://apify.com/swerve/israel-building-permits) - what has been approved to be built at an address, including urban-renewal projects, to spot buildings before they are marketed.

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

Yad2 scraper, Yad2 API, Israeli real estate API, Tel Aviv apartments, Jerusalem real estate data, Israel property listings, Hebrew real estate scraper, Ramat Gan rentals, Haifa apartments, Israeli rental market data, Israel housing data, yad2.co.il scraper

# 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. 'Commercial' covers offices, shops, warehouses, clinics, halls and other non-residential properties (both for-sale and for-rent are returned together; check the dealType field on each listing).

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

Optional cost cap on how many listings to return per city. Leave blank to scrape ALL matching listings for each city. Big cities such as Tel Aviv or Jerusalem can yield 1,000+ results, so a blank value returns everything the city has. Set a number (for example 50 or 200) only if you want to limit results and cost.

## `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)

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

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

## `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)

## `enrichListings` (type: `boolean`):

Fetches Yad2's item-detail and contact endpoints per listing to add publication/update dates, exact exclusivity, agency and licence details, phone number, contact name, full description, amenities, and definitive agent detection. ON by default. Set to false for faster runs when detail fields are not needed.

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

OFF by default. Adds a contactMetadata object to every listing that explains the number in contactPhone: which Yad2 response and field it was read from, when the actor received it, and whether Yad2 itself marked that same number as virtual (a routing number). That flag is filled only when Yad2 states it next to that exact number; otherwise it is null, and it is never guessed from the prefix or the publisher type. 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.

## `proxyConfig` (type: `object`):

Optional. Leave as 'No proxy' - the scraper handles geo-routing automatically. Only change if instructed by support.

## Actor input object example

```json
{
  "city": "Tel Aviv",
  "dealType": "rent",
  "requireParking": false,
  "requireElevator": false,
  "requireBalcony": false,
  "requireSecureRoom": false,
  "enrichListings": true,
  "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/yad2-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/yad2-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/yad2-scraper --silent --output-dataset

```

## MCP server setup

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