# EasyAuto123 Scraper – Vehicle Listings, VINs & Dealer Data (`abotapi/easyauto123-cars-scraper`) Actor

Scrape EasyAuto123 vehicle listings into clean structured data. Extract prices, VINs, odometer readings, make, model, year, trim, specs, images, dealer names, locations, contact details, listing URLs, and optional extra fields for market research, lead generation, and inventory tracking.

- **URL**: https://apify.com/abotapi/easyauto123-cars-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** Lead generation, Travel, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 dataset items

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## EasyAuto123 Cars Scraper

Extract EasyAuto123 used vehicle listings into a clean dataset for pricing analysis, stock tracking, lead routing, and vehicle comparison workflows.

### What You Get

Each saved vehicle can include:

- Listing ID, EasyAuto123 URL, title, make, model, variant, release year, VIN
- Displayed price, price type, odometer, fuel, transmission, drive type, engine capacity, colour, body/type labels
- Store location, region, state, store name, public phone, public email, address, and rating when available
- Primary image, full image list, car category, banner, stock status, update timestamp
- Price component rows, full store object, and full source vehicle object for advanced exports

### Input Modes

#### Search Filters

Use `mode: search` to build a vehicle search from filters. Supported filters include:

- Keywords, makes, models, variants
- Dealer locations
- Vehicle types, fuel types, transmissions, colours
- Lifestyle labels, vehicle sizes, EasyAuto123 car types
- Year, price, and odometer ranges
- Sort order

#### URLs

Use `mode: url` for one or more EasyAuto123 URLs. Supported examples:

- `https://easyauto123.com.au/buy/used-cars?page=1&limit=20`
- `https://easyauto123.com.au/buy/used-cars?page=2&limit=20&fuel-type=Hybrid`
- `https://easyauto123.com.au/buy/used-cars/details/2014/TOYOTA/CAMRY/Hybrid-HL/SA/Adelaide/Mile-End-South/Automatic/White/Sedan-Hybrid/6T1BD3FK40X141250`

### Limits

`maxItems` is the main cap. The actor stops once that many vehicles have been saved or no more matching vehicles are available.

`maxPages` is optional. Leave it as `0` to avoid a page cap. Set it only when you want to limit how far a search can go.

### Detail Fields

Keep `fetchDetails` enabled when you want the richest vehicle records. Turn it off for faster list-level runs when you only need listing data.

### Resume & Recurring Updates

Two distinct tools, both optional:

- **`resumeFromRunId`** continues ONE specific interrupted run. Paste a previous run ID or dataset ID and this run will skip vehicles it already saved there, instead of re-scraping (and re-billing) them.
- **`incrementalMode`** is for scheduling the SAME search again and again (daily, hourly, ...) and only getting what changed. Turn it on and the actor remembers the previous run of this exact search itself — no run/dataset id needed. The first run returns every matching vehicle as `NEW`. Later runs return only `NEW`, `UPDATED`, and `REAPPEARED` vehicles by default.
  - Each output row gains `changeType` (`NEW` / `UPDATED` / `UNCHANGED` / `REAPPEARED` / `EXPIRED`), `changedFields`, `firstSeenAt`, and `lastSeenAt`.
  - **`emitUnchanged`** (off by default) also returns vehicles with no change, marked `UNCHANGED` — this returns and bills extra rows.
  - **`emitExpired`** (off by default) also returns vehicles that were tracked before but are no longer found, marked `EXPIRED`. This only happens once a run has scanned the full tracked search — a run capped by `maxItems`, or one using `resumeFromRunId`, skips expiry detection for that run rather than risk marking a live vehicle as gone.
  - State is tracked separately per distinct combination of filters (mode, keywords, makes, models, variants, locations, vehicle type, fuel type, transmission, colour, lifestyle, vehicle size, car type, year/price/odometer range, sort, and whether detail fields are fetched). `maxItems`, `maxPages`, and delivery-only settings (proxy, MCP connectors, notifications) never affect which state a run uses — raising the item cap tomorrow does not start a new baseline.
  - **`stateKey`** optionally names the monitoring campaign, letting you deliberately share state across otherwise different filter setups (or just keep a stable, memorable key). Leave it empty to let the actor derive one automatically from the filters above.
  - A field-level change is only reported when the underlying value genuinely changes between two successfully-observed values. A vehicle's own last-updated timestamp, and its (rotating, signed) image links, do not by themselves count as a change — see Notes below.
  - `incrementalMode` and `resumeFromRunId` can be combined only to bootstrap a brand-new monitoring campaign from an existing pull (no incremental state saved yet for that state key); once state exists, remove `resumeFromRunId` or pick a different `stateKey`.

### 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, and 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** (the vehicle name) and its key fields flattened to plain text. Nested objects are collapsed to their main value and long lists are trimmed. 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.

### Proxy

The actor uses Apify Proxy by default. Keep the prefilled proxy configuration for normal runs, or provide your own proxy settings if your workflow requires it.

### Example Input

```json
{
  "mode": "search",
  "makes": ["Toyota"],
  "models": ["CAMRY"],
  "fuelTypes": ["Hybrid"],
  "maxItems": 20,
  "maxPages": 0,
  "fetchDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "mcpConnectors": []
}
```

### Output Example

```json
{
  "listingId": "f5504a4d-5263-4cc0-fc0a-08debf9c24ec",
  "url": "https://easyauto123.com.au/buy/used-cars/details/2011/SUBARU/IMPREZA/2.0i-L/QLD/Brisbane/Hendra/Automatic/White/Sedan/JF1GJ7KC5CG003176",
  "title": "2011 Subaru Impreza 2.0i-L",
  "make": "SUBARU",
  "model": "IMPREZA",
  "variant": "2.0i-L",
  "year": 2011,
  "price": 10990,
  "odometer": 168196,
  "vin": "JF1GJ7KC5CG003176",
  "fuelType": "Petrol",
  "transmission": "Automatic",
  "location": "Hendra",
  "state": "QLD",
  "storeName": "easyauto123 Hendra"
}
```

### Notes

The dataset can include additional fields beyond the table view. Export JSON if you need nested store details, price components, image metadata, or the full vehicle object.

Two fields are excluded from incremental mode's change detection but are still returned on every row: the vehicle's `updatedAt` timestamp (the site's own last-modified stamp; genuine content changes are already caught by diffing price, status, odometer, and the other fields directly), and the query parameters on image links (`imageUrls`, `primaryImage`, and the orbit/sphere image lists), which are per-fetch signed download tokens that change on every page load even for the exact same photo.

# Actor input Schema

## `mode` (type: `string`):

Choose whether to build a listing search from filters or start from one or more EasyAuto123 URLs.

## `urls` (type: `array`):

Use this in URLs mode. Add listing search URLs or individual vehicle URLs.

## `keywords` (type: `array`):

Optional make and model text, such as Toyota CAMRY or Ford RANGER.

## `makes` (type: `array`):

Vehicle makes, for example Toyota, Mazda, Ford, BYD, Kia, Hyundai, Mitsubishi, Subaru, Volkswagen, Nissan, Audi.

## `models` (type: `array`):

Vehicle models to include. Use values as shown on EasyAuto123, for example CAMRY, RANGER, HILUX, I30, CX-5.

## `variants` (type: `array`):

Optional vehicle variant names.

## `locations` (type: `array`):

Dealer locations, such as Hendra QLD, Brooklyn VIC, Joondalup WA, Mile End South SA, Liverpool NSW, Newcastle NSW.

## `vehicleTypes` (type: `array`):

Body and type labels, for example SUV, Wagon, Hatchback, Sedan, UTE, 7+ Seater, Hybrid, Electric.

## `fuelTypes` (type: `array`):

Fuel labels to include.

## `transmissions` (type: `array`):

Transmission labels to include.

## `colours` (type: `array`):

Vehicle colours, such as White, Grey, Blue, Black, Silver, Red.

## `lifestyles` (type: `array`):

Lifestyle labels, such as Family, City, Tradie, Outdoor Adventure, Eco Friendly.

## `vehicleSizes` (type: `array`):

Size labels to include.

## `carTypes` (type: `array`):

EasyAuto123 vehicle categories.

## `minYear` (type: `integer`):

Only include vehicles from this release year or newer.

## `maxYear` (type: `integer`):

Only include vehicles from this release year or older.

## `minPrice` (type: `integer`):

Only include vehicles at or above this displayed price.

## `maxPrice` (type: `integer`):

Only include vehicles at or below this displayed price.

## `minOdometer` (type: `integer`):

Only include vehicles at or above this odometer reading.

## `maxOdometer` (type: `integer`):

Only include vehicles at or below this odometer reading.

## `sort` (type: `string`):

Result ordering.

## `fetchDetails` (type: `boolean`):

Adds fields that are only available on individual vehicle pages.

## `maxItems` (type: `integer`):

Maximum number of dataset items to save. The run stops when this cap is reached or no more matching vehicles are available.

## `maxPages` (type: `integer`):

Optional page cap. Leave as 0 for no page cap; max items remains the main limit.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large crawl of vehicle listings without returning or charging for vehicles already collected there. Use this after an interrupted run, or when continuing a listing pull in another run. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns all matching vehicles as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED vehicles. Turn on "Emit unchanged" or "Emit expired" only when you also want those vehicles returned (and billed). State is kept separately for each filter combination and detail-mode setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the filters and detail setting — different searches then never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return vehicles that have not changed since the last run, marked UNCHANGED. This returns — and bills — extra rows you already have, so leave it off unless you specifically want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return vehicles that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search — not when Max items capped it or when Resume was used. This returns — and bills — extra synthetic rows, so leave it off unless you need expiry tracking.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON. The complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## `proxyConfiguration` (type: `object`):

Apify Proxy is used by default. Keep the prefilled setting unless you need a custom proxy.

## Actor input object example

```json
{
  "mode": "search",
  "urls": [
    "https://easyauto123.com.au/buy/used-cars?page=1&limit=20"
  ],
  "sort": "price-reduced",
  "fetchDetails": true,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "mode": "search",
    "urls": [
        "https://easyauto123.com.au/buy/used-cars?page=1&limit=20"
    ],
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/easyauto123-cars-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 = {
    "mode": "search",
    "urls": ["https://easyauto123.com.au/buy/used-cars?page=1&limit=20"],
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/easyauto123-cars-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 '{
  "mode": "search",
  "urls": [
    "https://easyauto123.com.au/buy/used-cars?page=1&limit=20"
  ],
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/easyauto123-cars-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=abotapi/easyauto123-cars-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/2aBfkWav4qW8pFb9S/builds/WgFx8JbdAu5QxShTj/openapi.json
