Properstar - Global Property Listings, URLs & Agency Data avatar

Properstar - Global Property Listings, URLs & Agency Data

Pricing

from $1.50 / 1,000 results

Go to Apify Store
Properstar - Global Property Listings, URLs & Agency Data

Properstar - Global Property Listings, URLs & Agency Data

Extract property listings from Properstar across global domains like .com, .co.uk, .ch, and .fr. Use search pages, listing URLs, or agency pages. Returns prices, multilingual descriptions, photos, floor plans, GPS coordinates, and agency details via Properstar’s data service.

Pricing

from $1.50 / 1,000 results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

3

Total users

1

Monthly active users

8 days ago

Last modified

Share

Properstar Scraper: Listings, Prices, Photos & Agency Data

Properstar Scraper turns Properstar into structured property data across every country domain it runs on (.com, .co.uk, .ch, .fr, and more), auto-detected from the URL you paste. Paste a search-results page, a single listing page, or an agency or agent page, and get clean records with prices, multilingual titles and descriptions, photos, floor plans, GPS coordinates, energy ratings, and agency contact details. Switch on full detail for amenities, view types, construction year, and floor, then export to JSON, CSV, or Excel, or pull results straight into your app through the API.

Why This Scraper?

  • Any Properstar country domain, auto-detected from the URL you paste, no domain allowlist to work around.
  • Three input shapes in one actor: search-results pages, single listing pages, and agency or agent pages.
  • Multilingual titles and descriptions captured per language, not just one.
  • 50+ named fields per listing, plus the complete source object so nothing is lost.
  • Optional full detail mode adds amenities, AI-extracted view types, construction year, and floor to search and agency results (listing-page URLs always include these).
  • Full measurements: living and land area in both square metres and square feet, alongside rooms, bedrooms, bathrooms, and energy/CO2 ratings.
  • Built for monitoring: incremental mode returns only new and changed listings on recurring runs, and a fully rejected run fails loudly instead of returning an empty dataset.

Use Cases

  • Real estate portals and PropTech tools: aggregate live listings across multiple country domains into one structured feed.
  • Investors and relocation agencies: compare prices, sizes, and locations across countries and currencies from a single search.
  • Market researchers and analysts: track price and inventory changes over time with incremental monitoring.
  • Lead generation and CRM tools: pull agency and agent contact details tied to their current live inventory.
  • Content and comparison sites: build country or city listing pages from live search results.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
id"100000001"
url"https://www.properstar.co.uk/listing/100000001"
class"PropertyListing" (also "ProjectListing", "UnitListing" on agency/agent inventory)
transactionType"Sell" (also "Rent")
type / subType"Apartment" / "Penthouse"
title"Sample listing title"
description"Full description text appears here."
titleByLanguage / descriptionByLanguage{ "en": "Sample listing title" }, one entry per language
price / currency1000000 / "GBP"
livingAreaSqm / landAreaSqm120 / 0
livingAreaSqft / landAreaSqft1291 / 0
rooms / bedrooms / bathrooms4 / 3 / 2
floor / constructionYear"3" / 2020 (full detail mode)
address / city / postcode"Sample Street 1" / "London" / "SW1"
countryISO"GB"
latitude / longitude51.5000 / -0.1200
pictures / picturesCount["https://images.example.com/0001.jpg"] / 12
floorPlans["https://images.example.com/plan-0001.jpg"]
amenities / views["Balcony", "Parking"] / ["City"] (full detail mode)
status"Published"
energyRating / co2Rating"C" / "B"
agencyId / agencyName1000000 / "Sample Agency"
publicationDate"2026-01-01T00:00:00Z"
changeType / changedFields"NEW" / ["price"] (incremental mode only)

Every record also carries agencySlug, agencyType, and agencyStatistics for the listing's agency; firstSeenAt and lastSeenAt in incremental mode; and the complete source object as raw, so nothing from Properstar's own data is lost.

How to Use

  1. Paste one or more Properstar URLs into Properstar URLs: search-results pages, single listing pages, or agency/agent pages, from any country domain.
  2. For search-page URLs, optionally refine with Transaction type, Property types, price and bedroom range, or Luxury listings only.
  3. Turn on Fetch full detail if you want amenities, view types, construction year, and floor on search or agency results (listing-page URLs always include these).
  4. Set Max listings and Max pages per URL to control run size and cost, then click Start.

Basic search page:

{
"startUrls": ["https://www.properstar.co.uk/united-kingdom/london/buy/apartment-house"],
"maxItems": 50
}

Search page with refinement filters:

{
"startUrls": ["https://www.properstar.com/spain/barcelona/buy/apartment-house"],
"transactionType": "buy",
"propertyTypes": ["apartment"],
"minPrice": 300000,
"maxPrice": 800000,
"minBedrooms": 2,
"maxItems": 200
}

Single listing (always full detail):

{
"startUrls": ["https://www.properstar.co.uk/listing/100000001"]
}

Agency or agent inventory:

{
"startUrls": ["https://www.properstar.co.uk/agency/sample-agency/1000000"],
"maxItems": 100,
"enrichDetail": true
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/properstar-scraper").call(run_input={
"startUrls": ["https://www.properstar.co.uk/united-kingdom/london/buy/apartment-house"],
"maxItems": 50,
})
for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
print(listing["title"], listing["price"], listing["currency"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/properstar-scraper').call({
startUrls: ['https://www.properstar.co.uk/united-kingdom/london/buy/apartment-house'],
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Caps and cost controls

  • Max listings (maxItems) stops the run once this many listings, across all URLs, have been returned. 0 is unlimited.
  • Max pages per URL (maxPagesPerUrl) caps how many 25-listing pages are walked per search or agency URL. Leave it empty (0) to walk every page until the site's own end of results, capped at roughly 2000 retrievable listings per URL.
  • Residential traffic budget (maxResidentialMb) caps the residential-exit browser traffic used for connection setup and, when Fetch full detail is on, per-listing detail fetches. The budget is estimated per page opened, not metered byte for byte. Once spent, the run keeps going and finishes the already-cheap list pagination, but stops fetching further detail pages. 0 means no cap.

Known limitation: overlapping URLs end early. "Already collected" is checked against everything collected so far in the whole run, not just the current URL. Once a later search or agency URL has returned at least one new listing, a following page of that URL made up only of listings an earlier URL already returned is read as the end of its results, and its deeper pages are silently skipped with no error. Example: you run a London search and then a Westminster search in one run; page 1 of Westminster has a few new listings, but every listing on page 2 was already returned by London, so the actor never reads page 3 of Westminster, even if it holds listings London never showed. The first URL in a run is never affected, and a later URL whose opening pages are all duplicates keeps going. The same rule applies to a Resume run: if new listings have been added near the top of the results since the interrupted run, the pages that follow them can consist entirely of already-saved listings, and the walk stops there before reaching the listings it was meant to add. If your URLs overlap and you need every listing, run each one as its own run (or its own scheduled task); for Resume, resume soon after the interruption.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted full-catalogue pull in a brand-new run: paste a previous run ID or dataset ID, and this run skips every listing id already saved there, appending only new listings. A checkpoint is also saved automatically as the run progresses, so an Apify platform migration or a Resurrect of a failed run picks back up in the same run without re-saving already-collected listings. No input is needed for that part; it is automatic.
  • Incremental mode (incrementalMode) is a different workflow: it re-runs the same startUrls and filters on a schedule (for example daily) and tells you only what changed, using state the actor keeps for you. The first run for a given search returns every listing as NEW. Later runs return only NEW, UPDATED (with changedFields), and REAPPEARED listings by default. Turn on emitUnchanged to also get UNCHANGED rows, or emitExpired to also get EXPIRED rows for listings that disappeared. EXPIRED detection only fires once a run has fully scanned every tracked URL; it is skipped on a resumeFromRunId run, a run capped by Max listings, a run where any URL stopped at Max pages per URL, a URL with more results than the roughly 2000 the site lets you retrieve, or a run where a page or connection was rejected mid-scan, since none of those prove a listing is actually gone. A listing marked EXPIRED that shows up again later is returned as REAPPEARED; without emitExpired, listings are never marked gone, so REAPPEARED does not occur.
  • Known limitation: false EXPIRED rows with overlapping URLs. A URL that stops early because of the overlap rule above (a page holding only listings an earlier URL already returned) still counts as having reached the end of its results. So with emitExpired on, listings on that URL's skipped deeper pages can be marked EXPIRED (and billed) while they are still live. Example: you track a London search and a Westminster search together, and a flat appears only on page 3 of Westminster. On a later run, page 2 of Westminster holds only listings London already returned, the walk stops there, and that flat comes back as EXPIRED although nothing on Properstar changed; it returns as REAPPEARED the next time a run reaches it. If you rely on EXPIRED, track each area or filter set in its own run (each gets its own saved state automatically), and treat an EXPIRED row as "not seen this run" rather than proof of delisting.
  • Incremental mode and Resume can be combined only to seed a brand-new baseline from an earlier dataset. If saved incremental state already exists for the same search, a run with both set fails straight away with a message; remove resumeFromRunId or set a different stateKey.
  • State is namespaced automatically per distinct startUrls + filter + enrichDetail combination, so two different searches never mix baselines. Set stateKey to name a campaign explicitly, or to share state deliberately across a different configuration.

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.

What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

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

ParameterTypeDefaultDescription
startUrlsarrayrequiredProperstar search, listing, or agency/agent URLs from any country domain. Multiple URLs are processed in order.
transactionTypestringanyRefine search-page URLs to buy or rent. any keeps the URL's own setting.
propertyTypesarray[]Restrict to apartment, house, land, commercial, office, parking, building, or room. Leave empty to use the URL's own types.
minPriceinteger(none)Minimum price in the listing's currency.
maxPriceinteger(none)Maximum price in the listing's currency.
minBedroomsinteger(none)Minimum number of bedrooms.
maxBedroomsinteger(none)Maximum number of bedrooms.
luxuryOnlybooleanfalseReturn only listings flagged as luxury.
enrichDetailbooleanfalseFetch each listing's detail page for amenities, AI-extracted view types, construction year, and floor. Adds a per-listing surcharge and is slower. Listing-page URLs always include full detail regardless of this setting.
maxItemsinteger20Maximum listings to return across all URLs. 0 = unlimited.
maxPagesPerUrlinteger0Maximum result pages to walk per search/agency URL (25 listings per page). 0 walks every page until the site's own end of results, capped at roughly 2000 retrievable listings per URL.
maxResidentialMbinteger0Soft, estimated cap on residential-exit browser traffic (connection setup, plus per-listing detail fetches when enrichDetail is on). Once reached, detail fetches stop for the rest of the run; list pagination is unaffected. 0 = no cap.
proxyobjectResidentialConnection settings. The one-time setup needs a residential exit (the default); pick a country to pin the exit region, or leave it unset to rotate.
resumeFromRunIdstring(empty)A previous run ID or dataset ID to continue a full-catalogue walk across separate runs. Listings already collected there (matched by id) are skipped, so this run only saves the new ones.
incrementalModebooleanfalseTurn on for recurring monitoring of the same startUrls/filters. Only NEW, UPDATED, and REAPPEARED listings are returned after the first run.
stateKeystring(empty)Name an incremental-mode monitoring campaign, or share state deliberately across differently-configured runs. Auto-derived from startUrls + filters + enrichDetail when empty.
emitUnchangedbooleanfalseIncremental mode only. Also return (and bill) listings with no change, marked UNCHANGED.
emitExpiredbooleanfalseIncremental mode only. Also return (and bill) listings no longer found, marked EXPIRED, only when the run fully scanned every tracked URL. See "Resume and recurring updates" for the exceptions and a known limitation with overlapping URLs.
mcpConnectorsarray(none)Optional: send a summary of each record to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which records are created.
maxNotifyListingsinteger50Cap 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 listing.

{
"id": "100000001",
"url": "https://www.properstar.co.uk/listing/100000001",
"class": "PropertyListing",
"transactionType": "Sell",
"type": "Apartment",
"subType": "Penthouse",
"title": "Sample listing title",
"description": "Full description text appears here.",
"titleByLanguage": { "en": "Sample listing title" },
"descriptionByLanguage": { "en": "Full description text appears here." },
"price": 1000000,
"currency": "GBP",
"livingAreaSqm": 120,
"livingAreaSqft": 1291,
"rooms": 4,
"bedrooms": 3,
"bathrooms": 2,
"floor": "3",
"constructionYear": 2020,
"address": "Sample Street 1",
"city": "London",
"postcode": "SW1",
"countryISO": "GB",
"latitude": 51.5,
"longitude": -0.12,
"pictures": ["https://images.example.com/0001.jpg"],
"picturesCount": 12,
"floorPlans": ["https://images.example.com/plan-0001.jpg"],
"amenities": ["Balcony", "Parking"],
"views": ["City"],
"agencyId": 1000000,
"agencyName": "Sample Agency",
"agencySlug": "sample-agency",
"agencyStatistics": { "numberOfListings": 0 },
"publicationDate": "2026-01-01T00:00:00Z"
}

Plan Requirement

The default Connection setting already selects a residential exit, which the one-time setup needs to open Properstar; a different setting may return no listings. Once setup is complete, the bulk of the data pull automatically switches to a lower-cost connection pool. Pick a proxy country under Connection to pin the exit region, or leave it unset to rotate automatically.

FAQ

How much does it cost?

You pay per listing returned, plus a small per-listing surcharge only when Fetch full detail is switched on. The Pricing tab shows the current rates. Use Max listings and Max pages per URL to cap the cost of any run.

This actor collects only publicly available listing data. You are responsible for how you use it: follow Properstar's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Photos, floor plans, and agency contact details may be subject to third-party rights.

Can I monitor the same search for new or changed listings?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated, and reappeared listings, and unchanged ones are not billed unless you turn on Emit unchanged.

Why did my run return fewer listings than I expected?

Check Max listings and Max pages per URL, which both cap a run by design. A single search or agency URL is also capped at roughly the site's own 2000-listing retrievable ceiling. If you pass several overlapping URLs in one run, a later URL can also stop early once a whole page of it repeats listings an earlier URL already returned (see "Known limitation: overlapping URLs end early" under Caps and cost controls), and with Emit expired on, listings it skipped this way can come back as EXPIRED even though they are still live. Run overlapping areas or filters as separate runs to avoid both.

Why did my run fail instead of returning an empty dataset?

If every request to Properstar was rejected, the run fails with a clear message so "no listings match" is never confused with "the connection could not be established". Run it again in a few minutes. If only some of your URLs failed, you still get what was found from the others.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear, or Airtable.

🔗 Want more real estate data?

Pair this actor with these related scrapers from the same team:

🏠 Property24
From $1/1K. Extract structured property listings from Property24, South Africa’s largest...
🏠 Immobiliare.it Scraper
From $1/1K. Extract property listings from Immobiliare.it with clean structured data...
🏠 Immowelt.de Scraper
Scrape detailed property listings from Immowelt.de into clean structured data. Extract...
🏠 Domain.com.au
Extract enriched Domain.com.au property listings across buy, rent, and sold, with...
🏠 Fotocasa.es
From $1/1K. Scrape Spain property listings from fotocasa.es. Get price, surface, rooms...
🏠 NewHomeSource
Scrape new homes, floor plans, builders and communities from NewHomeSource.com. Search by...

👉 Browse all abotapi scrapers

💬 Support & custom scrapers

  • 🐞 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 abotapi@proton.me or message Telegram @abotapi.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.