# Zoopla Scraper — UK Property API · Sale + Rent + Valuations (`sian.agency/zoopla-property-scraper`) Actor

Zoopla scraper for UK property data — sale and rent listings with valuation estimates for both, plus market KPIs (median price, price per sqft, area breakdowns) and an HTML report. Search by location, with bulk-location input on paid runs.

- **URL**: https://apify.com/sian.agency/zoopla-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Automation, Lead generation
- **Stats:** 15 total users, 6 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 property extracteds

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/platform/actors/running/actors-in-store#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

## 🇬🇧 Zoopla Property Scraper — UK Real Estate API · Sale · Rent · Full Property Details

[![Store - SIÁN Agency](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Store - Rightmove Scraper](https://img.shields.io/badge/Store-Rightmove%20Scraper-00DEB6)](https://apify.com/sian.agency/rightmove-property-scraper?fpr=sian) [![Store - Redfin Scraper](https://img.shields.io/badge/Store-Redfin%20Scraper-A02021)](https://apify.com/sian.agency/redfin-property-scraper?fpr=sian) [![Store - Zillow Scraper](https://img.shields.io/badge/Store-Zillow%20Scraper-1F4E79)](https://apify.com/sian.agency/zillow-property-scraper?fpr=sian)

> **Stable, API-backed UK property data from Zoopla.** For-sale + to-rent listings, **full per-listing property records** (description, features, EPC, tenure, photos, points of interest), and completed sold-price comparables across England, Scotland, Wales and Northern Ireland — search by location, postcode, coordinates, pasted Zoopla URL, listing id, or street address. Per-listing valuation estimates (sale + rent), built-in market KPIs (median price, £/sqft, area breakdowns), and an HTML report. Built on a stable upstream tier so your scrapes don't break when Zoopla rotates its layout — and so UK property data extraction is just an API call, not a maintenance project.

By [SIÁN Agency](https://apify.com/sian.agency?fpr=sian) · Independent tool — **not affiliated with Zoopla or Zoopla Property Group (ZPG)**.

***

### 🔎 What is the Zoopla Property Scraper — and when should you use it?

The **Zoopla Property Scraper** turns Zoopla's UK sale, rent and sold-price listings into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

**Use it when you need:** UK for-sale and to-rent listings with price in GBP, beds, baths, receptions, floor area, address and postcode, coordinates, photos, and the estate-agent branch behind each one. Details mode returns the full record per property, adding the listing description, feature list, EPC rating, tenure and council tax band. Sold-price comparables, sale and rent valuation estimates, and median price and price per sqft KPIs come out of the same run.

**Use something else when:** you want a different UK portal, or you already know which properties you want. Use [Rightmove Property Scraper](https://apify.com/sian.agency/rightmove-property-scraper?fpr=sian) for UK sale, rent and sold-price listings from Rightmove, with Land Registry sold prices stitched in. Use [Zoopla Property Detail Scraper](https://apify.com/sian.agency/zoopla-property-detail-scraper?fpr=sian) for a full dossier per Zoopla URL, listing ID or UK address when you already have the list. This actor covers the UK only.

### 🤖 Use with AI agents

Already connected to the [Apify MCP server](https://mcp.apify.com)? Just ask for this Actor by name: sian.agency/zoopla-property-scraper

**Your agent can pay for its own runs.** This Actor is eligible for [agentic payments](https://docs.apify.com/platform/actors/publishing/monetize), so an agent can discover it, run it and settle the bill over [x402](https://www.x402.org/) (USDC on Base) or [Skyfire](https://www.skyfire.xyz/) — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want UK property listings, sold prices and valuation estimates from Zoopla using the Apify Actor `sian.agency/zoopla-property-scraper`.

Use it when I need: UK for-sale and to-rent listings with price in GBP, beds, baths, receptions, floor area, address and postcode, coordinates, photos, and the estate-agent branch behind each one. Details mode returns the full record per property, adding the listing description, feature list, EPC rating, tenure and council tax band. Sold-price comparables, sale and rent valuation estimates, and median price and price per sqft KPIs come out of the same run.

Don't use it when: you want a different UK portal, or you already know which properties you want — use rightmove-property-scraper or zoopla-property-detail-scraper instead.

How to call it: pick a `searchMode`: `bylocation` (free-text `location`), `byzip` (`postalCode`, outward code such as NW3), `bycoordinates` (`latitude` + `longitude` + `radius` in miles), `byurl` (a pasted Zoopla search URL in `zooplaUrl`), `bulklocations` (an array in `locations`, PAID), `soldprices` (`soldLocation` for completed-sale comparables), `agentbranches` (`agentLocation` or `branchIds`), or `details` (`listingIds`, `zooplaListingUrls` or `propertyAddresses` for full records). Set `listingType` to `sale`, `rent` or `both`, narrow with `propertyType` / `priceRange` / `bedsRange` / `tenure`, cap with `maxResults`, and add PAID enrichments via `includeEstimates`, `includeImages`, `includePoi`, `includeHistory`, `includePriceHistory` or `includeEvCharging`.

Start with this input:
{
  "searchMode": "bylocation",
  "listingType": "sale",
  "location": "Hampstead, London",
  "bedsRange": "min:2",
  "priceRange": "min:500000,max:1500000",
  "maxResults": 25
}

Ask me which UK location or postcode, and whether you want properties for sale or to rent, then run the Actor and summarise the results as a table.
```

**Things you can ask your agent for:**

- *Pull two-bed flats for sale in Hampstead under £1.5m and rank them by price per square foot.*
- *Build a sold-price comparable set for NW3 to support a valuation.*
- *List the estate-agent branches active in Oxford with their phone numbers and current stock.*

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/zoopla-property-scraper.md](https://apify.com/sian.agency/zoopla-property-scraper.md).

### 🚀 What you get on every run

- **Full property records** ✨ NEW — the biggest gap just closed: look up a property by listing id, listing URL, or street address and get the FULL record (description, features, EPC rating, tenure detail, floor plans, points of interest) — not just a search-result summary
- **Structured listings** — propertyId, full address, GBP price, beds/baths/receptions, sqft, lat/lon, photos, estate-agent branch
- **Sold price history & comparables** — pull what UK properties *actually sold for*, with full per-property sale history (`historicSales[]`) and Zoopla valuation estimates — the gold standard for comps and underwriting
- **For-sale + to-rent in one call** — set `listingType: both` (PAID) and get both sides of the market in a single dataset
- **Auto-computed £/sqft** — for every sale listing with usable floor area
- **Market KPIs** — median price, price-distribution stats, area + property-type breakdowns, surfaced in a polished HTML report
- **5 enrichment add-ons** (optional, PAID) — valuation estimate, full-resolution images + floor plans, points of interest + transport links, property sale/listing history, advertised-price change timeline, and nearby EV charging stations — attach any combination to a listing
- **Estate-agent branch intelligence** — profile any UK branch (name, address, phone, memberships, listing counts) and pull its complete for-sale + to-rent inventory; discovers branches by name/area directly, with automatic fallback if that path is unavailable
- **Retry-helper record** — even on partial failures you get a JSON summary of what failed so you can rerun cheaply

***

### 🎯 Built for

- **Due-diligence teams** — pull the FULL record for a shortlist of properties (description, EPC, tenure, floor plans) by id, URL, or address in one run
- **Buy-to-let investors** — pull live comparables *and sold-price comps* (UK comps) for underwriting in seconds; compute yield from `listingType: both` runs
- **Estate agents & valuers** — back up asking-price advice with real sold-price evidence for any street or postcode area
- **Mortgage brokers** — generate 100-listing comp sets and sold-price comparables for valuation reports
- **PropTech teams** — feed your AVM / rent-prediction models with consistent UK training data, including realised transaction history, points of interest, and full listing detail
- **Investment funds** — schedule weekly sweeps of London / Manchester / Birmingham micro-markets

***

### 🧭 8 search modes

| Mode | Best for |
|---|---|
| **Details** ✨ NEW | Full listing/property record by listing id, listing URL, or street address |
| **By location** | Free-text — "Hampstead, London", "Oxford", "NW3" |
| **By postcode** | UK postcode outward code (`NW3`, `SW1A`, `M1`, `EC1A`) |
| **By coordinates** | Lat/lon + radius (miles) — e.g. for map-based UI |
| **By URL** | Paste any Zoopla search URL — filters auto-read from the URL |
| **Bulk locations** (PAID) | Sweep an array of locations in one run |
| **Sold prices** | Completed-sale comparables + full sold-price history for any UK area |
| **Agent branches** | Estate-agent branch profiles + each branch's full for-sale / to-rent inventory |

Live-listing modes share the same UK filter set: property type, tenure (freehold/leasehold/share-of-freehold), price/beds/baths/sqft ranges, new homes, chain-free, furnished state, pets allowed, bills included, and free-text keywords.

***

### 🏠 Details mode — full property records (NEW)

Every other mode above returns a **search-result summary**. Details mode returns the **full record** — the same depth of data you'd see on the actual listing page: description, full feature list, EPC rating, tenure detail, council tax band, floor plans, points of interest, and transport links.

**Three ways in — mix freely in one run:**

1. **Listing ID** — `listingIds: ["72743732"]` → `/details/byid`
2. **Listing URL** — `zooplaListingUrls: ["https://www.zoopla.co.uk/for-sale/details/72743732/"]` → `/details/byurl`
3. **Street address** — `propertyAddresses: ["10 Mansfield Road, NW3 2HN"]` (must include the full postcode) → `/details/byaddress`, which returns a **property-level** record (beds/baths/tenure, sale + rent estimate, historic listings/sales) instead of one specific advertised listing — useful when you have an address but not a live listing id

**What you get (listing id / URL):**

```json
{
  "propertyId": "73109201",
  "listingType": "sale",
  "propertyTitle": "3 bed flat for sale",
  "listingDescription": "An exceptional three-bedroom duplex apartment...",
  "features": ["Three Bedrooms", "Two Bathrooms", "Private Patio Garden"],
  "specs": { "beds": 3, "baths": 2, "epcRating": "C", "tenure": "share_of_freehold", "councilTaxBand": "G" },
  "media": { "photoCount": 20, "photos": ["https://lc.zoocdn.com/..."], "floorPlans": [] },
  "pointsOfInterest": [{ "title": "Swiss Cottage", "type": "london_underground_station", "distance": 0.3 }],
  "publicationStatus": "Live"
}
```

FREE tier processes up to 5 property records per run; PAID is unlimited.

***

### 🧩 6 enrichment add-ons (PAID)

Attach any combination to a listing — search-mode row or details-mode row — each fires one extra API call, charged only on success. 5 new add-ons ✨ join the original valuation estimate:

| Add-on | Input flag | Adds |
|---|---|---|
| Valuation estimate | `includeEstimates` | Sale + rent estimate with confidence band |
| Full-resolution images | `includeImages` | Full photo set + floor plans (most useful on search rows, which only carry thumbnails) |
| Points of interest | `includePoi` | Nearby schools/stations + transport links |
| Property history | `includeHistory` | The property's historic listings + sold-price record (uprn/address-keyed) |
| Price-change history | `includePriceHistory` | The listing's own advertised-price change timeline |
| EV charging | `includeEvCharging` | Nearby EV charging stations |

***

### 🏷 Sold prices mode (NEW)

Pull **completed-sale comparables** — the prices UK properties actually sold for — for any area, alongside the live for-sale and to-rent modes. This is the data that powers real valuations, BTL underwriting, and "what's it worth?" analysis.

**How to use it:**

1. Set **Search Mode = `soldprices`**.
2. Type a free-text **`soldLocation`** — `London`, `Hampstead, London`, `Oxford, Oxfordshire`, or an outward postcode like `NW3`. It's resolved to the right Zoopla area automatically.
3. *(Advanced)* Skip resolution by passing a precise **`geoId`** slug directly (e.g. `london`, `london/elm-row`).
4. Tune **`first`** (1–100) to control results per page, and `maxResults` for total volume.

**What you get per comparable:**

```json
{
  "propertyId": "5068790",
  "address": { "full": "Elm Row, Hampstead, London NW3" },
  "specs": { "beds": 3, "baths": 2, "receptions": 1 },
  "tags": ["Freehold"],
  "historicSales": [
    { "date": "2023-08-14", "price": 1985000 },
    { "date": "2015-03-02", "price": 1320000 }
  ],
  "saleEstimate": { "current": 2216000, "lower": 1994000, "upper": 2438000, "confidence": "MEDIUM" },
  "location": { "latitude": 51.5564, "longitude": -0.1782 },
  "scrapedAt": "2026-06-14T11:05:43.123Z"
}
```

Every sold comparable carries its **full sale history** (`historicSales[]` — date + GBP sold price), Zoopla's current **`saleEstimate`** (and, where available, `rentEstimate`) with confidence band, plus address, beds/baths/receptions, tenure, property type, and coordinates — ready for mapping and valuation workflows.

***

### 🏢 Agent branches mode

Profile UK **estate-agent branches** and pull each branch's **complete for-sale and to-rent inventory** in one run — agent prospecting, competitor tracking, and instructions-per-branch analysis without any manual browsing.

**Two ways in:**

1. **By area** — set **Search Mode = `agentbranches`** and type a free-text **`agentLocation`** (e.g. `Oxford`, `Hampstead, London`, `NW3`) — optionally narrowed with **`agentNameFilter`** (e.g. `Foxtons`). Branch discovery tries a direct name/area lookup first and automatically falls back to discovering branches from live listings in that area (including each branch's **phone number**) if that path is unavailable.
2. **Exact branches** — pass **`branchIds`** directly: numeric ids (e.g. `61460`) or full branch URLs from the `branch.branchUrl` field of any previous run. (Phone numbers are only available via area discovery.)

**What you get per branch:**

- A **branch profile row** (`listingType: "agent"`) — branch name, street address + postcode, phone (via area discovery), logo, branch URL, industry memberships (e.g. ARLA, TPO), and live for-sale / to-rent listing counts:

```json
{
  "branchId": "1990",
  "listingType": "agent",
  "propertyTitle": "Connells - Headington, Oxford",
  "address": { "full": "129-131 London Road, Headington, Oxford", "postcode": "OX3 9HZ" },
  "branch": { "name": "Connells - Headington, Oxford", "phone": "01865 360064", "branchUrl": "https://www.zoopla.co.uk/find-agents/branch/connells-headington-oxford-oxford-1990/" },
  "memberships": [ { "memberOf": "arla" }, { "memberOf": "tpo" } ],
  "forSaleCount": 20,
  "forRentCount": 0
}
```

- The branch's **full inventory** — every for-sale and to-rent listing lands as a regular listing row (price, beds/baths, £/sqft, photos, coordinates) tagged with its `branchId`, so market KPIs and the HTML report work out of the box.

Use `maxResults` to cap the rows per query (profile + inventory count toward the cap).

***

### 💰 Transparent pricing

Pay-per-event — no monthly subscription, no per-page overhead. **Charged only on successful extraction.** Apify subscription discounts apply automatically (Starter ≈ 67% off · Scale ≈ 71% off · Business ≈ 75% off vs Free).

| Event | Free | Starter | Scale | Business | Triggered when |
|---|---|---|---|---|---|
| Run started | $0.050 | $0.005 | $0.005 | $0.005 | Once per run |
| Property extracted | $0.015 | $0.005 | $0.0045 | $0.004 | Per listing, sold comparable, **or agent-branch profile** pushed to the dataset |
| Valuation enriched | — | $0.003 | $0.0027 | $0.0024 | Per successful full property record (details mode), and per successful enrichment add-on (estimate, images, points of interest, property history, price-change history, or EV charging) |

> **Sold prices and agent branches reuse the per-property event** — each sold comparable, branch profile, and branch-inventory listing is billed at the same "Property extracted" rate as a live listing. No separate surcharge.
> **Details mode and every enrichment add-on reuse the "Valuation enriched" event** — one charge per successful call, whichever add-on it was (or per full property record fetched in details mode). No separate surcharge per add-on type.

**Free tier** is built for low-volume testing — capped at 5 queries / 25 listings per run, no enrichment, no `listingType: both`.
**Paid tiers (Starter and up)** unlock unlimited listings, bulk locations, valuation enrichment, and `listingType: both`.

***

### 📦 Sample output (sale)

```json
{
  "propertyId": "73109201",
  "listingType": "sale",
  "url": "https://www.zoopla.co.uk/for-sale/details/73109201/",
  "thumbnailUrl": "https://lid.zoocdn.com/645/430/...jpg",
  "propertyTitle": "3 bed flat for sale",
  "address": { "full": "Lancaster Grove, Belsize Park, London NW3" },
  "pricing": {
    "price": 1850000,
    "priceCurrency": "GBP",
    "priceDisplay": "£1,850,000",
    "priceShort": "£1.85m",
    "pricePerSqft": 1390
  },
  "specs": { "beds": 3, "baths": 2, "receptions": 1, "sizeSqft": 1331 },
  "location": { "latitude": 51.54644, "longitude": -0.171423 },
  "branch": {
    "name": "ADN Residential",
    "phone": "020 8128 2227",
    "branchUrl": "https://www.zoopla.co.uk/find-agents/branch/adn-residential-london-159325/"
  },
  "tags": ["Share of Freehold"],
  "scrapedAt": "2026-05-05T17:05:43.123Z"
}
```

> **Note on `tags`:** This array always exists on every record (empty `[]` when the listing has no tags). On for-sale listings it typically carries the tenure label (`Freehold`, `Leasehold`, `Share of Freehold`); on rental listings it's usually empty. Filter `tenure` is supported as an *input* parameter, but tenure is reported on output as a string inside `tags[]`, not as its own structured field.

With `includeEstimates: true` (PAID), each listing additionally carries:

```json
{
  "estimate": {
    "uprn": "5068790",
    "saleEstimate": { "current": 2216000, "lower": 1994000, "upper": 2438000, "confidence": "MEDIUM" },
    "rentEstimate": null
  }
}
```

***

### ⚙️ Quick start

1. **Click "Try for free"** above — paste any UK location, postcode, or Zoopla URL (or pick **Sold prices** mode for comparables).
2. **Run.** First 25 listings are free.
3. **Check the dataset** for your structured listings, and the **HTML report** in the key-value store for market KPIs.

For automation: schedule via Apify's built-in scheduler, or call our REST API with your Apify token.

***

### ❓ FAQ

**Can I get the FULL listing record, not just search results?**
Yes — use the **`details`** search mode with a `listingIds`, `zooplaListingUrls`, or `propertyAddresses` entry. You get the full description, feature list, EPC rating, tenure detail, floor plans, points of interest, and transport links — the same depth as the live listing page.

**Does this work for sold prices?**
Yes — use the **`soldprices`** search mode. Type a free-text `soldLocation` (or pass a `geoId`) and you get completed-sale comparables with full per-property sale history (`historicSales[]`) plus Zoopla valuation estimates. Live for-sale and to-rent listings are covered by the other five modes.

**Can I scrape estate agent details?**
Yes — use the **`agentbranches`** search mode. Type a UK `agentLocation` (or pass exact `branchIds`) and you get a profile per branch (name, address, phone, memberships, listing counts) plus the branch's full for-sale and to-rent inventory. Branch name, phone, logo and branch-URL are also returned on every live listing in the other modes.

**What about Northern Ireland / Scotland?**
Zoopla covers all four UK nations; this actor inherits that coverage — for both live listings and sold prices.

**Why outward postcodes instead of full postcodes?**
Zoopla's slug-based search treats `NW3 1AA` as one literal — it usually returns 0 results. Outward codes (`NW3`, `SW1A`) resolve to area slugs and return real inventory. We auto-strip the inward code if you paste a full postcode.

**Can I get the estate agent's email?**
Branch name, phone, logo and Zoopla branch-URL are returned. Email is not exposed by Zoopla's public surface.

***

### ⚠️ Trademark Disclaimer

This Actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Zoopla, Zoopla Property Group (ZPG), or any of its subsidiaries**. "Zoopla" is used solely in a descriptive sense to identify the public data source the Actor reads from. All trademarks are the property of their respective owners.

***

### 📚 Legal & Scraping Notes

- This actor reads only **publicly visible** Zoopla pages — no logins, no bypassing of paywalls.
- You are responsible for complying with Zoopla's Terms of Service and applicable UK / EU data laws (UK GDPR, Data Protection Act 2018) when using the data.
- Personal data of estate agents (e.g. branch phone) is included only as published on Zoopla's public site.

***

### 💬 Support

- 🐛 Found a bug? File an issue in the Apify Console Issues tab
- ⭐ Loving the tool? Leave a 5-star review — it helps us build more
- 📧 <apify@sian-agency.online>

***

### 🧰 More from SIÁN Agency

- 🏠 [Rightmove Property Scraper — UK Sale, Rent & Sold Prices](https://apify.com/sian.agency/rightmove-property-scraper?fpr=sian)
- 🏡 [Redfin Property Scraper — Sale + Sold · Market KPIs](https://apify.com/sian.agency/redfin-property-scraper?fpr=sian)
- 🏙️ [Zillow Property Scraper + Market KPIs](https://apify.com/sian.agency/zillow-property-scraper?fpr=sian)
- 🌐 [Browse all SIÁN Agency actors →](https://apify.com/sian.agency?fpr=sian)

# Actor input Schema

## `searchMode` (type: `string`):

How to specify what to scrape.

• **bylocation** — free-text UK location (town, neighbourhood, postcode area)
• **byzip** — UK postcode (outward code preferred — e.g. NW3, SW1A)
• **bycoordinates** — latitude + longitude + radius (miles)
• **byurl** — paste a Zoopla search URL — filters are read from the URL
• **bulklocations** — array of locations in one run (PAID)
• **soldprices** — completed-sale comparables (sold price history) for a location
• **agentbranches** — estate-agent branch profiles + their full for-sale/to-rent inventory
• **details** ✨ NEW — full listing/property record by id, URL, or address (the deep-dive complement to every search mode above)

## `listingType` (type: `string`):

Which side of the UK market to scrape.

• **sale** — properties for sale
• **rent** — properties to rent
• **both** — runs each query twice — sale + rent (PAID)

Note: ignored when Search Mode = byurl (the URL itself encodes whether it's a for-sale or to-rent search).

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

Free-text UK location — neighbourhood, town, county, region, postcode area, or full address.

Examples: `London`, `Hampstead, London`, `Camden`, `Oxford, Oxfordshire`, `NW3`

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

Array of UK location strings to sweep in one run. PAID tier only.

## `postalCode` (type: `string`):

UK postcode — **outward code preferred** (the part before the space).

Full postcodes like `NW3 1AA` may return 0 results — outward codes (`NW3`, `SW1A`, `M1`, `EC1A`) resolve to area slugs.

Examples: `NW3`, `SW1A`, `EC1A`, `M1`, `OX1`

## `latitude` (type: `number`):

Latitude in decimal degrees. London centre ≈ `51.5074`.

## `longitude` (type: `number`):

Longitude in decimal degrees. Negative = west of Greenwich. London centre ≈ `-0.1278`.

## `zooplaUrl` (type: `string`):

Paste any search/filter URL from the Zoopla site.

Examples:

- `https://www.zoopla.co.uk/for-sale/property/london/?price_min=500000&beds_min=2`
- `https://www.zoopla.co.uk/to-rent/property/manchester/?price_max=1500&furnished_state=furnished`

## `soldLocation` (type: `string`):

Free-text UK location for completed-sale comparables — resolved automatically to a Zoopla area.

Examples: `London`, `Hampstead, London`, `Oxford, Oxfordshire`, `NW3`

## `geoId` (type: `string`):

Optional Zoopla geo-identifier slug — the most precise option, used as-is when supplied (skips location resolution).

Examples: `london`, `london/elm-row`

## `first` (type: `integer`):

Sold-price results requested per page (1–100, default 50). Use with Max results to control total volume.

## `agentLocation` (type: `string`):

Free-text UK location — estate-agent branches are discovered automatically from live listings in this area (including each branch's phone number). Ignored when Branch IDs are provided.

Examples: `Oxford`, `Hampstead, London`, `NW3`

## `branchIds` (type: `array`):

Exact estate-agent branch ids to profile — numeric ids (e.g. `61460`) or full branch URLs from the `branch.branchUrl` field of a previous run (the URL slug ends in the id). Takes priority over Agent location when both are set.

Note: branch phone numbers are only available via Agent location discovery.

## `agentNameFilter` (type: `string`):

Optional company-name substring filter for branch discovery (e.g. `Foxtons`, `Knight Frank`). Only used when Agent location is set (ignored for direct Branch IDs).

## `listingIds` (type: `array`):

Zoopla listing ids — digits only, one full property record per id (e.g. `72743732`). Find one in any search-mode row's `propertyId`, or in a listing URL's `/details/<id>/` segment.

## `zooplaListingUrls` (type: `array`):

Full Zoopla listing-DETAIL URLs (not search URLs) — must contain `/details/<id>/`. Example: `https://www.zoopla.co.uk/for-sale/details/72743732/`.

## `propertyAddresses` (type: `array`):

Full UK street addresses INCLUDING the postcode — returns a property-level record (beds/baths/tenure, sale + rent estimate, historic listings/sales) keyed by UPRN rather than a specific listing id. Example: `10 Mansfield Road, NW3 2HN`.

## `radius` (type: `number`):

Search radius around the location/postcode/coordinates, in miles. Allowed: 0, 0.25, 0.5, 1, 3, 5, 10, 20, 40. Default: 1.

## `propertyType` (type: `string`):

Comma-separated UK property types. Leave empty to include all.

Allowed: `flat, house, bungalow, terraced, semi_detached, detached, land, park_home, farm`

Examples: `flat`, `house,bungalow`, `terraced,semi_detached`

## `priceRange` (type: `string`):

Price range in GBP. Format: `min:N`, `max:N`, or `min:N,max:N`.

For sale: total price. For rent: monthly rent (pcm).

Examples: `min:500000,max:1500000`, `max:2000`, `min:300000`

## `bedsRange` (type: `string`):

Bedroom range. Studio = `min:0`. Format: `min:N`, `max:N`, or `min:N,max:N`.

Examples: `min:2`, `min:3,max:3`, `min:2,max:5`

## `bathsRange` (type: `string`):

Bathroom range. Format: `min:N`, `max:N`, or `min:N,max:N`.

## `sizeSqftRange` (type: `string`):

Floor-area range in square feet. Format: `min:N`, `max:N`, or `min:N,max:N`.

## `tenure` (type: `string`):

UK property tenure. Leave empty for any.

• **freehold** — own the building and the land
• **leasehold** — own the property for a fixed term
• **share\_of\_freehold** — leasehold + share in the building's freehold company

## `newHomes` (type: `string`):

New-build filter.

• **(any)** — Zoopla default (include new builds)
• **false** — exclude new builds
• **only** — only new builds

## `furnished` (type: `string`):

Furnishing state — only used when listingType = rent.

## `keywords` (type: `string`):

Free-text amenity keywords matched against listing descriptions.

Examples: `garden`, `parking`, `period features`, `garden parking`

## `sortOrder` (type: `string`):

How results are sorted. Default: Newest.

## `chainFree` (type: `boolean`):

Return only chain-free listings (no onward chain — common for new builds, executor sales, repossessions).

## `includeSold` (type: `boolean`):

Also include sold-STC / under-offer listings alongside live ones.

## `petsAllowed` (type: `boolean`):

Return only pet-friendly rentals.

## `billsIncluded` (type: `boolean`):

Return only rentals with bills included in rent.

## `includeRented` (type: `boolean`):

Also include let-agreed / already-rented listings alongside live ones.

## `maxResults` (type: `integer`):

Hard cap on listings returned per query. Auto-paginates until the cap is reached or the search is fully drained. Default 25 = one API page. FREE tier is always capped at 25 listings per run.

## `includeEstimates` (type: `boolean`):

When ON, fetches sale + rent valuation estimates for each listing (1 extra API call per listing). Adds an estimate-enriched charge per successful enrichment. Disabled on FREE tier.

Note: works best when listings have a clear UK postcode in the address. Listings without a resolvable address are silently skipped (no charge).

## `includeImages` (type: `boolean`):

Fetches the full-resolution photo set + floor plans for each listing. Most useful on search-mode rows (thumbnails only) and address-sourced details rows (no photos at all) — largely redundant on details rows sourced from a Listing ID/URL, which already embed the full photo set.

## `includePoi` (type: `boolean`):

Fetches nearby points of interest (schools, stations, ...) + transport links for each listing.

## `includeHistory` (type: `boolean`):

Fetches the historic listings + sold-price record for the PROPERTY behind each row (uprn/address-keyed) — complements the DB-wide soldprices search mode with a per-listing lookup.

## `includePriceHistory` (type: `boolean`):

Fetches the advertised-price change timeline for the LISTING itself (distinct from property history above — this is how the marketed price moved while it was listed, not the property's sale record).

## `includeEvCharging` (type: `boolean`):

Fetches nearby EV charging stations for each listing.

## Actor input object example

```json
{
  "searchMode": "bylocation",
  "listingType": "sale",
  "location": "Hampstead, London",
  "postalCode": "NW3",
  "latitude": 51.5074,
  "longitude": -0.1278,
  "soldLocation": "Hampstead, London",
  "first": 50,
  "agentLocation": "Oxford",
  "radius": 1,
  "tenure": "",
  "newHomes": "",
  "furnished": "",
  "sortOrder": "",
  "chainFree": false,
  "includeSold": false,
  "petsAllowed": false,
  "billsIncluded": false,
  "includeRented": false,
  "maxResults": 25,
  "includeEstimates": false,
  "includeImages": false,
  "includePoi": false,
  "includeHistory": false,
  "includePriceHistory": false,
  "includeEvCharging": false
}
```

# Actor output Schema

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

Structured Zoopla sale and rent listings with calculated £/sqft, and (optional) valuation estimates, images, points of interest, price history, and EV charging data.

## `htmlReport` (type: `string`):

HTML summary with run stats, market KPIs (median price, £/sqft distribution), area + property-type breakdowns, and per-query totals.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/zoopla-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/zoopla-property-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call sian.agency/zoopla-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sian.agency/zoopla-property-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/HWgSALkDkK5gif4lP/builds/nKWFNpT7hbfReWEhG/openapi.json
