# Equipment Auction Comps — Heavy Machinery Price Monitor (`alaudinburki/equipment-auction-comps`) Actor

Track used construction and agricultural equipment listings across auctions and marketplaces in one schema, with first_seen so you can see what is newly listed and what has moved.

- **URL**: https://apify.com/alaudinburki/equipment-auction-comps.md
- **Developed by:** [alaudin burki](https://apify.com/alaudinburki) (community)
- **Categories:** Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Equipment Auction & Used-Listing Comps — Heavy Machinery Price Monitor

Track used construction and agricultural equipment across marketplaces in **one schema**, and get the
comparison a dealer actually wants: for each make and model, **how many are listed right now and at
what asking prices** — plus `firstSeenAt`, so you can see what is newly listed and what has moved.

### What you get

**Rows — one per machine**

| Field | Description |
|---|---|
| `id` | Stable id, `mascus:hi6l5rbp` |
| `make` | Manufacturer, resolved from a known-makes list — `john deere`, not `john` |
| `model` | Model with the machine-type words stripped — `314e lcr` |
| `title` | Readable name, `cat 314e lcr` |
| `category` | The category it was found under, e.g. `crawler-excavators` |
| `typeWords` | The machine-type words found in the slug, e.g. `tracked excavator` |
| `price` | Asking price **if the index exposes one**, else `null` — never guessed |
| `url` | Direct link to the listing |
| `isNew` | `true` when `onlyNewSinceLastRun` is on and this id was not seen before |
| `firstSeenAt` | When this listing first appeared — carried across runs |
| `scrapedAt` | This run's timestamp |

**A second dataset, `comps`** — one row per make + model

| Field | Description |
|---|---|
| `machine` | `cat 314e lcr` |
| `listings` | How many are listed right now |
| `priceLow` / `priceHigh` | The asking-price range, when prices are exposed |
| `pricesSeen` | How many listings actually carried a price |
| `categories`, `sources` | Where they came from |
| `sampleUrl` | One listing to look at |

### Sample output

```json
{
  "id": "mascus:hi6l5rbp",
  "make": "cat",
  "model": "314e lcr",
  "title": "cat 314e lcr",
  "category": "crawler-excavators",
  "typeWords": "tracked excavator",
  "price": null,
  "url": "https://www.mascus.com/construction/crawler-excavators/cat-314e-lcr-tracked-excavator/hi6l5rbp.html",
  "isNew": null,
  "firstSeenAt": "2026-10-17T18:04:11.201Z",
  "scrapedAt": "2026-10-17T18:04:11.201Z"
}
```

```json
{ "machine": "cat 930h", "make": "cat", "model": "930h", "listings": 3,
  "categories": "wheel-loaders", "sources": "mascus", "pricesSeen": 0 }
```

### Default input

Runs with zero editing: three categories, Mascus, up to 1,000 listings, comps on. First run returns
everything; turn on **Only new since last run** after that to get only what changed.

### Limitations — stated plainly, because a surprise costs you a review

- **One source today: Mascus.** Its robots.txt is permissive and its listing URLs are a stable
  contract. **It is the only source that answered.**
- **Ritchie Bros, MachineryTrader, AuctionTime and TractorHouse all return HTTP 403** to a plain
  request. They are not scraped here — faking them would give you silently empty rows. Covering them
  needs the platform's proxy or a browser session.
- **Asking prices only, and only where the index exposes them.** Mascus's category pages do **not**
  publish a price, so `price` is usually `null`. Sold prices at auction live on individual lot pages
  and are **not** collected. Do not read `priceLow` as a market value when `pricesSeen` is 0.
- **Make and model are parsed from the URL slug** against a known-makes list. An unfamiliar brand is
  split at the first word, so a new manufacturer can appear as a two-word make.
- **This is not an appraisal tool.** It reports what is listed and what is asked — never what a
  machine is worth.

### Pricing

Pay per result — you are charged for the rows you receive, not for the run. Leave `Max listings` low
while you are testing.

### Notes on how it behaves

- Every URL comes from the listing slug, never from generated CSS class names — Mascus's classes are
  hashed and change on deploy, and a parser built on them breaks **silently**.
- Zero listings across every category is treated as a **failure**, not an empty result, so a layout
  change surfaces as an error instead of a blank CSV.
- `comps` is a **separate named dataset**, not extra rows in the main one.

# Actor input Schema

## `categories` (type: `array`):

Which equipment categories to read. These are URL segments on Mascus, e.g. crawler-excavators, wheeled-excavators, wheel-loaders, skid-steer-loaders, telehandlers, mini-excavators, backhoe-loaders, dozers, dumpers. Equipment TYPES are the point: 'skid steer', 'telehandler', 'wheel loader' and 'forklift' return zero competing Actors.

## `source` (type: `string`):

Which marketplace to read. Only Mascus is currently wired up — Ritchie Bros, MachineryTrader, AuctionTime and TractorHouse answer a plain request with HTTP 403 and are listed as unbuilt in the README rather than faked.

## `includeComps` (type: `boolean`):

In addition to the raw listings, write a second dataset grouped by make and model, with how many are listed and the asking-price range.

## `onlyNewSinceLastRun` (type: `boolean`):

Return only listings not seen in a previous run, and set isNew. Requires saved run history — leave off on the first run.

## `snapshotKey` (type: `string`):

Where the seen-listings baseline is stored. Change it to keep separate histories for separate searches.

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

Stop after this many listings.

## Actor input object example

```json
{
  "categories": [
    "skid-steer-loaders",
    "telehandlers",
    "wheel-loaders"
  ],
  "source": "mascus",
  "includeComps": true,
  "onlyNewSinceLastRun": false,
  "snapshotKey": "SEEN_EQUIPMENT",
  "maxItems": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

One row per item, with the 10 fields listed under Views.

# 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 = {
    "categories": [
        "skid-steer-loaders",
        "telehandlers",
        "wheel-loaders"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("alaudinburki/equipment-auction-comps").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 = { "categories": [
        "skid-steer-loaders",
        "telehandlers",
        "wheel-loaders",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("alaudinburki/equipment-auction-comps").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categories": [
    "skid-steer-loaders",
    "telehandlers",
    "wheel-loaders"
  ]
}' |
apify call alaudinburki/equipment-auction-comps --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,alaudinburki/equipment-auction-comps"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/noIAzUp6SJG7laceI/builds/dJaJJQk9eS3hV6fVO/openapi.json
