# TruckWorld Scraper — Used Trucks Australia (`crawloop/truckworld-scraper`) Actor

Scrape TruckWorld used trucks in Australia: prime movers, tippers, and trailers. Extract AUD prices with GST split, odometer, make/model/year, dealer phones, and images.

- **URL**: https://apify.com/crawloop/truckworld-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.49 / 1,000 scraped truckworld listings

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

## TruckWorld Scraper — Used Trucks Australia

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by TruckWorld, Sandhills Pacific, or Sandhills Global or its affiliates. Data is read from publicly accessible pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

> **Contact-data controls:** Phone/WhatsApp/fax fields are omitted from the dataset by default. Enable `includePhones` only for numbers already published on public pages and only when you have a lawful basis. Any contact-field examples below assume that explicit opt-in; otherwise those fields are absent.

> **Crawloop Commercial Vehicles Suite** — Australian TruckWorld asking prices with GST split, odometer, dealer phones, and inventory change alerts. Pair with European Truck1 for AU vs EU truck comps.

| Truck1 (EU trucks) | TruckPaper (US) | MachineryTrader | Machines4U | TruckWorld |
| :--- | :--- | :--- | :--- | :--- |
| [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper) | [TruckPaper Scraper](https://apify.com/crawloop/truckpaper-scraper) | [MachineryTrader Scraper](https://apify.com/crawloop/machinerytrader-scraper) | [Machines4U Scraper](https://apify.com/crawloop/machines4u-scraper) | TruckWorld Scraper ◄── you are here |

| IronPlanet | Ritchie Bros | Machineryline | Surplex | Troostwijk |
| :--- | :--- | :--- | :--- | :--- |
| [IronPlanet Scraper](https://apify.com/crawloop/ironplanet-scraper) | [Ritchie Bros Auction Scraper](https://apify.com/crawloop/rbauction-scraper) | [Machineryline Scraper](https://apify.com/crawloop/machineryline-scraper) | [Surplex Scraper](https://apify.com/crawloop/surplex-scraper) | [Troostwijk Scraper](https://apify.com/crawloop/troostwijk-scraper) |

**TruckWorld scraper** for Australia’s commercial truck marketplace — prime movers, tippers, tray trucks, pantechs, refrigerated units, utes, trailers, buses, and components. Extract **AUD asking prices with GST split** (ex GST / inc GST), odometer (km), year, make, model, horsepower, dealer phones, location, and images. Run category or keyword crawls (Kenworth, Isuzu, Hino), dealer inventory (`AccountCRMID`), or direct listing URLs — a practical **TruckWorld API alternative** for Python, Node.js, cURL, and MCP on Apify.

Built for **truck dealers**, **fleet buyers**, **finance desks**, and **market-intel teams** covering Australia. Choose `listings` for fast card-level catalogs (phones and GST already on the tile) or `details` for Vehicle JSON-LD street-address enrichment. Enable **`monitorMode`** on an Apify Schedule to track **new inventory** and **price changes**.

### When to use this Actor

Use the **TruckWorld Scraper** when you need:

- **Australian commercial truck inventory** — prime movers, tippers, tray, pantech, refrigerated, utes, trailers
- **GST-aware AUD prices** — card ask plus inc-GST when PriceTaxModel publishes both
- **Odometer, year, make/model**, horsepower, and right-hand-drive specs
- **Dealer phones on listing cards** — outreach without visiting every PDP
- **Dealer inventory watch** via `AccountCRMID`
- **Discovery** — category shortcuts, keyword search, or pasted start URLs

Ideal for traders comparing Australian asking prices against EU Truck1 comps.

#### When not to use

- You need **European commercial vehicles** → [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper)
- You need **EU heavy-equipment dealer stock** → [Machineryline Scraper](https://apify.com/crawloop/machineryline-scraper)
- You need **industrial auction lots** → [Surplex Scraper](https://apify.com/crawloop/surplex-scraper) or [Troostwijk Scraper](https://apify.com/crawloop/troostwijk-scraper)
- You need authenticated Auction Results **sold** hammer prices (often login-gated)

### Data pipeline

```
Input                              Mode                         Output
─────────────────────────         ────────────────────         ──────────────────────────

  Category / search / dealer ──►   listings (fast cards)  ──►  AUD price, GST, km, phone
  Keyword / AccountCRMID     ──►   details  (full PDP)   ──►  street address, ld+json
  Direct listing URLs        ──►                           ──►  make, model, year, HP

  Join by make + model + year ──►  comps with Truck1 / Machineryline
```

### Key Features

- **Two extraction modes** — `listings` for SSR cards; `details` for Vehicle ld+json address enrichment
- **GST-aware AUD prices** — `price`, `priceIncGst`, `gstFlag` (`ex_gst` / `inc_gst` / `na`)
- **Category shortcuts** — prime movers, tippers, trailers, utes, and more
- **Dealer phones on cards** — no details mode required for most retail rows
- **Monitor mode** — seed fingerprints, then emit only `new` / `price_change`; optional Telegram alerts
- **Retail-only filter** — skip AuctionTime cross-lists and auction-result rows
- **Cloudflare-ready** — curl_cffi Chrome TLS; Apify Residential (AU) on platform runs
- **Export-ready JSON** — Apify dataset for CSV / Excel / API / MCP

### Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `startUrls` | Array | Prime movers category | Search, category, dealer inventory, or listing URLs. |
| `searchQuery` | String | — | Keywords for a built search URL (e.g. Kenworth). |
| `categories` | Array | `[]` | Built-in body-type shortcuts (`prime-movers`, `tipper-trucks`, …). |
| `listingType` | String | `"For Retail"` | `"For Retail"`, `"For Rent"`, or `"Auction Results"`. |
| `manufacturer` | String | — | e.g. `KENWORTH`, `ISUZU`, `HINO`. |
| `category` | String | — | Raw Sandhills category id (`15158` prime movers). |
| `accountCrmId` | String | — | Dealer `AccountCRMID` inventory watch. |
| `state` | String | — | e.g. `Victoria`, `NSW`, `Queensland`. |
| `runMode` | String | `"listings"` | `"listings"` or `"details"`. |
| `pricedOnly` | Boolean | `false` | Keep only rows with a published price. |
| `retailOnly` | Boolean | `true` | Skip auction-result / AuctionTime cross-lists. |
| `maxItems` | Integer | `100` | Cap on emitted records. |
| `maxPagesPerUrl` | Integer | `10` | Pagination depth (~28 listings/page). |
| `concurrencyLimit` | Integer | `5` | Parallel PDP fetches in details mode. |
| `monitorMode` | Boolean | `false` | Delta tracking via named KV store. |
| `monitorStoreName` | String | `truckworld-monitor-state` | Distinct name per watch target. |
| `proxyConfiguration` | Object | Residential AU | Apify Residential AU required on platform runs. |

#### Example input

```json
{
  "startUrls": [
    { "url": "https://www.truckworld.com.au/listings/for-sale/prime-movers/15158" }
  ],
  "runMode": "listings",
  "maxItems": 50,
  "maxPagesPerUrl": 2,
  "retailOnly": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "AU"
  }
}
```

### Output

| Field | Type | Description |
| :--- | :--- | :--- |
| `id` | String | TruckWorld listing id |
| `title` | String | Listing title |
| `make` / `model` / `year` | — | Identity fields |
| `price` / `priceIncGst` / `currency` | — | AUD ask; GST split when published |
| `gstFlag` | String | `ex_gst`, `inc_gst`, or `na` |
| `mileage` | String | Odometer (typically km) |
| `horsepower` / `vin` | — | Specs when the card publishes them |
| `condition` | String | New / Used |
| `dealerName` / `dealerPhone` / `accountCrmId` | — | Seller surfaces (phone on the card) |
| `location` / `state` | — | Australian location |
| `images` | Array | Gallery URLs |
| `url` | String | Canonical listing URL |
| `changeType` | String | `new` / `price_change` in monitor mode |

#### Example output (listing card)

```json
{
  "id": "258974779",
  "url": "https://www.truckworld.com.au/listing/for-sale/258974779/2026-faw-j6p-prime-movers",
  "title": "2026 FAW J6P",
  "make": "FAW",
  "model": "J6P",
  "year": "2026",
  "condition": "New",
  "category": "Prime Movers",
  "price": 199000,
  "priceIncGst": 218900,
  "currency": "AUD",
  "gstFlag": "ex_gst",
  "mileage": "22 km",
  "horsepower": "540 HP",
  "dealerName": "FAW Trucks Australia",
  "dealerPhone": "+61380006667",
  "state": "Victoria",
  "location": "Deer Park, Victoria, Australia 3023"
}
```

### Use cases

- **AU truck price comps** for Kenworth / Volvo / Mack prime movers, Isuzu tippers, and tautliners
- **GST-aware valuation** — track ex-GST asks vs inc-GST display
- **Dealer prospecting** with phones already on listing cards
- **Fleet sourcing** by make, km, state, or `AccountCRMID`
- **Scheduled monitor** for new stock and price drops
- **Python / Node / MCP pipelines** that treat TruckWorld as a structured dataset

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/truckworld-scraper').call({
  startUrls: [{ url: 'https://www.truckworld.com.au/listings/for-sale/prime-movers/15158' }],
  runMode: 'listings',
  maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("crawloop/truckworld-scraper").call(
    run_input={
        "searchQuery": "kenworth",
        "runMode": "details",
        "maxItems": 20,
        "state": "Victoria",
    }
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("title"), item.get("price"), item.get("dealerPhone"))
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~truckworld-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"categories":["prime-movers"],"runMode":"listings","maxItems":15}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp).
Connect your Apify account, then call this Actor by its Store ID / name.

Example prompts:

- "Run TruckWorld Scraper for used Kenworth prime movers in Victoria and return the top 20 rows as JSON"
- "Scrape tipper trucks with TruckWorld Scraper and summarize make, km, and ex-GST price"
- "Chain TruckWorld Scraper then Truck1 Scraper to compare AU vs EU prime-mover comps"

### Suite next step

After Australian TruckWorld inventory, pull US trucks with [TruckPaper Scraper](https://apify.com/crawloop/truckpaper-scraper), European trucks with [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper), Australian machinery with [Machines4U Scraper](https://apify.com/crawloop/machines4u-scraper), or auction comps with [IronPlanet Scraper](https://apify.com/crawloop/ironplanet-scraper).

### FAQ

**Are prices always present?**\
Priced ads expose an AUD ask. Zero / Call-for-price rows leave `price` empty. Auction Results often show `PriceLabel: "Sold Price"` with a gated hammer — `retailOnly` skips those.

**How does GST work?**\
When both figures are published, `price` is the card ask and `priceIncGst` is GST-inclusive. If inc > ask, `gstFlag` is `ex_gst`.

**Listings vs details?**\
`listings` is enough for catalogs, comps, and outreach — cards already include AUD price, GST, km, and dealer phone. Use `details` when you need the PDP street address from Vehicle JSON-LD.

**Where do dealer phones come from?**\
Retail listing cards already include `RetailPhoneNumber`. Details mode adds street address from JSON-LD.

**Do I need a proxy?**\
On the Apify platform, yes — Cloudflare blocks datacenter IPs. Use Apify Residential with country `AU` and keep concurrency modest. Direct `curl_cffi` from some home/office IPs may work without a proxy.

**Why did I stop around 10k listings?**\
Unfiltered `/listings/search` caps at ~357 pages (28/page). Shard by `categories` or manufacturer to cover the full ~19.5k catalog.

**Can I watch one dealer?**\
Yes — pass `accountCrmId` from a listing card (or a search URL with `AccountCRMID=`). Pair with `monitorMode` on a schedule.

**How does monitor mode work?**\
The first run seeds a named Key-Value store (no dataset rows). Later scheduled runs emit only `new` and `price_change`. Use a distinct `monitorStoreName` per dealer or category. Optional Telegram alerts need a bot token and chat id.

**Do I need a login?**\
No. Public browse, search, and advert pages are in scope.

### Related Actors

- [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper) — European commercial trucks
- [TruckPaper Scraper](https://apify.com/crawloop/truckpaper-scraper) — US commercial trucks
- [MachineryTrader Scraper](https://apify.com/crawloop/machinerytrader-scraper) — US heavy equipment
- [TractorHouse Scraper](https://apify.com/crawloop/tractorhouse-scraper) — US and EU farm equipment
- [Machines4U Scraper](https://apify.com/crawloop/machines4u-scraper) — Australian used machinery
- [IronPlanet Scraper](https://apify.com/crawloop/ironplanet-scraper) — US weekly online equipment auctions
- [Machineryline Scraper](https://apify.com/crawloop/machineryline-scraper) — EU heavy equipment + dealers
- [Surplex Scraper](https://apify.com/crawloop/surplex-scraper) — industrial auction lots
- [Troostwijk Scraper](https://apify.com/crawloop/troostwijk-scraper) — European industrial auctions

# Actor input Schema

## `includePhones` (type: `boolean`):

Off by default. Include phone, mobile, WhatsApp, or fax fields already published on public pages only when you have a lawful basis.

## `startUrls` (type: `array`):

Search results, category SEO pages, dealer inventory URLs (AccountCRMID), or listing detail pages (e.g. /listings/for-sale/prime-movers/15158, /listing/for-sale/{id}/…).

## `searchQuery` (type: `string`):

Optional keyword search for a built /listings/search URL (e.g. Kenworth, Prime Mover, tautliner).

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

Built-in TruckWorld body-type roots when you do not paste URLs. Each shortcut becomes /listings/for-sale/{slug}/{id}.

## `listingType` (type: `string`):

Used when building a search URL from filters (or when startUrls is empty). Auction Results metadata is public; sold prices are often login-gated.

## `manufacturer` (type: `string`):

Filter by brand when building a search URL (e.g. KENWORTH, ISUZU, HINO, VOLVO, MACK, IVECO).

## `category` (type: `string`):

Sandhills category id if you prefer a raw id (e.g. 15158 prime movers, 15136 tippers, 881 trailers).

## `accountCrmId` (type: `string`):

Watch a single dealer inventory by AccountCRMID (from listing cards). Builds /listings/search?...\&AccountCRMID=...

## `state` (type: `string`):

Optional Australian state filter when building a search URL (e.g. Victoria, NSW, Queensland).

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

Optional sort key for built search URLs (9 = Recently Added, 2 = Price Low→High, 3 = Price High→Low, 5 = Year High→Low).

## `baseUrl` (type: `string`):

Site origin for built search URLs. Default TruckWorld Australia. Optional Asia hub: https://www.truckworld.asia (different inventory mix).

## `runMode` (type: `string`):

listings = fast card fields (AUD price, GST, odometer, dealer phone, images). details = also visit each PDP for Vehicle ld+json address enrichment.

## `pricedOnly` (type: `boolean`):

Skip Call-for-price / Auction / zero-price rows.

## `retailOnly` (type: `boolean`):

Skip AuctionTime / EquipmentFacts cross-lists and auction-result rows (recommended for asking-price comps).

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

Maximum dataset rows to emit (in monitor seed runs: max listings to fingerprint).

## `maxPagesPerUrl` (type: `integer`):

Maximum pagination pages per search / dealer inventory URL (28 listings per page). Unfiltered search caps around 357 pages (~10k) — shard by category for full coverage.

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

Apify Residential AU is required on platform runs — Cloudflare blocks datacenter IPs.

## `concurrencyLimit` (type: `integer`):

Parallel PDP fetches in details mode.

## `monitorMode` (type: `boolean`):

Delta tracking for category, search, or dealer inventory URLs. First run seeds a named Key-Value store (no dataset rows / alerts). Later runs output only new listings and price changes. Pair with an Apify Schedule.

## `monitorStoreName` (type: `string`):

Named Key-Value store for fingerprints across scheduled runs. Use a distinct name per watch target (dealer or category).

## `telegramToken` (type: `string`):

Bot token for real-time alerts on new listings and price changes (monitorMode only).

## `telegramChatId` (type: `string`):

Telegram user or group chat ID that receives monitor alerts.

## `resetMonitorState` (type: `boolean`):

Clear stored listing fingerprints before this run (forces a fresh seed run).

## Actor input object example

```json
{
  "includePhones": false,
  "startUrls": [
    {
      "url": "https://www.truckworld.com.au/listings/for-sale/prime-movers/15158"
    }
  ],
  "searchQuery": "KENWORTH",
  "categories": [],
  "listingType": "For Retail",
  "manufacturer": "KENWORTH",
  "category": "15158",
  "accountCrmId": "35091979",
  "state": "Victoria",
  "sort": "9",
  "baseUrl": "https://www.truckworld.com.au",
  "runMode": "listings",
  "pricedOnly": false,
  "retailOnly": true,
  "maxItems": 100,
  "maxPagesPerUrl": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AU"
  },
  "concurrencyLimit": 5,
  "monitorMode": false,
  "monitorStoreName": "truckworld-monitor-state",
  "resetMonitorState": false
}
```

# Actor output Schema

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

Default dataset items.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.truckworld.com.au/listings/for-sale/prime-movers/15158"
        }
    ],
    "baseUrl": "https://www.truckworld.com.au",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "AU"
    },
    "monitorStoreName": "truckworld-monitor-state"
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/truckworld-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 = {
    "startUrls": [{ "url": "https://www.truckworld.com.au/listings/for-sale/prime-movers/15158" }],
    "baseUrl": "https://www.truckworld.com.au",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "AU",
    },
    "monitorStoreName": "truckworld-monitor-state",
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/truckworld-scraper").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 '{
  "startUrls": [
    {
      "url": "https://www.truckworld.com.au/listings/for-sale/prime-movers/15158"
    }
  ],
  "baseUrl": "https://www.truckworld.com.au",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AU"
  },
  "monitorStoreName": "truckworld-monitor-state"
}' |
apify call crawloop/truckworld-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/truckworld-scraper"
        }
    }
}
```

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/whBj72gtuNSgrZzNc/builds/a3IqysoFXkNjgRQQD/openapi.json
