OnTheMarket Scraper - UK Property Listings & Agent Contacts
Pricing
from $1.00 / 1,000 property listings
OnTheMarket Scraper - UK Property Listings & Agent Contacts
Scrape onthemarket.com for-sale, to-rent and new-homes listings with 85+ fields: price, address & geo, bedrooms/bathrooms, full description, key info, nearest stations & schools, area stats, floorplans, virtual tours and complete agent contacts. Search by location + filters or paste URLs.
Pricing
from $1.00 / 1,000 property listings
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
1
Total users
0
Monthly active users
16 days ago
Last modified
Categories
Features
Share
OnTheMarket Scraper: UK Property Listings, Prices and Agent Contacts
OnTheMarket Scraper turns onthemarket.com into a clean UK property data feed. Get for-sale, to-rent and new-homes listings with prices in GBP, full address and geolocation, bedrooms and bathrooms, property features and media, and complete estate-agent contact details. Search by location and filters, or paste your own search or property URLs, then turn on full property details for descriptions, key info, floorplans, nearby stations and schools, and area stats. Export the dataset to JSON, CSV or Excel, or read it straight through the API.
Why This Scraper?
- Two ways to find properties. Search by location plus filters, or paste OnTheMarket search-result or property-details URLs. No need to build search URLs by hand.
- Three channels in one actor. For-sale, to-rent and new-homes listings, all read from the same search and detail pages.
- Rich fields, two depths. Every search card carries about 28 fields; turn on full property details to expand each record to 85+ fields.
- Direct agent contacts. Agent name, company, phone, website, contact URL and address are captured straight from the listing, never inferred or guessed.
- Search-side filters. Price, bedrooms, property type, radius and sort order, plus an include-under-offer / SSTC toggle, all applied as OnTheMarket's own query parameters so the site does the narrowing.
- UK-specific detail. EPC energy rating, tenure, council tax band, stamp duty label, and nearby stations and schools are captured on enriched records.
- A steady connection. The run rotates its connection automatically if a request is refused, so a large search keeps going without manual intervention.
Use Cases
- Property portals and lead tools: mirror OnTheMarket's for-sale, to-rent and new-homes inventory into your own site, app or feed.
- Estate agent directories and prospecting: build a list of active agents, their listings and direct contact details by area.
- Market and pricing research: track asking prices, price qualifiers and stock levels across UK towns, postcodes and property types.
- House-hunting and relocation tools: feed a personal search (location, budget, bedrooms, property type) into a spreadsheet, bot or notification app.
- Academic and planning research: study housing supply, property mix and new-build activity across regions.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
id | "12345678" |
url | OnTheMarket link to the property |
channel | "FOR-SALE" (also "TO-RENT", "NEW-HOMES") |
propertyTitle | "3 bedroom detached house for sale" |
humanisedPropertyType | "Detached house" |
displayAddress | "42 Sample Road, Sampleton, London, SW0 0AA" |
bedrooms / bathrooms | 3 / 2 |
displayPrice | "ยฃ450,000" |
price | 450000 |
priceQualifier | "Guide price" |
latitude / longitude | 51.5074 / -0.1278 |
mainLabel | "New" |
daysSinceAddedReduced | "Added today" |
features | ["Detached", "Off-street parking", "Garden"] |
images | array of listing photo URLs |
agentName / agentId | "Sample Estates" / 4321 (plus shortPrice and agentLogo) |
feesLabel / feesDescription | tenancy or fee information text on the card (rentals) |
sourceUrl | the results page the listing was read from |
seedType / seedValue | what started the row: "location" with the location text, or "url" with the start URL |
rawAgent | the complete verbatim agent object from the listing |
detailScraped | true when full property details were fetched for this row |
description | full listing description text (when full details are on) |
keyInfo | tenure, council tax band, EPC rating and similar facts (when full details are on) |
station / school | nearby stations / schools with distance (when full details are on) |
agentPhone / agentWebsiteUrl / agentContactUrl | direct agent phone, website and contact-page link (when full details are on) |
With Include full property details on, records also carry summary, rooms, priceRaw, stampDutyLabel, floorplans, videos, virtualtours, minimumAreaSqFt / minimumAreaSqM, areaStats, poi, canonicalUrl, agentCompanyName, agentPhoneEnquiries, agentAddress, agentPostcode and agentBranchId.
How to Use
- Pick a mode: search by location and filters, or paste URLs.
- For search mode, choose a channel and one or more locations, then narrow with price, bedrooms, property type, radius or sort order.
- Turn on Include full property details if you need descriptions, key info, floorplans, nearby stations and schools, and full agent contacts.
- Set Max items (and, if needed, Max pages) to control run size and cost, then click Start.
Houses for sale in London, mid-range price band:
{"mode": "search","channel": "FOR-SALE","locations": ["London"],"minPrice": 500000,"maxPrice": 1000000,"propertyTypes": ["houses"],"sortType": "price-asc","maxItems": 50}
Two to three bedroom rentals in Manchester, with full details:
{"mode": "search","channel": "TO-RENT","locations": ["Manchester"],"minBedrooms": 2,"maxBedrooms": 3,"includeDetails": true,"maxItems": 30}
Pasted Start URLs in search mode. If you paste your own Start URLs but leave Mode on Search and Locations at its London default (or empty), the run switches to URL mode and scrapes your URLs, so you are not billed for London listings you did not ask for. If you changed Locations, Search mode wins and the pasted URLs are ignored with a warning in the run log; set Mode to URL to scrape them.
URL mode left unedited. If you switch to URL mode and leave Start URLs as it is, the run now scrapes one example of each supported URL shape (sale, filtered and sorted, page 2 of a search, to-rent, new homes by path or by flag, postcode, a property page with or without the trailing slash, a place landing page, an agent branch and an agents directory), up to Max items. Replace the list with your own links for a real run. Filters, sort and page in a pasted URL are kept as written.
Agent pages. An agent branch page returns one agent record and an agents directory returns one record per agent, walking its pages up to Max items or Max pages. Listing rows carry recordType: "property" and agent records carry recordType: "agent", are billed like any other delivered dataset row, and are not part of incremental change tracking.
Paste a search page and a property page together:
{"mode": "url","startUrls": ["https://www.onthemarket.com/for-sale/property/bath/","https://www.onthemarket.com/details/12345678/"],"includeDetails": true,"maxItems": 40}
New homes near a postcode area, including under offer:
{"mode": "search","channel": "NEW-HOMES","locations": ["SW19"],"radius": "5","includeUnderOffer": true,"maxItems": 25}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/onthemarket-scraper").call(run_input={"mode": "search","channel": "FOR-SALE","locations": ["London"],"maxItems": 20,})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["displayAddress"], listing["displayPrice"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/onthemarket-scraper').call({mode: 'search',channel: 'FOR-SALE',locations: ['London'],maxItems: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How Max items and Max pages interact
By default there is no page limit: the run walks forward through OnTheMarket's result pages until Max items is reached or the site stops returning a next page. Set Max pages only if you want a hard ceiling on how many pages a single location or pasted URL walks, independent of Max items.
Incremental mode (recurring monitoring)
Turn on Incremental mode to run the same search on a schedule and get only what changed. The first run returns every matching listing as NEW. Later runs compare each listing with the last run and return only NEW, UPDATED and REAPPEARED listings. Each row carries changeType, changedFields (for UPDATED, the fields that moved), firstSeenAt and lastSeenAt.
- The days-since-added counter, the age and promotion labels (
mainLabel,dataLabelId,primaryPropertyLabel,propertySticker,premium,spotlight), image lists, area statistics, the view counter and the similar-property lists stay in the output but are never compared, so a listing cannot turn intoUPDATEDjust because it got older ("Added today" to "Recently added") or its promotion slot changed. Add more with Ignore fields when detecting changes. - State is kept per search setup (locations or URLs, channel, filters, details on or off) or under your State key.
- Emit unchanged and Emit expired add
UNCHANGEDandEXPIREDrows. Billing: every row the run returns is stored in the default dataset and billed through the same per-listing event as a normal run (plus the detail event when details are on), soUNCHANGEDandEXPIREDrows you ask for are billed like any other returned row. Listings that are suppressed because they did not change are not returned and not billed, so leave both switches off to pay only forNEW,UPDATEDandREAPPEAREDrows. - Max items counts every returned row (including
UNCHANGEDandEXPIREDrows when switched on); suppressed unchanged listings use no slot. A listing is only remembered as delivered once its row was really stored: rows cut by Max items or the maximum cost limit are not saved to the baseline, so the next run returns them again. A run cut short by Max items, Max pages, Resume, a failed page, a single listing URL or a results page opened past its first page never marks anythingEXPIRED. - With Include full property details on, a listing whose details page could not be loaded this run is left as it was, not reported as changed.
Searching more than one location or URL in one run
Within a single run, a property that turns up again under a later location or pasted URL is only returned, and billed, once. Genuinely different listings found afterwards are not affected, so an overlapping search area does not cost you extra rows or lose the rest of that page's results.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed, and only rows delivered to the dataset are sent.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify โ Settings โ Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the
mcpConnectorsfield ("Pipe results into your apps"). If the picker is empty, you have not authorized a connector yet. - For Notion, also set
notionParentPageUrlto the page where items should be created. maxNotifyListingscaps how many items are written to each connector per run.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (location + filters) or url (paste links). |
channel | string | FOR-SALE | Which listings to scrape (search mode): FOR-SALE, TO-RENT, or NEW-HOMES. |
locations | array | ["London"] | Towns, cities, postcodes or areas to search (search mode). If left empty in search mode, the run searches London. |
startUrls | array | one example of each URL shape | URL mode only: OnTheMarket search-result URLs (sale, to-rent, new homes, postcode, with filters, sort and page), /details/{id}/ URLs, /property/{place}/ landing pages (read as the for-sale search for that place), agent branch pages and agents directories. |
minPrice | integer | (none) | Lowest price: sale price, or monthly rent for to-rent. |
maxPrice | integer | (none) | Highest price: sale price, or monthly rent for to-rent. |
minBedrooms | integer | (none) | Fewest bedrooms. |
maxBedrooms | integer | (none) | Most bedrooms. |
propertyTypes | array | (none) | Filter by property type. Includes flats-apartments (flat + apartment) and mobile-park-homes. Leave empty for all types. |
radius | string | (none) | Expand the search around the location, from a quarter mile up to 40 miles. |
sortType | string | recommended | recommended, price-asc, or price-desc. |
includeUnderOffer | boolean | false | Also include listings that are under offer or sold subject to contract. |
addedToSite | string | none | Only listings added in the last 24-hours, 3-days or 7-days. |
includeDetails | boolean | false | Fetch each property's details page for the full description, key info, floorplans, nearby stations and schools, area stats, and complete agent contact details. |
maxItems | integer | 20 | Maximum number of listings to return (the run cap). Set to 0 for no item limit. |
maxPages | integer | 0 | Cap on how many result pages are walked. 0 means no page limit (stops at Max items). |
proxyConfiguration | object | {"useApifyProxy": true} | Proxy settings for the run. Runs on any Apify plan. |
resumeFromRunId | string | (none) | Resume: ID of a previous run (or dataset) of this actor. Listings and agent records already in that dataset are skipped, so the run returns only the rows not collected yet. |
incrementalMode | boolean | false | Recurring monitoring: first run returns everything as NEW, later runs return only NEW, UPDATED and REAPPEARED listings. |
stateKey | string | (none) | Optional name for a monitoring campaign (incremental mode only). Empty derives a key from the search settings. |
emitUnchanged | boolean | false | Also return listings that did not change, marked UNCHANGED (billed like any returned row, counted in Max items). |
emitExpired | boolean | false | Also return listings no longer found after a complete scan, marked EXPIRED (billed like any returned row, counted in Max items). |
ignoreFieldsForChanges | array | (none) | Extra top-level field names to leave out of change detection (incremental mode only). |
mcpConnectors | array | (none) | Optional MCP connectors (Notion, Linear, Airtable, Apify) that receive a summary of each delivered row. |
notionParentPageUrl | string | (none) | Notion page under which item pages are created (Notion connector only). |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"id": "12345678","url": "https://www.onthemarket.com/details/12345678/","channel": "FOR-SALE","propertyTitle": "3 bedroom detached house for sale","humanisedPropertyType": "Detached house","bedrooms": 3,"bathrooms": 2,"displayPrice": "ยฃ450,000","price": 450000,"priceQualifier": "Guide price","displayAddress": "42 Sample Road, Sampleton, London, SW0 0AA","latitude": 51.5074,"longitude": -0.1278,"mainLabel": "New","daysSinceAddedReduced": "Added today","features": ["Detached", "Off-street parking", "Garden"],"images": ["https://media.onthemarket.com/sample/1.jpg", "https://media.onthemarket.com/sample/2.jpg"],"description": "A well presented three bedroom detached house close to local amenities and transport links.","keyInfo": ["Tenure: Freehold", "Council tax band: D", "EPC rating: C"],"station": [{ "name": "Sample Park", "distanceMiles": 0.4 }],"school": [{ "name": "Sample Primary School", "distanceMiles": 0.3 }],"agentName": "Sample Estates","agentCompanyName": "Sample Estates Ltd","agentPhone": "01632 960001","agentWebsiteUrl": "https://www.sample-estates.example","agentContactUrl": "https://www.onthemarket.com/agents/sample-estates/contact/","agentAddress": "1 Sample Parade, Sampleton, SW0 0AA","rawAgent": { "id": 4321, "name": "Sample Estates" },"detailScraped": true}
keyInfo, station, school, areaStats, poi and rawAgent are passed through as OnTheMarket publishes them, so their inner structure follows the site and the nested values above are only a sketch.
Plan Requirement
The default proxy setting (datacenter) returned pages in our checks, so the run works out of the box on any Apify plan. If a request is refused, the run rotates its connection automatically. For large or frequent searches, the residential proxy group gives more headroom; pick it under Connection. If every request is refused for the whole run, the run fails with a clear message instead of finishing empty (see the FAQ).
FAQ
How much does it cost?
Billing uses three events: one per delivered dataset row (listing rows and agent rows alike), one per listing enriched with Include full property details, and one per-run start. Rows that are not delivered (unchanged listings suppressed by Incremental mode, or failed pages) are not billed; every row that is delivered is billed, including UNCHANGED and EXPIRED rows when you switch them on. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape OnTheMarket?
This actor collects only publicly available property listing data as published on OnTheMarket. You are responsible for how you use it: follow OnTheMarket's terms and the laws that apply to you, including data-protection rules where you use agent contact details for outreach, and get legal advice if you plan commercial redistribution.
Can I get only new listings on a schedule?
Yes. Turn on Incremental mode (see above) and schedule the run: each run returns only new, updated or reappeared listings, and you are billed only for the rows it returns. To continue one specific interrupted run instead, paste its run ID into Resume from a previous run.
Why did a run return fewer listings than Max items?
A few honest reasons: Max pages stopped the page walk before Max items was reached; the search area genuinely has fewer results than Max items; or OnTheMarket did not recognise a location string, so the run tried a best-guess area name built from your text, and when that page did not exist the location was skipped with a note in the run log. Use the place names OnTheMarket's own search box suggests to avoid this. A listing that appears again under a later location or URL in the same run is only counted once, not treated as new.
Why did my run fail with "Could not load any results page"?
If every request to OnTheMarket is refused and no page is retrieved at all, the run ends as Failed with the message "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later." It is not reported as an empty success, and nothing is billed for rows that were never delivered. The run summary saved as OUTPUT in the key-value store shows requests, blocks and rotations. Retry later or choose the residential proxy group under Connection.
A search that genuinely has no matches, or a page OnTheMarket reports as not found (HTTP 404), is different: the run finishes normally with zero items and a "No results" note in the log. Open the same search on onthemarket.com to confirm it really has results.
Does this include estate agent reviews or ratings?
No. OnTheMarket does not publish estate-agent reviews, ratings or testimonials, so none are collected. The EPC energy rating shown in keyInfo is a property attribute, not an agent rating.
Can I use it with AI agents or automation platforms?
Yes. Call it from the API, the Scheduler, or any Apify integration (Make, Zapier, n8n, Google Sheets, webhooks), or from an MCP client through Apify's own MCP server.
๐ Want more real estate data?
Pair this actor with these related scrapers from the same team:
| ๐ Rightmove Fast, reliable Rightmove.co.uk scraper for sale, rent, and sold-price listings. Search by... | ๐ PropertyGuru SG Scraper Scrape PropertyGuru.com.sg sale and rental listings with 30+ structured fields, including... |
| ๐ Jitty Scraper Scrape residential property listings from Jitty.com across the UK. Search with 20+... | ๐ Homes.co.nz Scraper Scrape Homes.co.nz listings by location or URL with pagination. Extract property details... |
| ๐ Apartments.com Scraper Scrape Apartments.com rentals by city, ZIP, neighborhood, address or URL. Extract rent... | ๐ค AU Residential Property Scraper Scrape Australian real estate listings with detailed property information. Extract... |
๐ Browse all abotapi scrapers
๐ฌ Support
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
- โญ Enjoying it? A quick review on the actor page helps other users find it.