Historical Car Price Changes & Listings avatar

Historical Car Price Changes & Listings

Pricing

from $0.10 / 1,000 results

Go to Apify Store
Historical Car Price Changes & Listings

Historical Car Price Changes & Listings

Get verified before-and-after car 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

Inus Grobler

Maintained by Community

Actor stats

3

Bookmarked

54

Total users

3

Monthly active users

11 days ago

Last modified

Share

Historical Car 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

ViewUse
price_changesCompare recorded before-and-after asking prices. This is the default view.
observationsExport dated observations; the same listing may appear at several observation times.
archived_listingsExplore stored listing history within the selected period. Availability depends on the collected history.
currentLegacy 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 brandQuery, modelQuery, yearMin, yearMax, mileageMin and mileageMax. Price filters apply in each listing's own currency; do not combine currencies as if they were equivalent. Zero disables the numeric price filters. 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 ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("thescrapelab/ultimate-car-listings-scraper-100-sites").call(
run_input={"view": "price_changes", "countries": ["ZA"], "lookbackDays": 90, "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["brand"], row["model"], 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"].