Historical Property Price Changes & Listings
Pricing
from $0.10 / 1,000 results
Historical Property Price Changes & Listings
Get verified before-and-after property listing prices from maintained historical observations. Five results by default, with country, date, source and listing filters; optional raw archive and AI analysis.
Pricing
from $0.10 / 1,000 results
Rating
0.0
(0)
Developer
Inus Grobler
Maintained by CommunityActor stats
1
Bookmarked
9
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
Historical Property Listings & Price Changes
Export stored listing history and recorded asking-price changes for market research, price tracking and dated comparisons. Coverage and available fields depend on the collected sources. An asking price is not a completed sale price.
Quick start
Run the suggested input in Apify Console for up to five price-change records from the last 90 days. Leave countries blank for the small starter sample, or select countries to narrow the export. Download the default dataset as JSON, CSV or Excel.
{"view": "price_changes","countries": ["ZA"],"lookbackDays": 90,"limit": 5}
Choose an export
| View | Use |
|---|---|
price_changes | Compare recorded before-and-after asking prices. This is the default view. |
observations | Export dated observations; the same listing may appear at several observation times. |
archived_listings | Explore stored listing history within the selected period. Availability depends on the collected history. |
current | Legacy current-inventory export. For new current-data workflows, use the dedicated current listings Actor. |
lookbackDays defaults to 90 and supports up to 366 days. observedFrom is an optional inclusive YYYY-MM-DD date that overrides the lookback. observedTo is an optional inclusive YYYY-MM-DD date and defaults to today. limit defaults to 5 and supports up to 1000 delivered rows.
Filters and coverage
Use countries, websites, minPrice and maxPrice, plus markets, areaQuery, minBedrooms and maxBedrooms. Price filters apply in each listing's own currency; do not combine currencies as if they were equivalent. Zero disables the numeric price filters. Property records can cover for-sale and to-rent; the default market is for-sale.
The available records depend on source coverage and the selected dates. An empty search can succeed with no dataset rows. Set requireResults only when an empty export should count as a failed health check.
estimateOnly: true returns a bounded lower-bound preview without delivering paid rows. It does not establish an exact database count.
Read results
Price-change records expose previous_price, current_price, change_amount, change_percent, direction, observed_at, country_code, currency_code and url, with available listing details. Observation and inventory views expose their corresponding stored fields. Missing optional metadata reflects source coverage; do not treat it as a measured zero.
For another page, read next_continuation_token from the run's OUTPUT key-value record and pass it as continuationToken with the same filters and date range. Keep output record identity and observation dates when comparing exports across runs.
Optional aiEnrichment is off by default. aiMaxItems defaults to 5 and supports up to 20 items. A successful enriched item incurs the separately listed AI event; the analysis is not a valuation or inspection.
Run with Python
Install apify-client, supply your Apify token and use the Actor's API name. This example supports typed Run models and older dictionary responses.
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("thescrapelab/the-ultimate-property-scraper").call(run_input={"view": "price_changes", "countries": ["ZA"], "markets": ["for-sale"], "limit": 5})if run is None:raise RuntimeError("Actor call returned no run or storage metadata")for row in client.dataset((run['defaultDatasetId'] if isinstance(run, dict) else run.default_dataset_id)).iterate_items():print(row["city"], row["previous_price"], row["current_price"], row["url"])
Use the default dataset for rows and the run's key-value store for OUTPUT and ESTIMATE. Key-value get_record() responses retain dictionary access through ["value"].