# Rightmove Scraper: UK Property Listings & Price Drops (`datasmithlab/rightmove-property-scraper`) Actor

UK homes for sale and rent from Rightmove with price per m², EPC, tenure and floor area. Track new listings, price drops and removed homes between runs. Search by town or URL; bedrooms, coordinates, agent and photos.

- **URL**: https://apify.com/datasmithlab/rightmove-property-scraper.md
- **Developed by:** [Datasmithlab](https://apify.com/datasmithlab) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 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

## Rightmove Scraper: UK Property Listings & Price Drops

Export homes for sale and to rent from [Rightmove](https://www.rightmove.co.uk) by **town name** or **search URL**, with price, bedrooms, **floor area in m² and price per m²**, EPC rating, tenure, coordinates, agent and photos.

Turn on **tracking** and every later run returns only what changed: **new listings, price drops, price rises and removed homes**, with the previous price and the % change. Schedule it daily and you have a price-drop alert for any area.

No proxy, no login. Only estate agents' business details; phone numbers and emails inside free-text descriptions are masked.

### What you get

- **Clean numbers.** `£650,000` → `price: 650000`, `currency: "GBP"`. Rent comes with `pricePeriod: "month"` or `"week"`. Floor area is converted from sq ft to **m²**, and `pricePerSqm` is computed for homes for sale.
- **Change tracking.** With *Only new, price-changed and removed listings* on, each row has `changeType`: `NEW`, `PRICE_DROP`, `PRICE_UP` or `REMOVED`, plus `previousPrice`, `priceChange`, `priceChangePct` and `firstSeenAt`. Unchanged listings are not returned and **not charged**.
- **Rightmove's own flag** too: `portalUpdateReason` (for example `new` or `price_reduced`) is included whenever Rightmove provides it, even without tracking.
- **Search by town** (`Manchester`, `Milton Keynes`, `Hackney`...) with filters for price, bedrooms, property type, radius, "added in the last N days" and sold STC / let agreed. Or paste a Rightmove search URL with your own filters (filters the Actor doesn't support are listed under `ignoredUrlParams` in the `SEARCHES` report).
- **Full details (optional).** Open each listing to add the full description, postcode, exact floor area, council tax band, service charge, ground rent, lease length, nearest stations with distance, floorplans, parking, garden and heating.
- **Reports** in the run's key-value store: `SEARCHES` (location found, listings available, pages read, status per search) and `HEALTH`. If Rightmove blocks the run or changes its page format, you get a clear message instead of an empty dataset.

### How to search

| You want | Set |
|---|---|
| Homes for sale in a town | **Towns or areas** `Manchester` |
| Rentals | **Buy or rent** `To rent` |
| 2+ bed flats under £250k | **Min bedrooms** `2`, **Max price** `250000`, **Property types** `Flat` |
| Only what's new today | **Added or reduced in the last** `24 hours` |
| A search you already set up on Rightmove | Paste it in **Rightmove search URLs** |
| A daily price-drop alert | Turn on tracking and schedule the Actor daily |

Town names are the ones Rightmove uses (`property-for-sale/Milton-Keynes.html` → `Milton Keynes`). If a name doesn't exist, the `SEARCHES` report says so.

Rightmove shows at most **42 pages (about 1,000 listings) per search**. For big cities, search by area (`Hackney`, `Camden`...) or add filters; the report marks a search as `capped` when listings were left out.

### Output example

```json
{
  "id": "rightmove:93025995",
  "url": "https://www.rightmove.co.uk/properties/93025995",
  "title": "4 bedroom house for sale",
  "transaction": "sale",
  "propertyType": "House",
  "price": 650000,
  "currency": "GBP",
  "priceText": "£650,000",
  "pricePerSqm": 3611,
  "bedrooms": 4,
  "bathrooms": 3,
  "areaSqm": 180.0,
  "address": "Poulter Croft, Middleton, Milton Keynes",
  "latitude": 52.042858,
  "longitude": -0.715468,
  "tenure": "FREEHOLD",
  "listedAt": "2026-09-11T10:58:29Z",
  "updatedAt": "2026-10-07T16:37:59Z",
  "portalUpdateReason": "price_reduced",
  "agencyName": "Cauldwell Property Services",
  "imageCount": 35,
  "changeType": "NEW",
  "previousPrice": null,
  "firstSeenAt": "2026-10-08T00:00:30Z"
}
```

On a later run, the same home after a price cut would come back as `"changeType": "PRICE_DROP"` with `previousPrice`, `priceChange` and `priceChangePct` filled in.

With details on, rows also include for example:

```json
{
  "postcode": "N4 2NE",
  "councilTaxBand": "C",
  "nearestStations": [{"name": "Manor House Station", "distanceMiles": 0.26, "types": ["LONDON_UNDERGROUND"]}],
  "floorplanUrls": ["https://media.rightmove.co.uk/property-floorplan/..."],
  "description": "Amazing one bedroom apartment to rent in the popular..."
}
```

### Pricing

You pay per row: one price for a listing from the search results and a higher one for a listing opened with full details. Rows filtered out, and unchanged listings in tracking mode, are free.

### Good to know

- **Tracking memory** is kept per set of searches and filters. Change the towns or filters and the next run starts fresh (everything is `NEW` once). `REMOVED` means the home is **no longer in your search results**: usually sold, let or withdrawn, but also a home whose new price moved outside your price filter, or one now under offer when *sold STC* is off. It is reported only when every search was read completely, never with *Added or reduced in the last N days* (homes simply age out of that window), and not when more than half of the remembered homes vanish at once (that looks like an incomplete page, so they are kept for the next run).
- **Floor area** is only there when the agent published it (often on the listing page only, so *full details* fills more of them).
- **Agents only.** Rightmove listings come from estate agents; the agent's name, branch address and office phone are included as business contact details. No private individual's data is collected, and phone numbers or emails written inside descriptions are replaced with `[phone removed]` / `[email removed]`.
- **If Rightmove blocks the run**, the search is reported as `blocked` and the run stops. Try again later. The Actor reads Rightmove's public pages politely (about one request per second) and does not use proxies or any workaround.
- This Actor is independent and not affiliated with Rightmove.

Found a bug or need a field? Open an issue on this page. We read every one and reply.

# Actor input Schema

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

Place names as Rightmove spells them, one per line, e.g. 'Manchester', 'Milton Keynes', 'Hackney'. Each becomes one search.

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

Or paste search pages from rightmove.co.uk (property-for-sale or property-to-rent). The filters in the URL are kept; the filters below are not applied to pasted URLs.

## `transaction` (type: `string`):

For town names above.

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

Rent: monthly price.

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

Rent: monthly price. Leave empty for no limit.

## `minBedrooms` (type: `integer`):

0 = studio.

## `maxBedrooms` (type: `integer`):

Leave empty for no limit.

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

Leave empty for all types.

## `addedWithinDays` (type: `string`):

Rightmove's own 'added to site' filter (includes recent price reductions).

## `radiusMiles` (type: `string`):

Extend each town search by this many miles.

## `includeUnderOffer` (type: `boolean`):

Also return homes already under offer.

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

Order of Rightmove search results.

## `onlyNewOrChanged` (type: `boolean`):

Remembers every listing per set of searches. Later runs return only NEW listings, PRICE_DROP / PRICE_UP (with previous price and % change) and REMOVED listings (gone from your search results; not reported with 'Added or reduced in the last'). Schedule it daily for a price-drop alert.

## `includeDetails` (type: `boolean`):

Adds full description, postcode, exact floor area, council tax band, service charge, lease length, nearest stations, floorplans, parking, garden and heating. Slower and charged as 'listing with details'.

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

Stop after this many rows (you are charged per row).

## `maxPagesPerSearch` (type: `integer`):

24 listings per page. Rightmove shows at most 42 pages (about 1,000 listings) per search; split big cities into areas to get more.

## Actor input object example

```json
{
  "locations": [
    "Manchester"
  ],
  "transaction": "sale",
  "includeUnderOffer": false,
  "sort": "newest",
  "onlyNewOrChanged": false,
  "includeDetails": false,
  "maxItems": 200,
  "maxPagesPerSearch": 42
}
```

# Actor output Schema

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

Listings (table view, JSON/CSV/Excel export).

## `allFields` (type: `string`):

Every field, including photos, key features and details.

## `searches` (type: `string`):

For each search: location found, listings available, pages read, status.

## `health` (type: `string`):

Empty-field ratios, failed searches, detail errors.

# 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 = {
    "locations": [
        "Manchester"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datasmithlab/rightmove-property-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 = { "locations": ["Manchester"] }

# Run the Actor and wait for it to finish
run = client.actor("datasmithlab/rightmove-property-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 '{
  "locations": [
    "Manchester"
  ]
}' |
apify call datasmithlab/rightmove-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datasmithlab/rightmove-property-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/FNSvqhE7PS0GlbIiH/builds/Yoga8CPDYB49oGPwD/openapi.json
