# Yad2 Real Estate Scraper - Israel Property Listings (`nice_dev/yad2-listings-scraper`) Actor

Scrape Yad2.co.il real estate: homes for sale, rentals and commercial property across Israel, with price, rooms, size, floor, address, GPS, photos, amenities, seller phone and recorded sales nearby.

- **URL**: https://apify.com/nice_dev/yad2-listings-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (community)
- **Categories:** Real estate, Lead generation, MCP servers
- **Stats:** 11 total users, 7 monthly users, 99.1% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.96 / 1,000 listings

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?

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

### 🏠 What is Yad2 Real Estate Scraper?

**Yad2 Real Estate Scraper** extracts **property listings from [Yad2.co.il](https://www.yad2.co.il/realestate)**, Israel's largest classifieds site: **apartments and houses for sale, rentals and commercial property**, with **price, rooms, size, floor, full address and GPS, photos, every amenity, the agency and its licence number** — and, as options, **the seller's phone number, the recorded sales around each listing and the local price per m² trend**.

Type a **city in English or Hebrew** (`Tel Aviv`, `חיפה`) or paste any Yad2 search URL, click **Start**, and download the listings in JSON, CSV or Excel. No login, nothing to set up, and it is **fast: about 30 listings with their full listing page in 3 seconds**.

### 📋 What data can you extract from Yad2?

One item per listing, 107 fields:

| Category | What you get |
| --- | --- |
| 🏷️ **Listing** | link, ad number, board (sale, rent, commercial), private owner or agency |
| 🏠 **Property** | type (apartment, penthouse, garden apartment, office, shop…) in Hebrew and English, rooms, size, floor, building floors, condition |
| 💰 **Price** | asking price or monthly rent in shekels, price per m², **price before the last reduction**, building fee, arnona |
| 📍 **Location** | region, area, city, neighbourhood, street, number — in Hebrew with English names — and GPS |
| ✅ **Amenities** | parking, elevator, balcony, safe room (mamad), air conditioning, storage, furniture, accessibility, pets, and the commercial ones |
| 👤 **Seller** | agency, logo, licence number, brokers, seller id, and the **phone number** (option) |
| 📝 **Dates and text** | full description, publication, last update, last bump, move-in date, end of the ad |
| 🧾 **Market data** | **recorded sales near each listing** and the **local price per m² since 2023** (options) |

Every field, with an example, is listed in the **Output** section below.

Fields read on the listing page (description, dates, amenities, agency details) are filled when **Listing details** is ticked (off by default); the phone numbers, recorded sales and price trend when their option is ticked. Otherwise they are `null`.

### ✅ Why use Yad2 Real Estate Scraper?

- 🚀 **Fast**: about 30 listings with their full listing page in 3 seconds.
- 🏙️ **Type the place in English or Hebrew**: a city (`Ramat Gan`), a neighbourhood or a street (`פלורנטין`), several in one run — or a whole region, or all of Israel.
- 🎯 **Every filter of the site**: price, rooms, size, floor, property type, condition, parking, elevator, balcony, safe room, air conditioning, storage, furniture, accessibility, window bars, renovated, exclusive, price dropped, with photos, with a price, private owners or agencies, sort by price.
- 🏢 **Homes and commercial property**: for sale, for rent, offices, shops, warehouses, clinics, halls.
- 🧾 **Market data no other Yad2 scraper gives**: the recorded sales closest to each listing, and the local price per m² month by month since 2023.
- 🧩 **Nothing missed, nothing twice**: pagination is automatic, a big search is split by price so that more than the site's 500 pages can be read, and each listing is returned once.
- 🔔 **New listings and price changes**: tick **Only new listings**, schedule the Actor, and each run returns (and charges) only what it has never delivered before — plus, if you want, the listings whose price went down or up.
- 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy rotation and JSON/CSV/Excel export via the Apify platform.

### 🚀 How to scrape Yad2

1. Create a free Apify account.
2. Open **Yad2 Real Estate Scraper**, choose the **Deal type** (for sale, for rent, commercial) and type a **Location** (e.g. `Tel Aviv`).
3. Or paste your own Yad2 URLs into **Start URLs**: any real estate search page (the filters set on the site are kept — except « pets allowed » and « for roommates », which Yad2 does not let a scraper search: use the `petsAllowed` / `forRoommates` columns — pagination is automatic) or single listing pages.
4. Set **Max listings** (100 by default, 0 = no limit), tick the extra data you want, then click **Start**.
5. Download the dataset in JSON, CSV, Excel or via API.

### 💰 How much does it cost to scrape Yad2?

This Actor uses **pay per event** pricing: **$0.99 per 1,000 listings**, plus **$0.09 per 1,000 listings read with their listing page** (option, off by default), **$0.59 per 1,000 phone numbers**, **$4.59 per 1,000 listings with recorded sales nearby** and **$5.39 per 1,000 listings with a price trend**, and the `price-change` event for each listing that comes back because its price changed (only with **Also listings whose price changed**; its price is on the Pricing tab) — each option charged only when the listing really gets it — plus **$0.001 per run start** (free plan prices; lower on paid Apify plans). Example: 1,000 listings with their listing page = $1.08; with the phone numbers = $1.67; with phones and recorded sales = $6.26. Platform usage (compute, proxy) is included in the price.

### ⚙️ Input

```json
{
    "dealType": "rent",
    "location": "Tel Aviv",
    "maxPrice": 8000,
    "minRooms": 3,
    "requireSecureRoom": true,
    "extractDetails": true,
    "maxItems": 200
}
```

Several places, a cap per place, the phone numbers and the recorded sales nearby, only the listings not delivered before:

```json
{
    "dealType": "forsale",
    "locations": ["Haifa", "רמת גן", "city:8600"],
    "maxItemsPerQuery": 100,
    "includeContacts": true,
    "includeNearbyDeals": true,
    "onlyNew": true,
    "stateKey": "north-sales"
}
```

Or with your own URLs:

```json
{
    "startUrls": [
        { "url": "https://www.yad2.co.il/realestate/forsale?topArea=2&area=1&city=5000&minPrice=2000000&maxPrice=4000000" },
        { "url": "https://www.yad2.co.il/realestate/item/5mv5v9te" }
    ],
    "maxItems": 500
}
```

| Field | Notes |
| --- | --- |
| `dealType`, `commercialDealType` | `forsale`, `rent` or `commercial`; for commercial property, sale, rent or both. |
| `location`, `locations` | A city in English, with its usual spellings (`Tel Aviv`, `Haifa`, `Petah Tikva`, `Rishon LeZion`, `Beersheba`), or a city, neighbourhood, street or area in Hebrew (`פלורנטין`), or a Yad2 id (`city:5000`); one search per place. Neighbourhoods, streets and areas are found in Hebrew only. |
| `region` | A whole region when no location is given, or `all` (the 8 regions). |
| `query`, `searchQueries` | Free-text search of the site (Hebrew works best); one search per keyword × place (max 500 searches per run). |
| `startUrls` | Yad2 real estate search pages (filters kept, pagination automatic) or listing pages. When set, the search fields are ignored. |
| `propertyTypes`, `propertyConditions` | Only these property types / conditions (codes of the list in the form). |
| `minPrice`, `maxPrice`, `minRooms`, `maxRooms`, `minSquareMeters`, `maxSquareMeters`, `minFloor`, `maxFloor` | Ranges, applied by the site (price in shekels; half rooms allowed). |
| `requireParking`, `requireElevator`, `requireBalcony`, `requireSecureRoom`, `requireAirConditioning`, `requireStorage`, `requireAccessibility`, `requireWindowBars`, `requireRenovated`, `requireFurnished`, `exclusiveOnly`, `priceDroppedOnly`, `withPhotosOnly`, `withPriceOnly` | Only the listings that have it. |
| `sellerType` | `any`, `private` (owners) or `agency`. |
| `sortBy` | `newest` (default: last published or bumped first), `priceAsc`, `priceDesc`. |
| `maxItems` | Stop after this many listings for the whole run (`0` = unlimited). |
| `maxItemsPerQuery` | Cap for EACH search (place × keyword, or search URL). 0 = no per-search cap. |
| `extractDetails` | Open each listing page: description, dates, amenities, agency (default off). |
| `includeContacts` | Seller name and phone number(s), brokers' phones. |
| `includeNearbyDeals`, `nearbyDealsLimit` | The recorded sales closest to each listing (10 by default, up to 50). |
| `includePriceTrend` | Local asking price per m², month by month since 2023 (homes for sale). |
| `postedAfter`, `postedBefore` | Publication date range: `2026-09-01`, or a period before now (`7 days`, `2 weeks`, `1 month`, `24 hours`). Needs `extractDetails`. |
| `excludeKeywords` | Drop the listings whose title or features contain one of these words; the description too when **Listing details** is ticked. |
| `onlyNew`, `includePriceChanges`, `minPriceChangePercent`, `knownListingsDatasetId`, `knownListingIds`, `stateKey`, `resetState` | Monitoring: only the listings never delivered under this memory key, plus (option, needs `onlyNew`) those whose price moved by at least the given % (3 by default); `knownListingsDatasetId` / `knownListingIds` (need `onlyNew`) put the listings you already have in the memory, free; `resetState` forgets the memory. |
| Advanced | `proxyConfiguration` (Apify proxy by default, included in the price; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `minRequestIntervalMs`, `maxRequestRetries`, `stopOnBlocked` (off by default: stops the run at the first request Yad2 refuses, with no new try), `debugLog`. |

### 📦 Output

One real listing (Tel Aviv rent, 24/09/2026), the agent's name, licence and phone replaced, shortened: 51 of the 107 fields, 2 photos and 1 recorded sale of 10.

```json
{
    "id": "5mv5v9te",
    "url": "https://www.yad2.co.il/realestate/item/5mv5v9te",
    "board": "rent",
    "dealType": "rent",
    "sellerType": "agency",
    "title": "שדרות ירושלים 153",
    "adNumber": 44146687,
    "propertyType": "דירה",
    "propertyTypeEn": "apartment",
    "propertyConditionEn": "renovated",
    "rooms": 1,
    "squareMeters": 27,
    "floor": 2,
    "buildingFloors": 3,
    "features": [
        "חניה",
        "בהזדמנות",
        "חבל לפספס"
    ],
    "price": 2290,
    "currency": "ILS",
    "priceBefore": 2390,
    "priceDropped": true,
    "priceDropPercent": 4.2,
    "pricePerSqm": 85,
    "houseCommittee": 25,
    "regionEn": "Tel Aviv area",
    "city": "תל אביב יפו",
    "cityEn": "Tel Aviv-Yafo",
    "neighborhood": "מכללת תל אביב יפו, דקר",
    "street": "שדרות ירושלים",
    "houseNumber": "153",
    "latitude": 32.040514,
    "longitude": 34.756865,
    "imageUrl": "https://img.yad2.co.il/Pic/202609/19/2_6/o/y2_14_jSu49YWymg_20260919.jpeg",
    "images": [
        "https://img.yad2.co.il/Pic/202609/19/2_6/o/y2_14_jSu49YWymg_20260919.jpeg",
        "https://img.yad2.co.il/Pic/202609/16/2_6/o/y2_14__QRioU4P_r_20260916.jpeg"
    ],
    "imageCount": 14,
    "contactName": "ישראל ישראלי",
    "brokers": [
        {
            "name": "ישראל ישראלי",
            "licenseNumber": "0000000",
            "phone": "050-0000000"
        }
    ],
    "contactPhone": "050-0000000",
    "isVirtualPhoneNumber": true,
    "description": "ללא תיווך !!! חדר ענק 20 מטר בדירת שותפים עם מרפסת כולל חניה חינם 24/7 , חדר משו",
    "publishedAt": "2026-09-10T11:49:53.000Z",
    "bumpedAt": "2026-09-24T20:27:46.000Z",
    "entranceDate": "2026-09-30",
    "hasParking": true,
    "hasElevator": false,
    "hasSecureRoom": false,
    "hasAirConditioning": true,
    "nearbyDeals": [
        {
            "price": 1550000,
            "saleDate": "2019-03-13",
            "rooms": 3,
            "squareMeters": 57,
            "floor": 4,
            "buildingFloors": 4,
            "buildYear": 1970,
            "propertyType": "דירה בבית קומות",
            "address": "שדרות ירושלים, תל אביב יפו"
        }
    ],
    "changeType": null,
    "previousPrice": null,
    "priceChangePercent": null,
    "searchUrl": "https://www.yad2.co.il/realestate/rent?area=1&city=5000&region=3",
    "scrapedAt": "2026-09-24T20:33:00.556Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

#### All 107 fields

| Fields | What you get |
| --- | --- |
| `id`, `url`, `title`, `adNumber`, `orderId` | 🏷️ **Listing** — `5mv5v9te`, the listing page, `שדרות ירושלים 153` (street and number, as on the card), the ad number shown on Yad2 |
| `board`, `dealType`, `sellerType` | `forsale` / `rent` / `commercial`, `forsale` / `rent`, `private` (owner) / `agency` |
| `propertyType`, `propertyTypeEn`, `propertyTypeId`, `propertyGroup` | 🏠 **Property** — `דירה`, `apartment`, `1`, `apartments` |
| `propertyCondition`, `propertyConditionEn` | `משופץ`, `renovated` (new from the developer, new, renovated, well kept, needs renovation) |
| `rooms`, `squareMeters`, `squareMetersBuilt`, `floor`, `buildingFloors`, `balconies`, `parkingSpaces` | `3.5`, `85`, `80`, `3`, `6`, `1`, `1` |
| `features` | the feature tags of the card, in Hebrew — `קרוב לים` (close to the sea) |
| `price`, `currency`, `pricePerSqm` | 💰 **Price** — asking price or monthly rent in shekels (`null` when not shown), `ILS`, price per m² |
| `priceBefore`, `priceDropped`, `priceDropPercent` | the price before the last reduction, `true`, `4.2` |
| `houseCommittee`, `propertyTax`, `paymentsInYear` | monthly building fee (vaad bayit), arnona, rent payments a year |
| `region`, `regionId`, `regionEn`, `area`, `areaId`, `areaEn` | 📍 **Location** — region and area, Hebrew, id and English |
| `city`, `cityId`, `cityEn`, `neighborhood`, `neighborhoodId`, `street`, `streetId`, `houseNumber`, `address` | `תל אביב יפו`, `5000`, `Tel Aviv-Yafo`, neighbourhood, street, number, full address line |
| `latitude`, `longitude`, `shelterDistance` | GPS, distance to the closest public shelter in meters |
| `imageUrl`, `images`, `imageCount`, `videoUrl` | 📸 **Media** — main photo, every photo, photo count, video |
| `agencyName`, `agencyLogoUrl`, `agencyAbout`, `agencyLicenseNumber` | 🏢 **Agency** — name, logo, presentation, real-estate licence number |
| `sellerId`, `contactName`, `contactSecondName`, `brokers`, `isExclusive` | 👤 **Seller** — advertiser id (same for all listings of one seller), names, brokers with their licence number, exclusive listing |
| `contactPhone`, `contactSecondPhone`, `isVirtualPhoneNumber`, `hideNumberDuringWeekend` | 📞 **Phone** (**Seller phone numbers**) — `050-0000000` (as Yad2 writes it), second number, relay number, no calls on Shabbat |
| `description`, `publishedAt`, `updatedAt`, `bumpedAt`, `expiresAt` | 📝 **Listing page** — full description, first publication, last edit, last bump to the top, end of the ad |
| `entranceDate`, `isEntranceFlexible`, `isImmediateEntrance` | move-in date, flexible, immediate |
| `hasParking`, `hasElevator`, `hasBalcony`, `hasSecureRoom`, `hasBuildingShelter`, `hasAirConditioning`, `hasTornadoAirConditioning`, `hasBoiler`, `hasWindowBars`, `hasStorage`, `isFurnished`, `furnitureInfo`, `isAccessible`, `isRenovated`, `isKosherKitchen` | ✅ **Amenities** — `true` / `false` from the listing page (`null` without it); what furniture is included |
| `petsAllowed`, `forRoommates`, `isLongTermContract` | rentals: pets allowed, for roommates, long-term contract |
| `hasHighCeiling`, `hasAlarm`, `hasCameras`, `hasKitchenette`, `hasLoadingRamp`, `hasMeetingRoom`, `hasCommunicationRoom`, `isDivisible` | commercial property: high ceiling, alarm, cameras, kitchenette, loading ramp, meeting room, server room, divisible space |
| `nearbyDeals` | 🧾 **Recorded sales nearby** (option) — price, sale date, rooms, size, floor, building floors and year, address of the closest recorded sales |
| `priceTrend` | 📈 **Local price trend** (option) — `{ "month": "2026-08", "pricePerSqm": 43300 }`, every month since 2023 |
| `changeType`, `previousPrice`, `priceChangePercent` | **Monitoring**: `new`, `price_drop` or `price_rise`, previous price, change in % (null without `includePriceChanges`) |
| `searchUrl`, `scrapedAt` | the Yad2 results page it was found on, ISO timestamp |

### 💡 Tips

#### How to get more results

Set `maxItems` to `0` and search a whole city or region: a search of more than the 500 pages Yad2 serves (about 10,000 listings) is split by price automatically. With `sortBy` set to a price order, only the first 500 pages are read, in that order.

#### How to reduce costs

The price is per listing and per option, so the levers are `maxItems`, `maxItemsPerQuery`, the site's filters, and `onlyNew` for recurring runs (you never pay twice for the same listing). Leave **Listing details** off (the default) when the card fields are enough: the listing page is charged only when it is read.

#### Several searches in one run

Fill `locations` and / or `searchQueries`: the Actor runs one search per place × keyword (up to 500 per run). A listing found by several searches is saved — and charged — once. Set `maxItemsPerQuery` to give every search its own cap: without it the first searches can use up the whole `maxItems` budget. You can also paste several search URLs into `startUrls`: each one is a search of its own, with the same cap.

#### Monitoring: new listings and price changes

Tick **Only new listings** (`onlyNew`) and schedule the Actor. The first run returns everything; each later run skips the listings already delivered: they are not saved, not charged, and their page is not even opened. Tick **Also listings whose price changed** too, and a listing already delivered comes back when its price moved by at least **Min price change (%)** (3 % by default), with `changeType` = `price_drop` or `price_rise`, `previousPrice` and `priceChangePercent`; it is charged the `price-change` event on top of the options it holds, and a new listing is not. The price is read from the search page, so following the prices opens no extra page; with **Listing details** ticked, the page of a listing whose search price moved is opened, and if it still shows the price you were given nothing is returned or charged. The memory lives in a named key-value store of your account (`yad2-listings-scraper-seen`, up to 150,000 listings per key) and is only updated with listings that really reached the dataset, so a failed run never hides anything. Give each schedule its own `stateKey` (two schedules sharing a key would hide each other's listings), and tick `resetState` once to start over. Yad2 moves listings back to the top when they are bumped and does not sort a search by date, so each run reads the search page by page and a search stops once 3 results pages in a row (60 to 120 listings, depending on whether the pages hold one or both kinds of seller) hold only listings you already have; one new listing on a page starts that count again, and a new listing deeper than that waits for a later run: the more often you schedule the Actor, the fewer known listings can be bumped above a new one. The listings you already have cost nothing. A listing that does not pass a time-dependent filter yet (a relative "posted before" date) is checked again on the next run. The price memory keeps the last 100,000 listings per key (50,000 under 512 MB of run memory); past that, the ones not met for the longest time are forgotten. A run with **Max listings** stops at it, but the next run cannot always go on from there: the listings it delivered are skipped, and the search stops after 3 results pages in a row with nothing new, so the next run reaches the undelivered listings only while the delivered ones fill fewer than 60 to 120 positions of the search. To take a whole city or region, run once with **Max listings** at `0` (or above the total) instead of several capped runs; for a feed of new listings only, give the schedule a cap above what the search gets between two runs.

##### Already have the listings from another tool?

With **Only new listings** ticked, tell the Actor which listings you already have and it will not return them, not even once, and never charge them. Pick a dataset of your account in **Dataset of listings you already have** (a past run of this Actor, or the output of any other tool), and/or paste Yad2 listing tokens or links in **Listings you already have (IDs or links)**. The Actor can read the dataset you pick and nothing else of your account.

- Each row is read for its listing token: in `id`, else in a Yad2 link found in `url`, `link`, `adUrl` or `listingUrl` (`https://www.yad2.co.il/realestate/item/5mv5v9te`, with or without the city in the path). Rows with no token are counted in the log and ignored, and so is a pasted entry of more than 2,000 characters (the log says how many).
- Nothing is written to your dataset and nothing is charged for them. They go straight into the memory of the **Memory key**, before the listing pages of Yad2 are read, so the first run already returns only what is new. The memory keeps up to 150,000 listings per key: if the import does not fit, the log says how many were left out and why; room is kept in the memory for the listings of the run itself, so the import never fills it up.
- With **Also listings whose price changed** ticked, the `price` of a row (a number above 0) becomes the price known: a listing that has not moved is skipped, and one that moved comes back as `price_drop` or `price_rise` instead of as a new listing. A row that comes from a listing page of this Actor (it has an `adNumber` or a `publishedAt`) is not mistaken for a search-page price: it never causes a false change on the first pass.
- The import runs once per run; if the dataset cannot be read, the run stops before it asks Yad2 for anything.

#### Filter by publication date

`postedAfter` and `postedBefore` take a date (`2026-09-01`, the whole day is included, Israel time) or a period before now (`7 days`, `2 weeks`, `1 month`; via the API also `24 hours` or a full ISO date-time). The filter reads `publishedAt`, the first publication read on the listing page, so it needs **Listing details**. Filtered-out listings are never charged and do not count in `maxItems`; the run summary tells how many were filtered.

#### Phone numbers

Yad2 gives a limited number of phone numbers to each visitor in a short time. With the default Apify proxy, each refused number is asked again from a new address; a listing whose number is still refused is saved without it, and not charged for it. Without a proxy, the run stops asking numbers after 3 refusals in a row and says so in the log.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one item per Yad2 property listing. Actor id: `nice_dev/yad2-listings-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/yad2-listings-scraper`.

Smallest input, for a cheap first call:

```json
{
    "location": "Tel Aviv",
    "maxItems": 10
}
```

Key output fields: `url`, `dealType`, `price`, `rooms`, `squareMeters`, `floor`, `address` and `contactPhone` (with `includeContacts`).

Cost: $0.99 per 1,000 listings, plus $0.09 per 1,000 listings read with their listing page (option, off by default: $1.08 per 1,000 with it ticked, for the first input above), plus $0.001 per run start (free plan prices; lower on paid Apify plans). Phone numbers, recorded sales and price trends cost extra, see the pricing section above. Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`.

### ❓ FAQ

#### Is it legal to scrape Yad2?

The Actor only reads what Yad2 shows publicly to any anonymous visitor. It logs in to nothing and solves no captcha. Results can contain personal data (sellers' names and, with the option, phone numbers), which is protected by Israel's Privacy Protection Law and the GDPR: do not store it without a legitimate reason, and do not use it for unsolicited messages. You are responsible for using the data in compliance with Yad2's Terms of Use and applicable law. This Actor is not affiliated with Yad2.

#### Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds). To never insist after a refusal, turn on **Stop at the first refusal**: the run ends at the first request Yad2 refuses (a refused phone number included), with no new try and no other proxy address, and keeps what it already saved.

#### Why are some texts in Hebrew?

Street, neighbourhood, city, property type, condition, features and descriptions are given exactly as Yad2 stores them, in Hebrew. The fields with a fixed vocabulary also have an English twin: `cityEn`, `regionEn`, `areaEn`, `propertyTypeEn`, `propertyConditionEn`.

#### Is the data safe to open in Excel or to show on a web page?

Titles and descriptions are the sellers' own words, copied as they are. A text can begin with `-`, `+`, `=` or `@`: Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. Every URL field holds an http(s) URL or `null`. On a web page, escape every field like any text written by a stranger.

#### Known limitations

- Neighbourhoods, streets and areas are found by their Hebrew name only; cities in English or Hebrew. A town known in English by another name than Yad2's (`Akko` for Acre, `Tzfat` for Safed) is typed as Yad2 writes it, in Hebrew, or as `city:<id>`.
- Yad2 sorts private listings and agency listings separately, and each results page gives its private listings first: with a price sort, a capped run gets the cheapest (or dearest) of each group, so with all sellers a cap of 20 or less may hold private listings only.
- The price trend exists for homes for sale only; recorded sales need the listing's GPS.
- `onlyNew` alone remembers listing ids, not their content: a listing whose price changed is returned again only with **Also listings whose price changed**, and only the price is followed (not the other fields).
- Two runs sharing the same `stateKey` at the same time may both return the same new listing.

**A run the platform stops without warning** (out of memory, run timeout)

- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the listings already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them.
- With `onlyNew`, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the listings it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the listings of its last 2 seconds once more.

#### Something doesn't work?

The last line of the log counts the listings saved, filtered out and no longer on Yad2 (removed while the run was reading them), and the requests that failed after every retry. Those requests and the removed listings are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause.

If Yad2 changes its pages, you are told instead of paying for blank rows. A results page that counts listings but gives none the Actor can read is an error (listed in `FAILED_REQUESTS`), never a quiet "No listings found". If the first 20 listings read all lack their city, their property type or — with `extractDetails` — their description or publication date, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first listings are charged.

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` record of the key-value store show exactly which URLs failed and why.

# Actor input Schema

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

Yad2 real estate search URLs (`https://www.yad2.co.il/realestate/forsale?topArea=2&area=1&city=5000`, and the same for rent and commercial pages — the filters set on the site are kept except pets allowed / for roommates, which Yad2 refuses to scrapers — use the petsAllowed / forRoommates columns; pagination is automatic) or single listing URLs (`https://www.yad2.co.il/realestate/item/5mv5v9te`). When this list is not empty, the search fields below (deal type, locations, keywords, search filters) are ignored; caps, post-filters, options and monitoring still apply. Max 1 000 URLs.

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

Which Yad2 board to search: homes for sale, homes for rent, or commercial property (offices, shops, warehouses…).

## `commercialDealType` (type: `string`):

Only for **Deal type** = Commercial: both, sale only or rent only.

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

A city in English (`Tel Aviv`, `Haifa`, `Petah Tikva`: the usual spellings work), or a city, neighbourhood, street or area in Hebrew (`תל אביב יפו`, `פלורנטין`), or a Yad2 id such as `city:5000`. The first match is used and written in the log. Empty = the whole **Region** (or all of Israel).

## `locations` (type: `array`):

Several places in one run: one search per place (times each keyword below, max 500). Added to **Location**; listings found by several searches are saved once.

## `region` (type: `string`):

Search a whole Yad2 region when **Location** is empty; the first choice walks the 8 regions one after another. Ignored when a location is given (its region is found automatically).

## `query` (type: `string`):

Free-text search of the site (Hebrew works best, e.g. `ים` for sea view). Empty = no keyword.

## `searchQueries` (type: `array`):

Several keywords in one run: one search per keyword (times each location). Added to **Search keyword**.

## `propertyTypes` (type: `array`):

Only these property types (any of them). Empty = all types. Homes and commercial types are listed together: pick the ones of your **Deal type**.

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

Minimum price in Israeli shekels (monthly rent for rentals).

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

Maximum price in Israeli shekels (monthly rent for rentals).

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

Minimum number of rooms (half rooms allowed, e.g. `2.5`).

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

Maximum number of rooms.

## `minSquareMeters` (type: `integer`):

Minimum floor area in square meters.

## `maxSquareMeters` (type: `integer`):

Maximum floor area in square meters.

## `minFloor` (type: `integer`):

Lowest floor (ground floor = 0).

## `maxFloor` (type: `integer`):

Highest floor (ground floor = 0).

## `propertyConditions` (type: `array`):

Only listings in one of these conditions. Empty = any condition.

## `sellerType` (type: `string`):

Private owners only, agencies (brokers) only, or both.

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

Only listings with parking.

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

Only listings with an elevator.

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

Only listings with a balcony.

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

Only listings with a secure room (ממ״ד).

## `requireAirConditioning` (type: `boolean`):

Only listings with air conditioning.

## `requireStorage` (type: `boolean`):

Only listings with a storage room.

## `requireAccessibility` (type: `boolean`):

Only listings accessible to people with disabilities.

## `requireWindowBars` (type: `boolean`):

Only listings with window bars (סורגים).

## `requireRenovated` (type: `boolean`):

Only listings marked as renovated.

## `requireFurnished` (type: `boolean`):

Only furnished listings.

## `exclusiveOnly` (type: `boolean`):

Only listings marketed exclusively by one agency.

## `priceDroppedOnly` (type: `boolean`):

Only listings whose price was reduced (the previous price is in `priceBefore`).

## `withPhotosOnly` (type: `boolean`):

Skip listings without any photo.

## `withPriceOnly` (type: `boolean`):

Skip listings whose price is not shown.

## `sortBy` (type: `string`):

Order in which Yad2 returns the listings (applied by the site before collection, so a capped run gets the right end of each group). Newest first = most recently published or bumped first. Yad2 sorts private listings and agency listings separately and gives the private ones first on each page: with all sellers, a cap of 20 or less may hold private listings only.

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

Maximum number of listings to save for the whole run (after deduplication and filters). 0 = no limit.

## `maxItemsPerQuery` (type: `integer`):

Cap for EACH search (location × keyword, or search URL), so that the first search cannot use up the whole **Max listings** budget. 0 = no per-search cap.

## `extractDetails` (type: `boolean`):

Open each listing (1 extra request) for the description, publication / update dates, all amenities, entrance date, building floors, parking spaces, agency and licence numbers, English place names. Needed by **Posted after / before**. Off by default: tick it to get these fields.

## `includeContacts` (type: `boolean`):

Seller name and phone number(s), and each broker's phone and licence number (1 extra request per listing; with Listing details off, the listing page is read too, and not charged). Yad2 hands out a limited number of phone numbers per IP address, so runs with this option are slower.

## `includeNearbyDeals` (type: `boolean`):

Closest recorded sales (sale price, date, rooms, size, floor, building year, address) around each listing, from Yad2's sold-property data. Turns on **Listing details**.

## `nearbyDealsLimit` (type: `integer`):

How many nearby recorded sales to attach to each listing (closest first).

## `includePriceTrend` (type: `boolean`):

Monthly average asking price per m² for comparable homes around each listing since 2023 (for-sale homes only). Turns on **Listing details**.

## `postedAfter` (type: `string`):

Only listings first published on or after this date: `2026-09-01`, or a period before now such as `7 days`, `2 weeks`, `1 month` (API: `24 hours` and full ISO date-times work too). Needs **Listing details**.

## `postedBefore` (type: `string`):

Only listings first published on or before this date (the whole day is included), or older than a period such as `30 days`. Needs **Listing details**.

## `excludeKeywords` (type: `array`):

Drop the listings whose title or features contain one of these words (case ignored); the description too when Listing details is ticked.

## `onlyNew` (type: `boolean`):

Skip the listings that a previous run (same **Memory key**) already delivered: they are not saved and not charged, and their page is not even opened. First run = everything is new.

## `includePriceChanges` (type: `boolean`):

With **Only new listings**: also return the listings already delivered whose price went up or down since the last row delivered (`changeType` = `price_drop` / `price_rise`, with `previousPrice` and `priceChangePercent`). Charged per price change delivered (event `price-change`). A listing without a price is never a change.

## `minPriceChangePercent` (type: `number`):

With **Also listings whose price changed**: a listing comes back only if its price moved by at least this many percent.

## `stateKey` (type: `string`):

Name of the memory used by **Only new listings**. Give each schedule / task its own key (e.g. `tlv-rentals`) so that they do not share their memory. Letters, digits, `-` and `_`.

## `resetState` (type: `boolean`):

Forget everything remembered under this **Memory key** before the run: this run returns (and charges) every listing again. Untick it afterwards.

## `knownListingsDatasetId` (type: `string`):

With **Only new listings**: a dataset of your account (a past run of this Actor, or any other tool) whose listings are put in the memory as already delivered, before the site is read: they are never returned and never charged. The token is read in `id`, or in a Yad2 link (`url`, `link`, `adUrl`, `listingUrl`). With **Also listings whose price changed**, a `price` above 0 becomes the price known. The Actor can read this dataset only.

## `knownListingIds` (type: `array`):

With **Only new listings**: Yad2 listing tokens (`5mv5v9te`) or links (`https://www.yad2.co.il/realestate/item/5mv5v9te`) put in the memory as already delivered: never returned, never charged. Up to 100 000; for more, use the dataset field.

## `proxyConfiguration` (type: `object`):

Apify Proxy or your own proxies. Keep the default: it is included in the price. The residential Apify proxy is not available in this Actor.

## `maxConcurrency` (type: `integer`):

Maximum number of requests processed in parallel.

## `maxRequestsPerMinute` (type: `integer`):

Most requests to Yad2 in any 60 seconds, all of them counted: results pages, listing pages and the extra pages read for a listing (phone numbers, recorded sales, price trend). A budget, not an even pace: up to this many can leave at once when the minute starts (spread them with the minimum delay below). Lower it if the site answers HTTP 429 / 403 in the log.

## `minRequestIntervalMs` (type: `integer`):

Smallest gap between two requests, in milliseconds. Unlike the per-minute rate, this spreads the requests evenly instead of letting them go out in a burst. 0 = no gap.

## `maxRequestRetries` (type: `integer`):

Retries per request before it is marked as failed. Behind a proxy, a request the site turns away is also retried on a new proxy session up to 10 times without using up these retries.

## `stopOnBlocked` (type: `boolean`):

Stop the run as soon as Yad2 refuses one request (HTTP 403, 429 or a verification page). That request is not tried again, no other proxy address is tried and no more requests are sent. The listings already saved are kept and charged as usual. A refused phone number counts as a refusal too. Off = a refused request is tried again on another address.

## `debugLog` (type: `boolean`):

Include debug messages in the run log.

## Actor input object example

```json
{
  "startUrls": [],
  "dealType": "rent",
  "commercialDealType": "any",
  "location": "Tel Aviv",
  "locations": [],
  "region": "all",
  "searchQueries": [],
  "propertyTypes": [],
  "propertyConditions": [],
  "sellerType": "any",
  "requireParking": false,
  "requireElevator": false,
  "requireBalcony": false,
  "requireSecureRoom": false,
  "requireAirConditioning": false,
  "requireStorage": false,
  "requireAccessibility": false,
  "requireWindowBars": false,
  "requireRenovated": false,
  "requireFurnished": false,
  "exclusiveOnly": false,
  "priceDroppedOnly": false,
  "withPhotosOnly": false,
  "withPriceOnly": false,
  "sortBy": "newest",
  "maxItems": 100,
  "maxItemsPerQuery": 0,
  "extractDetails": false,
  "includeContacts": false,
  "includeNearbyDeals": false,
  "nearbyDealsLimit": 10,
  "includePriceTrend": false,
  "excludeKeywords": [],
  "onlyNew": false,
  "includePriceChanges": false,
  "minPriceChangePercent": 3,
  "stateKey": "default",
  "resetState": false,
  "knownListingIds": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8,
  "maxRequestsPerMinute": 300,
  "minRequestIntervalMs": 0,
  "maxRequestRetries": 5,
  "stopOnBlocked": false,
  "debugLog": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "dealType": "rent",
    "location": "Tel Aviv",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/yad2-listings-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 = {
    "dealType": "rent",
    "location": "Tel Aviv",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/yad2-listings-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 '{
  "dealType": "rent",
  "location": "Tel Aviv",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/yad2-listings-scraper --silent --output-dataset

```

## MCP server setup

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