# Rightmove Yield Scanner (`lowlanddata/rightmove-yield-scanner`) Actor

One run samples an area's sale and rental markets, groups them by bedrooms and property type, and delivers gross yield per group - buy medians, monthly rent medians, annualized rent and the yield percent, sample sizes attached. Asking prices and advertised rents, honestly labeled. Aggregates only.

- **URL**: https://apify.com/lowlanddata/rightmove-yield-scanner.md
- **Developed by:** [Lowland Data](https://apify.com/lowlanddata) (community)
- **Categories:** Real estate, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $17.91 / 1,000 results

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?

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 Yield Scanner — gross rental yields by area

One run answers the buy-to-let question for an area: **what does a rental property earn here, relative to what it costs?** The scanner samples both sides of the local market on Rightmove — properties for sale and properties to rent — groups them by bedrooms and property type, and delivers one row per group: median and quartile asking prices on the buy side, median advertised rent on the rent side, and the gross yield percentage that follows.

This is the kind of area screen you would otherwise pay a PropertyData subscription for, priced per run instead. It is built on the [Rightmove Scraper](https://apify.com/lowlanddata/rightmove-scraper) and inherits its privacy guarantee: the output is aggregates only, and the underlying extractor never collects agent contact data.

### Quick start (30 seconds)

1. Put an area into **location** — a town (`Manchester`), a district (`Didsbury, Manchester`) or an outcode (`LS6`), just like the Rightmove search box.
2. Click **Start**. That's the whole minimum setup.
3. When the run finishes — about a minute at default depth — open the dataset's **Overview** tab: one row per property group, sorted straight into a yield table you can export as CSV/Excel/JSON.

Optional knobs: a purchase-price band (your budget, applied to the sale side), a search radius up to 40 miles, and `samplePages` to sample more of each market for steadier medians.

### What you can build with it

- **Screen areas before you view anything.** A buy-to-let investor runs one scan per candidate town and reads the answer off the `grossYieldPct` column — with the sample sizes right next to it saying how much to trust each row.
- **Rank towns for clients.** A sourcer runs the same input over ten locations and hands over a ranked table: same budget, same method, different towns.
- **Compare groups inside one city.** An analyst reads one Manchester run and sees that 2-bed apartments and 1-bed apartments sit within a tenth of a point of each other, while thinner groups scatter — which is itself the finding.
- **Track an area over time.** Schedule the same scan weekly and watch the buy medians, rent medians and the yield between them move.

### What you get

Each property group is one dataset item. From a live Manchester run (6 pages per side, 149 sale + 149 rental listings sampled):

```json
{
  "location": "Manchester",
  "bucket": "2-bed apartment",
  "buySampleSize": 29,
  "buyMedianGbp": 220000,
  "buyP25Gbp": 190000,
  "buyP75Gbp": 270000,
  "rentSampleSize": 41,
  "rentMedianMonthlyGbp": 1450,
  "annualRentGbp": 17400,
  "grossYieldPct": 7.9,
  "currency": "GBP"
}
```

Field notes, so you know exactly what you are buying:

- `bucket` is the property group: bedrooms plus property type. Yields are only ever computed inside a group — a studio is never compared to a five-bed house.
- `buyMedianGbp`, `buyP25Gbp`, `buyP75Gbp` are the median and quartile **asking prices** of the group's sale listings. The quartile spread shows how wide the market is around the median.
- `rentMedianMonthlyGbp` is the median **advertised monthly rent**. Rents listed at other frequencies are skipped rather than converted.
- `grossYieldPct` is annualized rent over buy median: median monthly rent × 12 ÷ median asking price × 100, to one decimal.
- `buySampleSize` and `rentSampleSize` are the row's trust signal. In the same Manchester run, 1-bed flats showed 13% gross — on 9 sale and 17 rental listings. The 2-bed apartments' 7.9% sat on 29 and 41. Read the yield and the sample sizes together, always.

**Honest limits, stated plainly:** this is a **gross** yield from **asking** prices and **advertised** rents. No voids, letting fees, maintenance, tax or mortgage costs are deducted, and no correction is made for the gap between asking and achieved prices. The sale and rent samples are different properties, matched only by group. A high yield from a thin sample is a hint to investigate, not a thesis to act on.

### How much does it cost?

$1.99 per 1,000 rows delivered, pay-as-you-go — no subscription, no charge for empty or failed runs. Since one row is a whole property group, an area scan typically produces 5–15 rows: **a full area answer for under $0.03.**

The price is all-inclusive — platform compute and proxies are covered, with no separate charges. Datacenter proxies are sufficient. A default-depth run finishes in about a minute.

### Not technical? Let your AI assistant set it up

Copy this into ChatGPT, Claude or any AI assistant, fill in the one line, and follow the conversation:

```text
Help me set up the "Rightmove Yield Scanner" actor on Apify
(https://apify.com/lowlanddata/rightmove-yield-scanner). Guide me one step at a time.

What I want to know: [E.G. "which of Leeds, Sheffield and Nottingham has the best
gross yields for 2-bed properties under 200k"]

Guide me to:
1. Propose my input values: location (as I'd type it on rightmove.co.uk), an
   optional priceMinGbp/priceMaxGbp purchase budget, radiusMiles if I want the
   surrounding area, and samplePages if I want steadier medians.
2. Create a free Apify account (apify.com), open the actor page, paste the values
   into the Input form, and start a run — one run per town if I'm comparing several.
3. Read the results table with me: gross yield per property group, and how the
   buySampleSize/rentSampleSize columns tell us which rows to trust.
4. Show me how to export the table as CSV/Excel, and how to set up a weekly
   Schedule if I want to track an area over time.
5. If the results are what I wanted, remind me at the end to leave a quick rating
   on the actor page, and to report anything broken or missing on its Issues tab.
```

### Input

| Field                | Description                                                                                        |
| -------------------- | -------------------------------------------------------------------------------------------------- |
| `location`           | Area as you would type it on Rightmove. Required. First suggestion wins.                           |
| `priceMinGbp`        | Only consider sale listings at or above this price. Applies to the buy side only.                  |
| `priceMaxGbp`        | Only consider sale listings at or below this price — your purchase budget. Buy side only.          |
| `radiusMiles`        | Widen the scan this many miles around the location (0–40).                                         |
| `samplePages`        | Result pages sampled per market side, sale and rental (2–42, default 10). More = steadier medians. |
| `maxItems`           | Upper bound on yield rows (default 50; free plan 25). One row per property group.                  |
| `proxyConfiguration` | Proxy settings; keep Apify proxy enabled.                                                          |

A run minimally needs a `location`. A group only makes it into the output when at least 5 priced listings back it on **both** the sale and the rental side — below that, medians are noise, so the row is withheld rather than published.

### Use it from your code

Run the scanner and get the yield table straight back with one HTTP call:

```bash
curl "https://api.apify.com/v2/acts/lowlanddata~rightmove-yield-scanner/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -X POST -H "Content-Type: application/json" \
  -d '{"location": "Manchester", "priceMaxGbp": 250000}'
```

Node.js:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lowlanddata/rightmove-yield-scanner').call({
  location: 'Manchester',
  priceMaxGbp: 250000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lowlanddata/rightmove-yield-scanner").call(
    run_input={"location": "Manchester", "priceMaxGbp": 250000})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

Schedules, webhooks and the Make/Zapier/n8n integrations all work out of the box — this is a standard Apify actor.

### Use it with AI agents (MCP)

Claude, Cursor and other MCP-capable agents can run the scanner as a tool through Apify's hosted MCP server: the agent picks the areas, starts the runs and reads the yield tables — no glue code.

Claude Code:

```bash
claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/rightmove-yield-scanner"
```

Cursor or Claude Desktop (add a custom connector / MCP server with this URL):

```text
https://mcp.apify.com?actors=lowlanddata/rightmove-yield-scanner
```

Sign in with your Apify account when prompted — runs are billed to it. Setup details per client: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp).

Prompts that work once connected:

- "Scan gross yields in Liverpool under 200k and tell me which property groups look strongest."
- "Run the yield scanner over Leeds, Sheffield and Hull with the same budget and rank them for 2-bed properties."
- "Scan Nottingham yields and flag any group where the sample sizes are too small to trust."

### Is it legal to use this data?

Yes, and this actor makes the question especially short. The output is **aggregate market statistics** — medians, quartiles and percentages over groups of listings. No individual property, no address, no agent, no personal data of any kind appears in a row. The underlying Rightmove adapter is itself built privacy-first — agent phone numbers, contact routes and coordinates are never collected — and this scanner adds a further layer: it publishes only the statistics computed across samples.

Requests are paced, load on the site is kept negligible, and no anti-bot protection is bypassed.

### Is there a Rightmove API for rental yields?

No — Rightmove publishes no public API, and no yield endpoint exists anywhere in it. Yield-by-area tables are otherwise the territory of subscription products. This actor is the per-run alternative: one HTTP call in, one yield table out, computed live from both sides of the current market.

### Does Rightmove block scrapers?

Rightmove serves its listings openly to ordinary requests, and the scanner stays inside that welcome: paced sampling, standard datacenter proxies, a few hundred listings read per run. If a run does hit a temporary block, it fails fast with a clear status message and a retry usually lands on a clean proxy session.

### How do I compare yields across areas?

Run the scanner once per town, changing **only** `location` and keeping every other input identical — same budget, same radius, same `samplePages`. Because the method is fixed, the rows are directly comparable: pull the `grossYieldPct` for the same `bucket` (say, `2-bed apartment`) out of each run and you have a like-for-like ranking. The MCP setup above lets an AI agent do the whole loop — run the towns, collect the tables, rank the groups — from a single prompt.

### FAQ

**What is a good rental yield in the UK?** Rules of thumb put a workable gross yield around 5–6%, with 7%+ considered strong and common in northern cities; London typically sits lower. Treat these as orientation, not advice — what this scanner gives you is the actual current figure per property group in the area you name.

**How do I calculate rental yield from Rightmove?** The manual way: find comparable sale and rental listings, take a typical asking price and a typical monthly rent, then compute rent × 12 ÷ price × 100. This actor does exactly that, but with medians over dozens of listings per group instead of a handful you picked by eye — one run, one table.

**Is the yield gross or net?** Gross, and labeled as such. Nothing is deducted: no void periods, letting fees, maintenance, insurance, tax or mortgage costs. Net yield depends on your own cost structure; the gross figure is the comparable market signal to start from.

**Are these asking prices or sold prices?** Asking prices and advertised rents — what the market is asking today, not what it achieved. Achieved sale prices usually come in below asking, so real-world gross yields tend to land somewhat above the figure shown. No correction is applied, because any correction would be a guess.

**How much should I trust a row?** Read `buySampleSize` and `rentSampleSize` first. A yield backed by 29 sale and 41 rental listings is a solid area signal; one backed by 9 and 17 is a lead worth checking, nothing more. The minimum of 5 per side keeps pure noise out, but small legitimate samples still pass — the sizes are printed on every row precisely so you can judge.

**Why does one group show a spectacular yield?** Usually a thin sample. In a live Manchester run, 1-bed flats showed 13% gross on 9 sale listings against the 7.9% of 2-bed apartments on 29. A few cheap sale listings or a few expensive rentals can swing a small group hard. Spectacular number + small sample = investigate, don't conclude.

**How do I apply my purchase budget?** Set `priceMaxGbp` (and optionally `priceMinGbp`). The band filters the **sale** side only, so the buy medians reflect what you could actually purchase.

**Why doesn't the price band filter the rent side?** Because the rent side answers a different question: what do properties like these rent for in this area? Filtering rentals by your purchase budget would make no sense — rents are sampled across the whole group so the rent median stays representative.

**Can I scan around a town, not just inside it?** Yes — `radiusMiles` widens both market sides up to 40 miles around the location. Useful for smaller towns where the town itself is too thin to clear the 5-listings-per-side bar.

**How do I compare several towns?** One run per town, identical input apart from `location`, then compare the same `bucket` across runs. See the recipe section above.

**Can I schedule it?** Yes — add a Schedule in the Apify Console with your input and the same scan runs weekly or monthly. Each run is a dated snapshot of the area's buy medians, rent medians and yields, which turns the scanner into a trend tracker.

**Can I export to Excel or CSV?** Yes — the dataset exports as CSV, Excel, JSON or XML from the Apify Console or the API. The Overview table maps one-to-one onto a spreadsheet.

**Why did my run fail saying no group reached 5 listings?** The area was too thin: no (bedrooms, property type) group had at least 5 priced listings on both the sale and the rental side. The fix is in the message itself — widen the area with `radiusMiles` or raise `samplePages`. Failed runs cost nothing.

**Are weekly rents included?** No — rents are used only when advertised per month. Other frequencies are rare on Rightmove and are skipped rather than converted, so the rent medians stay clean.

**Does it list the individual properties?** No — the output is the statistics, one row per group. When a group looks promising, run the [Rightmove Scraper](https://apify.com/lowlanddata/rightmove-scraper) on the same location with matching filters to see the actual listings behind it.

**Is the output GDPR-safe to store?** Yes, structurally: rows contain only aggregate statistics — no addresses, no agents, no personal data. The underlying adapter never collects agent contact data in the first place.

**Does it work with Make, Zapier or n8n?** Yes — it is a standard Apify actor; all platform integrations, webhooks and schedules apply.

**How fresh are the numbers?** Live at run time — every run samples Rightmove directly on both sides. There is no cached index; the table reflects the market at the minute you ran it.

**Why did my run produce few rows?** Most areas genuinely produce 5–15 groups that clear the 5-per-side bar — that is the answer, not a truncation. The free-plan cap of 25 rows rarely binds for a single-area scan; `maxItems` (default 50) is the hard ceiling.

### Related scrapers

The same privacy-clean output, same market:

- [Rightmove Scraper](https://apify.com/lowlanddata/rightmove-scraper) — the parent actor: full property listings as structured JSON, for when you want the properties behind the statistics.
- [Rightmove BMV Deal Finder](https://apify.com/lowlanddata/rightmove-bmv-deal-finder) — flags listings priced below their local market level.
- [Rightmove New Listings Alert](https://apify.com/lowlanddata/rightmove-new-listings-alert) — a scheduled feed of only the listings added since you last looked.

### Troubleshooting

The actor fails fast with the reason in the run's status message:

- **"Rightmove does not know the location ..."** — type the place as the Rightmove search box suggests it, e.g. `Didsbury, Manchester` instead of an abbreviation.
- **"No (bedrooms, property type) group reached 5 priced listings on both the sale and rental side. Widen the area or raise samplePages."** — the area is too thin at this depth; add `radiusMiles` or increase `samplePages`.
- **"Rightmove blocked the run before any results could be fetched."** — a temporary block; a retry usually lands on a clean proxy session.
- **A group you expected is missing** — it fell under 5 priced listings on one side. Raise `samplePages` to sample deeper into both markets.

### Support

Found an issue, or want a statistic the rows don't carry yet? Open an issue on the actor's **Issues tab** — reports get fixed, this actor is actively maintained.

Working well for you? A **rating on this page** takes ten seconds and helps other buyers find this scanner — it is also the clearest signal of what we should build next.

# Actor input Schema

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

The area to scan: a UK city, town, district or postcode as you would type it on Rightmove, e.g. "Manchester" or "LS6".

## `priceMinGbp` (type: `integer`):

Only consider sale listings at or above this price.

## `priceMaxGbp` (type: `integer`):

Only consider sale listings at or below this price - your actual budget.

## `radiusMiles` (type: `integer`):

Widen the scan this many miles around the location (0-40).

## `samplePages` (type: `integer`):

Result pages sampled per market side - sale and rental (2-42). More pages = steadier medians.

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

Upper bound on yield rows (one per property group).

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

Proxy settings. Keep Apify proxy enabled.

## Actor input object example

```json
{
  "location": "Manchester",
  "samplePages": 10,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `rows` (type: `string`):

One gross-yield row per property group.

# 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 = {
    "location": "Manchester",
    "samplePages": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lowlanddata/rightmove-yield-scanner").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 = {
    "location": "Manchester",
    "samplePages": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("lowlanddata/rightmove-yield-scanner").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 '{
  "location": "Manchester",
  "samplePages": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call lowlanddata/rightmove-yield-scanner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lowlanddata/rightmove-yield-scanner"
        }
    }
}

```

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/xNvNMdu92FTRaAD2b/builds/nzFhaWAV03ILibDmS/openapi.json
