# Zoopla Property Detail Scraper — Valuation, by URL or Address (`sian.agency/zoopla-property-detail-scraper`) Actor

Paste Zoopla URLs, listing IDs, or UK addresses and get a full property dossier: price, beds, tenure, lease and ground rent, council-tax band, EPC, photos, floor plans, and agent. Add Zoopla sale and rent valuation, sold-price history, price changes, and EV charging. Bulk Zoopla API.

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

## Pricing

from $6.75 / 1,000 property detail 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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 Detail Scraper — Valuation, by URL or Address 🏡

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Zoopla Scraper](https://img.shields.io/badge/Store-Zoopla%20Scraper-3B5998)](https://apify.com/sian.agency/zoopla-property-scraper?fpr=sian) [![Redfin Property Scraper](https://img.shields.io/badge/Store-Redfin%20Property%20Scraper-A02021)](https://apify.com/sian.agency/redfin-property-scraper?fpr=sian) [![Property Skip Tracing](https://img.shields.io/badge/Store-Property%20Skip%20Tracing-1AE392)](https://apify.com/sian.agency/property-skip-tracing?fpr=sian)

#### 🎉 The only Zoopla actor that returns a sale + rent VALUATION per property — the UK Zestimate, by listing URL/ID or any address
##### Built for PropTech teams, investors, and lead-gen — full UK dossiers plus valuation, sold-price history, and EV charging, one row per property

---

### 📋 Overview

**Turn any Zoopla listing — or any UK address — into a clean, structured dossier.** Paste listing URLs, listing IDs, or addresses with a postcode and get price, tenure, EPC, size, photos, nearby schools and transport, and the listing branch. Then toggle the headline add-on: a **Zoopla sale and rent valuation** — the UK equivalent of a Zestimate — that no other Zoopla tool offers.

**Why property teams choose us:**
- ✅ **Zoopla valuation per property**: sale + rent estimate, confidence band, and last-sale delta — by listing URL/ID **or by any UK address+postcode** (off-market homes included). Nobody else on the Store does this.
- ⚡ **Full UK dossier in one row**: price, tenure, leasehold years, ground rent, service charge, council-tax band, EPC rating, beds/baths/receptions, size in sqft, description, all photos + floor plans, nearby schools and transport links, and the listing branch.
- 🎯 **3 lookup modes, one clean schema**: listing URLs, listing IDs, and UK addresses — mix and match, duplicates removed automatically, one row per property.
- 💰 **Fair pricing, no punitive start fee**: pay per property, only for lookups that resolve — not-found lookups are **never billed**, and there is no $0.05 start tax.
- 💎 **Opt-in intelligence add-ons**: sold-price / land-registry history, dated price changes, and the 20 nearest EV charge points — data no Zoopla scraper exposes.
- ✨ **Bulk-ready**: feed hundreds of URLs, IDs, or addresses from a CSV and export clean JSON, CSV, or Excel.

---

### ✨ Features

- 💷 **Zoopla Valuation**: sale + rent estimate with lower/upper band, confidence, and last-sale change — the UK property valuation nobody else returns per listing.
- 🏡 **Complete Property Dossier**: tenure, lease years, ground rent, service charge, council-tax band, EPC, size, and full description.
- 🖼 **All Photos + Floor Plans**: every listing image URL and floor-plan bundled free with the base row.
- 🏫 **Neighbourhood Intel**: nearest schools, stations, tube, and transport links included at no extra charge.
- 📜 **Sold-Price & Land-Registry History**: past sales, prices, and photos per property (add-on).
- 📉 **Price-Change Tracking**: dated reductions and increases on the live listing (add-on).
- 🔌 **EV-Charging Proximity**: the 20 nearest public charge points to any listing (add-on).
- 🧭 **Three Lookup Modes**: URL, listing ID, or UK address — whichever your data has.
- 💰 **Pay-Per-Result**: charged only for properties that resolve; not-found lookups are free.

---

### 🎬 Quick Start

Add listing URLs, listing IDs, or UK addresses, pick any add-ons, and run. You get one dossier row per property in seconds.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~zoopla-property-detail-scraper/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"propertyUrls": ["https://www.zoopla.co.uk/for-sale/details/73767353/"], "includeValuation": true}'
````

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Add your properties

Paste Zoopla **listing URLs**, **listing IDs**, or **UK addresses (with postcode)** — one per line, mix and match.

#### Step 2: Pick add-ons (optional)

Toggle **Zoopla valuation**, **sold-price history**, **price changes**, or **EV charging** for extra intelligence per property.

#### Step 3: Run and export

Start the actor and download clean **JSON, CSV, or Excel** from the dataset.

**That's it! In under a minute, you'll have:**

- A structured dossier per property with price, tenure, EPC, and photos
- A Zoopla sale + rent valuation for every home (when toggled or looked up by address)
- Sold-price history, price changes, and nearby EV chargers on demand

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `propertyUrls` | array | No | Zoopla listing-details URLs (for-sale, to-rent, new-homes) |
| `listingIds` | array | No | Numeric Zoopla listing IDs (the digits after `/details/`) |
| `addresses` | array | No | Full UK addresses **including a postcode** — resolves to a valuation |
| `includeValuation` | boolean | No | Add-on: Zoopla sale + rent valuation for listing lookups |
| `includeSoldPriceHistory` | boolean | No | Add-on: land-registry / sold-price history |
| `includePriceChanges` | boolean | No | Add-on: dated price changes on the live listing |
| `includeEvCharging` | boolean | No | Add-on: 20 nearest EV charge points |

**Example — listing lookup with valuation:**

```json
{
  "propertyUrls": ["https://www.zoopla.co.uk/for-sale/details/73767353/"],
  "listingIds": ["73767353"],
  "includeValuation": true,
  "includeSoldPriceHistory": true
}
```

**Example — value any UK address (no live listing needed):**

```json
{
  "addresses": ["Cranley Close, Guildford, GU1 2JN"],
  "includeSoldPriceHistory": true
}
```

***

### 📤 Output

Results are saved to the Apify dataset with **60+ fields** per property, including:

| Field | Type | Description |
|-------|------|-------------|
| `listingId` | string | Zoopla listing ID |
| `displayAddress` | string | Property address |
| `postcode` | string | Full UK postcode |
| `price` / `priceValue` | string / number | Display price and numeric GBP value |
| `section` | string | for-sale, to-rent, or new-homes |
| `propertyType` | string | flat, detached, terraced, ... |
| `beds` / `baths` / `receptions` | number | Room counts |
| `sizeSqft` | number | Floor size in square feet |
| `tenureLabel` | string | Freehold / leasehold / share of freehold |
| `leaseholdYears` | number | Remaining lease years |
| `councilTaxBand` | string | Council-tax band |
| `epcRating` | string | EPC energy rating (A–G) |
| `photos` / `floorPlans` | array | All image URLs |
| `pointsOfInterest` / `transports` | array | Nearby schools + transport |
| `branchName` | string | Listing branch / agent |
| `valuation` | object | Zoopla sale + rent estimate (band + confidence) |
| `soldPriceHistory` | object | Land-registry sale history (add-on) |
| `priceChanges` | object | Dated price changes (add-on) |
| `evCharging` | object | 20 nearest EV charge points (add-on) |

**Example:**

```json
{
  "listingId": "73767353",
  "uprn": "10009804462",
  "displayAddress": "Southwark Bridge Road, Borough, London SE1",
  "postcode": "SE1 0BQ",
  "price": "£550,000",
  "priceValue": 550000,
  "section": "for-sale",
  "propertyType": "flat",
  "beds": 2,
  "baths": 2,
  "sizeSqft": 764,
  "tenureLabel": "Share of freehold",
  "councilTaxBand": "A band has not yet been confirmed.",
  "epcRating": "B",
  "valuation": {
    "saleEstimateCurrent": 586000,
    "saleEstimateLower": 556000,
    "saleEstimateUpper": 615000,
    "saleConfidence": "HIGH",
    "rentEstimateCurrent": 2750,
    "currency": "GBP"
  },
  "branchName": "Kinleigh Folkard & Hayward - Kennington"
}
```

***

### 💼 Use Cases & Examples

#### 1. Zoopla Valuation for Any UK Address

**Analysts and PropTech teams valuing a portfolio or a lead list.**

**Input:** UK addresses with postcodes.
**Output:** A Zoopla sale + rent estimate with confidence band and last-sale delta per address.
**Use:** Value off-market homes, seed AVMs, or benchmark asking prices — no live listing required.

#### 2. Bulk Listing Enrichment for PropTech ETL

**Data engineers feeding a warehouse.**

**Input:** Zoopla URLs or listing IDs from your pipeline.
**Output:** Clean 60+ field dossiers ready for BigQuery, Snowflake, or pandas.
**Use:** Replace brittle in-house Zoopla scraping with a structured, bulk-ready feed.

#### 3. Investor Underwriting with Sold-Price History

**Buy-to-let and flip investors.**

**Input:** Listing IDs plus the sold-price and price-change add-ons.
**Output:** Land-registry sale history and dated reductions per property.
**Use:** Build comps, gauge negotiation room, and time offers.

#### 4. Lead-List Enrichment with Branch & Agent

**Agents and prop-tech marketers.**

**Input:** A CSV of Zoopla URLs.
**Output:** Rows with the listing branch, price, tenure, and full attributes.
**Use:** Prioritise outreach and sync straight into a CRM.

#### 5. Amenity & EV-Readiness Screening

**Developers, relocation, and lending teams.**

**Input:** Listing IDs with the EV-charging add-on.
**Output:** Nearby schools and transport (free) plus the 20 nearest EV chargers.
**Use:** Score liveability and EV readiness at scale.

***

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/zoopla-property-detail-scraper').call({
  propertyUrls: ['https://www.zoopla.co.uk/for-sale/details/73767353/'],
  includeValuation: true
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/zoopla-property-detail-scraper').call(
    run_input={'addresses': ['Cranley Close, Guildford, GU1 2JN']}
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~zoopla-property-detail-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"listingIds": ["73767353"], "includeSoldPriceHistory": true}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: Schedule or webhook
2. **HTTP Request**: Call the actor API
3. **Process**: Handle JSON results
4. **Action**: Save, notify, or transform

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **Up to 5 properties** per run — full dossier quality
- No credit card required
- Perfect for testing and small projects

#### PAID Tier (Production Ready)

- **Unlimited** properties per run
- All add-ons unlocked: valuation, sold-price history, price changes, EV charging
- Pay-per-result: charged only for properties that resolve; not-found lookups are free

💰 **Fair, transparent pricing** — a per-property base rate plus a small charge only for add-ons that actually return data, and a start fee 10× lower than the incumbent detail tool.

🔗 [View current pricing](https://apify.com/sian.agency/zoopla-property-detail-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: How many properties can I process?**
A: FREE tier: up to 5 per run. PAID tier: unlimited.

**Q: Can I get a Zoopla valuation without a live listing?**
A: Yes — use the `addresses` input with a full UK postcode. Each address resolves to a sale + rent estimate, even for off-market homes.

**Q: What happens if a property isn't found?**
A: It's skipped and you are **never charged** for it.

**Q: What input does the address mode need?**
A: A full UK address including the postcode, e.g. `Cranley Close, Guildford, GU1 2JN`. Addresses without a postcode are rejected before any charge.

**Q: What output formats are available?**
A: JSON, CSV, and Excel — export directly from the Apify dataset.

**Q: Is this legal?**
A: Yes — we only extract publicly available data. See the legal section below.

**Q: How much does each add-on cost?**
A: Each successful add-on (valuation, sold-price history, price changes, EV charging) is charged once, and only when it returns data.

***

### 🐛 Troubleshooting

**Address lookup returns "not found"**

- Make sure the address includes a **full UK postcode** (e.g. `SE1 0BQ`).
- Use the format `street, town, POSTCODE`.

**A listing URL is rejected**

- Use a listing-**details** URL (`zoopla.co.uk/.../details/<id>/`), not a search-results page.

**An add-on returned nothing**

- Add-ons only apply where they make sense (price changes and EV charging need a live listing) and are only charged when data is returned — a blank add-on is free.

**Fewer rows than inputs**

- Duplicates across URL / ID / address modes are removed automatically, and not-found lookups are skipped.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### ⚠️ Trademark Disclaimer

Zoopla™ is a trademark of Zoopla Limited. This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by** Zoopla Limited. All product names, logos, and brands are the property of their respective owners and are used for identification and descriptive purposes only. This actor only accesses publicly available information and is intended for lawful use in compliance with applicable terms and regulations.

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue in the actor's repository
- Check [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `propertyUrls` (type: `array`):

🏡 **LOOKUP BY URL:** Paste Zoopla listing-details links, one per line.

📋 **How to get a URL:**

1. Open any listing on zoopla.co.uk
2. Copy the browser address — it looks like `https://www.zoopla.co.uk/for-sale/details/73767353/`
3. Paste it here (Bulk edit accepts one URL per line)

✅ **SUPPORTED:** `zoopla.co.uk/.../details/...` listing pages (for-sale, to-rent, new-homes)
🚫 **NOT supported:** search-result pages like `zoopla.co.uk/for-sale/property/london/` — use our Zoopla Scraper for those

💡 **TIP:** Mix and match with listing IDs and addresses below — duplicates are removed automatically.

⚡ **TIER LIMITS:** FREE runs process up to 5 properties total; paid Apify plans are unlimited.

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

🔢 **LOOKUP BY LISTING ID:** The numeric ID from any Zoopla listing URL — the digits right after `/details/`.

📋 **Example:** for `.../details/73767353/` the listing ID is `73767353`.

💡 **TIP:** Ideal when your database already stores Zoopla IDs — the fastest, most exact lookup mode.

⚡ **TIER LIMITS:** FREE runs process up to 5 properties total; paid Apify plans are unlimited.

## `addresses` (type: `array`):

📍 **LOOKUP BY ADDRESS:** Full UK addresses INCLUDING a postcode, one per line — resolves to a Zoopla sale and rent valuation for that address (no live listing required, off-market homes included).

📋 **Format:** `street, town, POSTCODE` — e.g. `Cranley Close, Guildford, GU1 2JN`.

⚠️ **A full UK postcode is required** (e.g. `SE1 0BQ`). Addresses without one are rejected.

💡 **TIP:** Perfect for valuing a CSV of addresses — each resolves to `saleEstimate` + `rentEstimate` with a confidence band. Toggle the sold-price add-on for land-registry history too.

⚡ **TIER LIMITS:** FREE runs process up to 5 properties total; paid Apify plans are unlimited.

## `includeValuation` (type: `boolean`):

💷 **VALUATION ADD-ON:** For listing (URL / listing ID) lookups, fetches the Zoopla sale and rent estimate — current value, lower/upper band, confidence, and last-sale delta.

ℹ️ Address lookups already include the valuation in the base row, so this toggle has no extra effect on them.

💰 Adds one enrichment charge per property (only when an estimate is returned).

⚡ Available on paid Apify plans.

## `includeSoldPriceHistory` (type: `boolean`):

📜 **SOLD-PRICE ADD-ON:** Land-registry sale and historic-listing records for the property — dates, prices, beds/baths, and photos per past sale.

💰 Adds one enrichment charge per property (only when history is returned).

⚡ Available on paid Apify plans.

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

📉 **PRICE-CHANGE ADD-ON:** Dated price reductions and increases on the live listing — the market-timing signal for offers.

💰 Adds one enrichment charge per property (only when the listing has recorded price changes). Applies to listing (URL / listing ID) lookups.

⚡ Available on paid Apify plans.

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

🔌 **EV-CHARGING ADD-ON:** The nearest public EV charge points to the listing — name, address, distance, and connector count for the 20 closest.

💰 Adds one enrichment charge per property (only when charge points are returned). Applies to listing (URL / listing ID) lookups.

⚡ Available on paid Apify plans.

## Actor input object example

```json
{
  "propertyUrls": [
    "https://www.zoopla.co.uk/for-sale/details/73767353/"
  ],
  "listingIds": [
    "73767353"
  ],
  "addresses": [
    "Cranley Close, Guildford, GU1 2JN"
  ],
  "includeValuation": false,
  "includeSoldPriceHistory": false,
  "includePriceChanges": false,
  "includeEvCharging": false
}
```

# Actor output Schema

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

One row per property: price, tenure, lease and ground rent, council-tax band, EPC, photos, floor plans, nearby POI and transport, branch, and optional Zoopla valuation / sold-price history / price changes / EV charging add-ons

## `scrapingSummary` (type: `string`):

HTML summary showing extracted dossiers, not-found lookups, failures, and charged add-ons

# 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-detail-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-detail-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-detail-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Zoopla Property Detail Scraper — Valuation, by URL or Address",
        "description": "Paste Zoopla URLs, listing IDs, or UK addresses and get a full property dossier: price, beds, tenure, lease and ground rent, council-tax band, EPC, photos, floor plans, and agent. Add Zoopla sale and rent valuation, sold-price history, price changes, and EV charging. Bulk Zoopla API.",
        "version": "1.0",
        "x-build-id": "Vebe16XRxiCVRjeIc"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~zoopla-property-detail-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-zoopla-property-detail-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/sian.agency~zoopla-property-detail-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-zoopla-property-detail-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/sian.agency~zoopla-property-detail-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-zoopla-property-detail-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "propertyUrls": {
                        "title": "🏡 Zoopla Listing URLs",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "🏡 **LOOKUP BY URL:** Paste Zoopla listing-details links, one per line.\n\n📋 **How to get a URL:**\n1. Open any listing on zoopla.co.uk\n2. Copy the browser address — it looks like `https://www.zoopla.co.uk/for-sale/details/73767353/`\n3. Paste it here (Bulk edit accepts one URL per line)\n\n✅ **SUPPORTED:** `zoopla.co.uk/.../details/...` listing pages (for-sale, to-rent, new-homes)\n🚫 **NOT supported:** search-result pages like `zoopla.co.uk/for-sale/property/london/` — use our Zoopla Scraper for those\n\n💡 **TIP:** Mix and match with listing IDs and addresses below — duplicates are removed automatically.\n\n⚡ **TIER LIMITS:** FREE runs process up to 5 properties total; paid Apify plans are unlimited.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "listingIds": {
                        "title": "🔢 Listing IDs",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "🔢 **LOOKUP BY LISTING ID:** The numeric ID from any Zoopla listing URL — the digits right after `/details/`.\n\n📋 **Example:** for `.../details/73767353/` the listing ID is `73767353`.\n\n💡 **TIP:** Ideal when your database already stores Zoopla IDs — the fastest, most exact lookup mode.\n\n⚡ **TIER LIMITS:** FREE runs process up to 5 properties total; paid Apify plans are unlimited.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "addresses": {
                        "title": "📍 UK Addresses (with postcode)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "📍 **LOOKUP BY ADDRESS:** Full UK addresses INCLUDING a postcode, one per line — resolves to a Zoopla sale and rent valuation for that address (no live listing required, off-market homes included).\n\n📋 **Format:** `street, town, POSTCODE` — e.g. `Cranley Close, Guildford, GU1 2JN`.\n\n⚠️ **A full UK postcode is required** (e.g. `SE1 0BQ`). Addresses without one are rejected.\n\n💡 **TIP:** Perfect for valuing a CSV of addresses — each resolves to `saleEstimate` + `rentEstimate` with a confidence band. Toggle the sold-price add-on for land-registry history too.\n\n⚡ **TIER LIMITS:** FREE runs process up to 5 properties total; paid Apify plans are unlimited.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "includeValuation": {
                        "title": "💷 Zoopla valuation (add-on)",
                        "type": "boolean",
                        "description": "💷 **VALUATION ADD-ON:** For listing (URL / listing ID) lookups, fetches the Zoopla sale and rent estimate — current value, lower/upper band, confidence, and last-sale delta.\n\nℹ️ Address lookups already include the valuation in the base row, so this toggle has no extra effect on them.\n\n💰 Adds one enrichment charge per property (only when an estimate is returned).\n\n⚡ Available on paid Apify plans.",
                        "default": false
                    },
                    "includeSoldPriceHistory": {
                        "title": "📜 Sold-price history (add-on)",
                        "type": "boolean",
                        "description": "📜 **SOLD-PRICE ADD-ON:** Land-registry sale and historic-listing records for the property — dates, prices, beds/baths, and photos per past sale.\n\n💰 Adds one enrichment charge per property (only when history is returned).\n\n⚡ Available on paid Apify plans.",
                        "default": false
                    },
                    "includePriceChanges": {
                        "title": "📉 Price changes (add-on)",
                        "type": "boolean",
                        "description": "📉 **PRICE-CHANGE ADD-ON:** Dated price reductions and increases on the live listing — the market-timing signal for offers.\n\n💰 Adds one enrichment charge per property (only when the listing has recorded price changes). Applies to listing (URL / listing ID) lookups.\n\n⚡ Available on paid Apify plans.",
                        "default": false
                    },
                    "includeEvCharging": {
                        "title": "🔌 EV charging (add-on)",
                        "type": "boolean",
                        "description": "🔌 **EV-CHARGING ADD-ON:** The nearest public EV charge points to the listing — name, address, distance, and connector count for the 20 closest.\n\n💰 Adds one enrichment charge per property (only when charge points are returned). Applies to listing (URL / listing ID) lookups.\n\n⚡ Available on paid Apify plans.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
