# Rightmove Property Scraper (`superslowsloth/rightmove-listings-scraper`) Actor

Scrape UK property listings from Rightmove - price, address, bedrooms, tenure, floor area, coordinates, agent and photos, for sale or to rent, by town, postcode or region.

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

## Pricing

from $0.63 / 1,000 listing scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Rightmove Property Scraper

Returns UK property listings from [Rightmove](https://www.rightmove.co.uk) - the
asking price, the address, bedrooms and bathrooms, tenure, floor area,
coordinates, the marketing agent and every photo on the listing - for sale or
to rent.

Search by town, region, postcode or outcode. Filter by price, bedrooms,
property type and radius, and sort by newest so a repeated run tells you what
came on the market since the last one.

### You can type a place name

Rightmove itself is keyed on internal location ids such as `REGION^87490`, and
nothing on the site will take a place name in their place. This actor looks up
whatever you type in Rightmove's own location list and uses the best match, so
`London`, `SW1A` and `Manchester` all work. If you already hold an id, paste it
and no lookup request is spent.

### Every listing is delivered and charged exactly once

De-duplication is global across the whole run, and it happens *before* the
charge. It is needed for two real reasons, not as a precaution:

- A property matches more than one of your locations whenever they overlap, and
  a search radius makes that the normal case rather than the exception.
- Rightmove inserts listings that agents paid to feature above the ordinary
  results, so the same property can arrive in a featured slot and again in its
  own position.

### What a "page" means here, and why the budget is in listings

A Rightmove page carries 24 ordinary results plus any featured listings on top,
so a page is 24 or 25 rows depending on what the agents bought that day. Every
budget in this actor is therefore expressed in listings, never in pages:
`maxItems` is a count of rows you will be charged for.

Rightmove refuses to page past an offset of 1008 - about 42 pages - and serves
the last page it will serve rather than an error. The walk stops there instead
of paying for rows it has already delivered.

### Output fields

| Field | Notes |
|---|---|
| `id` | Rightmove's property id. Stable, and what a repeated run joins on. |
| `url` | Canonical listing URL, with the channel fragment Rightmove's own links carry. |
| `display_address` | The address as the agent published it. |
| `transaction_type`, `channel` | `buy`/`rent`, and Rightmove's own `BUY`/`RENT`. |
| `price` | Asking price in whole pounds; per month on a rental. |
| `price_frequency` | `monthly` on most rentals, `not specified` on sales. |
| `price_display`, `price_qualifier` | The price as printed, and `Offers Over`, `Guide Price` and so on. |
| `bedrooms`, `bathrooms` | Counts. `0` bedrooms is a real answer on a studio. |
| `property_sub_type` | `Flat`, `Detached`, `Terraced`... as printed. |
| `tenure` | `FREEHOLD`, `LEASEHOLD`, `SHARE_OF_FREEHOLD`. |
| `display_size` | Floor area as printed, e.g. `1,432 sq. ft.`. |
| `latitude`, `longitude` | Rightmove's own coordinates for the property. |
| `summary`, `key_features` | The agent's blurb, and bullet points where the listing carries them. |
| `first_visible_date`, `update_date` | When the listing appeared and when it last changed, ISO-8601 UTC. |
| `added_or_reduced`, `listing_update_reason` | `Reduced on 07/09/2026`, and `price_reduced`/`new`. |
| `let_available_date` | Rentals only: when the property is free to move into. |
| `agent_name`, `agent_branch`, `agent_phone`, `agent_url`, `agent_logo_url` | The marketing agent. |
| `featured`, `premium` | Whether the agent paid for the listing to be surfaced. |
| `auction`, `development`, `students` | Listing flags as Rightmove sets them. |
| `fees_apply`, `fees_apply_text` | Tenant fees, on rentals that state them. |
| `image_count`, `floorplan_count`, `image_urls`, `virtual_tour_urls` | Media on the listing. |
| `search_location`, `location_identifier` | Which of your searches produced this row. |

### What this source does not give

Stated rather than guessed. A missing value is always `null`, never `0` and
never an empty string, because a zero reads as a measurement that was taken.

- **No floor area on most listings.** Rightmove leaves `displaySize` empty
  whenever the agent did not measure it; that arrives as `null`, not `""` and
  not `0`.
- **No tenure on rentals.** It is not a thing a letting states, so it is null
  rather than guessed from the property type.
- **No sold prices and no valuation.** This reads the live search; Rightmove's
  sold-price history is a different service and is not included.
- **The asking price is not the selling price.** `price` is what the agent is
  asking today, and `added_or_reduced` is the only history on the row.
- **Coordinates are Rightmove's, and are approximate for some listings.** They
  are what the site publishes, not a surveyed position.
- **A paid-for featured listing sits above the ordinary results.** `featured`
  and `premium` are on every row so a consumer measuring position knows which
  rows bought theirs.
- **Rightmove accepts only its own price steps.** A price outside them is
  answered with a page-not-found, which this actor reports as a failed search
  rather than retrying - no exit address in the world changes that answer.

# Actor input Schema

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

Where to search, one per line: a town, a region, a postcode or an outcode, e.g. "London", "Manchester", "SW1A". Each is looked up in Rightmove's own location list and the best match is used. If you already have a Rightmove location id such as REGION^87490, paste it instead and it is used as given, with no lookup request spent.

## `channel` (type: `string`):

Which Rightmove channel to search. "buy" reads property for sale, "rent" reads property to rent. The two are different pages on the site and a listing belongs to exactly one of them.

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

Lowest price to include, in pounds. For rentals this is per calendar month, which is the unit Rightmove prices lettings in. Rightmove only accepts prices from its own list of steps and answers anything else with a page-not-found, which this actor reports rather than retrying.

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

Highest price to include, in pounds; per calendar month for rentals. Same caveat as the minimum: Rightmove accepts only its own price steps.

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

Fewest bedrooms to include. 0 is a real value on Rightmove and selects studios.

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

Most bedrooms to include.

## `radius` (type: `string`):

How far beyond the location to search. Rightmove accepts only these steps; anything else is refused by the site. A radius makes overlapping searches likely, which is fine - a property matched by two of your locations is still delivered and charged once.

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

Restrict to certain property types, using Rightmove's own names: detached, semi-detached, terraced, flat, bungalow, land, park-home. Leave empty for every type.

## `includeSSTC` (type: `boolean`):

Include properties already under offer. Rightmove hides them by default; this actor always states the choice explicitly so a change to that default cannot quietly change what a saved run returns.

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

How Rightmove should order the results before they are read. "Newest first" is what makes a repeated run useful for monitoring new stock.

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

Budget for the whole run, across every location, not per location. A property that matches more than one of your searches, or that Rightmove repeats in a paid featured slot, is delivered and charged once.

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

How deep to walk a single location. A page carries 24 results plus any featured listings the agents paid to insert above them. Rightmove itself refuses to page past index 1008, so roughly 42 pages is the site's own ceiling whatever is set here.

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

Optional. Rightmove answered a plain datacenter address on 2026-09-12 with no proxy at all. It does rate-limit an address that walks pages quickly, and a proxy is what gives the scraper a fresh address to retry on when that happens.

## Actor input object example

```json
{
  "locations": [
    "London"
  ],
  "channel": "buy",
  "radius": "0.0",
  "includeSSTC": false,
  "sort": "6",
  "maxItems": 100,
  "maxPages": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listings` (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 = {
    "locations": [
        "London"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/rightmove-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 = {
    "locations": ["London"],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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