# Madlan New Listings Monitor - New Apartments and Price Changes (`leadproof/madlan-new-listings-monitor`) Actor

- **URL**: https://apify.com/leadproof/madlan-new-listings-monitor.md
- **Developed by:** [Lead Proof](https://apify.com/leadproof) (community)
- **Categories:** Real estate, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 new listing or price changes

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

## Madlan New Listings Monitor

Watch a Madlan real-estate search and get only the listings Madlan publishes after the monitor starts, plus price changes. Schedule it every 15 minutes, every hour or once a day: each run is one check.

### Why this Actor

- **Only new listings, never old ones sent as new.** The first run records the start and delivers nothing. After that, a listing is delivered only when Madlan first saw it after the monitor started. An older listing that comes back to the top after a refresh is never charged as new.
- **Cheap, frequent checks.** Madlan can sort a search newest first. A check reads from the newest end until it reaches listings from before the previous check, so a check of all apartments for sale in Tel Aviv reads a few pages, not thousands of listings.
- **Price changes from the listing's own history.** A price drop or rise since the previous check is delivered with the previous price, for every listing the check reads.
- **One check at a time.** Two runs of the same monitor never overlap: a run that starts while another is still checking steps back without charging.
- **Alerts.** Give a webhook URL and get a POST whenever a check is partial or fails.

### Quick start

1. Set **Transaction** and a **City** (or paste a Madlan search URL, for example a neighbourhood).
2. Give the watch a **Monitor name**, for example `tlv-sale`.
3. Run it once. That first run records the start.
4. Schedule the Actor, for example every hour, and connect the dataset to email, Slack, a sheet or your own system.

```json
{
  "transactionType": "sale",
  "filters": {"city": "תל אביב יפו", "minRooms": 3, "maxPrice": 4000000},
  "monitorName": "tlv-sale-3-rooms",
  "webhookUrl": "https://example.com/madlan-alerts"
}
```

Or watch a search you set up on the site:

```json
{
  "searchUrls": ["https://www.madlan.co.il/for-rent/חיפה-ישראל?filters=_0-6000_3-4"],
  "monitorName": "haifa-rent"
}
```

### How a check works

Every check asks Madlan for the search sorted by date, newest first. A new listing, a price change and a refresh all move a listing to the front. The check reads pages from the front until a whole page is older than the previous check (with a three-hour overlap, because Madlan shows a listing about an hour after it first sees it). A listing is new when Madlan's own first-seen time is after the monitor started.

If a check would need more pages than **Pages per check, at most**, it delivers what it read and is marked partial; raise the cap for a big city checked rarely.

### Output

One row per new listing or price change, in the same shape as the Madlan rows of [Israel Real Estate Scraper](https://apify.com/leadproof/israel-real-estate):

| Field | Meaning |
|---|---|
| `changeType` | `new` or `price_changed` |
| `id`, `url` | Madlan listing ID and link |
| `title`, `description` | Property type, street and city; description when Madlan shows one |
| `price`, `previousPrice`, `priceChangedAt` | Price in ILS; for a price change, the price before and the date of the change |
| `location`, `attributes` | Street, neighborhood, city, coordinates, rooms, size, floor, property type, condition, building year, amenities, neighborhood scores, price history |
| `images` | Public image URLs (not downloaded) |
| `publishedAt`, `updatedAt` | When Madlan first saw the listing and when it was last updated |
| `seller` | `private` or `agency`, and exclusivity when shown |
| `monitor` | `changeType`, `monitorName`, `checkedAt` |

Each run also writes a `SUMMARY` record: status (`baseline`, `succeeded`, `partial`, `skipped`, `failed`), listings checked, new listings, price changes, pages read and the point the check read back to.

### Pricing

Pay per event, platform usage included:

- **Check:** a small fee per search checked.
- **Listings checked:** a fee per 100 listings read in a check.
- **New listing or price change:** per delivered row.

The first run of a monitor is charged as a check and delivers nothing. The exact prices are on the Pricing tab. Narrower searches and less frequent checks cost less.

### Good to know

- Use one **Monitor name** per search. Changing the search under the same name keeps the old memory.
- Memory lives in the named key-value store `madlan-new-listings-monitor` in your Apify account. Delivered listings unseen for 60 days are dropped from it.
- A partial check (some pages refused) still delivers what it found; the next check reads back further.
- Price changes are found on the listings a check reads, which are the ones Madlan moved to the front since the previous check. A price change Madlan does not move to the front is not seen.
- Filters other than city, price, rooms, size, property type, parking and elevator are not available: Madlan applies these itself, so a check never has to read listings it would throw away.
- The Actor reads public Madlan pages through Israeli residential proxies, retrying refused requests from other IPs. It has no official agreement with Madlan.

### Related LeadProof actors

- [Israel New Listings Monitor](https://apify.com/leadproof/israel-new-listings-monitor): this watch and the Yad2 one together, one feed, an apartment on both sites delivered once.
- [Yad2 New Listings Monitor](https://apify.com/leadproof/yad2-new-listings-monitor): the same watch for Yad2.
- [Israel Real Estate Scraper](https://apify.com/leadproof/israel-real-estate): Yad2 and Madlan listings in one run.

Questions or a custom watch: support@leadproof.co. Built by [LeadProof](https://leadproof.co).

# Actor input Schema

## `transactionType` (type: `string`):

Which Madlan board to watch. Commercial watches both commercial rent and sale.

## `filters` (type: `object`):

The search to watch. City is required unless you give search URLs. Madlan applies every filter here itself.

## `searchUrls` (type: `array`):

Optional. Madlan search URLs copied from the browser, for example https://www.madlan.co.il/for-sale/תל-אביב-יפו-ישראל, including neighbourhood searches. The place and the filters in the URL are watched. Use these or Filters.

## `monitorName` (type: `string`):

Name of this watch, for example tlv-sale. Each name keeps its own memory, so use one name per search. Without a name the memory is keyed to the search itself.

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

Also deliver listings whose price went up or down since the previous check, marked changeType price_changed with previousPrice. Charged like a new listing.

## `maxPages` (type: `integer`):

A check reads pages from the newest end until it reaches listings from before the previous check. This caps that read; raise it for a whole big city checked rarely.

## `webhookUrl` (type: `string`):

Optional. Receives a JSON POST when a check is partial or fails, with the reason.

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

Israeli residential proxy by default. Every request uses a new IP.

## Actor input object example

```json
{
  "transactionType": "sale",
  "filters": {
    "city": "תל אביב יפו",
    "minRooms": 3
  },
  "monitorName": "tlv-sale-3-rooms",
  "includePriceChanges": true,
  "maxPages": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IL"
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

New listings and price changes found by this check.

## `csv` (type: `string`):

The same rows as CSV.

## `summary` (type: `string`):

Status, listings checked, new listings, price changes, pages read.

# 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 = {
    "transactionType": "sale",
    "filters": {
        "city": "תל אביב יפו",
        "minRooms": 3
    },
    "monitorName": "tlv-sale-3-rooms",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "IL"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("leadproof/madlan-new-listings-monitor").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 = {
    "transactionType": "sale",
    "filters": {
        "city": "תל אביב יפו",
        "minRooms": 3,
    },
    "monitorName": "tlv-sale-3-rooms",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "IL",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("leadproof/madlan-new-listings-monitor").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 '{
  "transactionType": "sale",
  "filters": {
    "city": "תל אביב יפו",
    "minRooms": 3
  },
  "monitorName": "tlv-sale-3-rooms",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IL"
  }
}' |
apify call leadproof/madlan-new-listings-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,leadproof/madlan-new-listings-monitor"
        }
    }
}
```

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/60L0u1W5gdienmjoX/builds/H6O6Qn5QsKAyyqZpo/openapi.json
