# TruckPaper Scraper — Commercial Truck & Trailer Listings (`crawloop/truckpaper-scraper`) Actor

Scrape TruckPaper commercial trucks and trailers for dealers and fleet buyers: asking prices, make/model/year, mileage, VIN, horsepower, dealer phones, and images. Monitor new inventory and price changes. Listings or details mode.

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

## Pricing

from $2.15 / 1,000 scraped truckpaper listings

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

## TruckPaper Scraper — Commercial Truck & Trailer Listings

> **Crawloop Commercial Vehicles Suite** — US TruckPaper asking prices, mileage/VIN specs, dealer phones, and inventory change alerts. Pair with European Truck1 for cross-Atlantic truck comps.

| Truck1 (EU trucks) | TruckPaper (US trucks) | Machineryline (EU heavy) | Surplex | Troostwijk |
| :--- | :--- | :--- | :--- | :--- |
| [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper) | TruckPaper Scraper ◄── you are here | [Machineryline Scraper](https://apify.com/crawloop/machineryline-scraper) | [Surplex Scraper](https://apify.com/crawloop/surplex-scraper) | [Troostwijk Scraper](https://apify.com/crawloop/troostwijk-scraper) |

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by TruckPaper, Sandhills Global, or their brands. Data is read from publicly accessible pages only. You are responsible for complying with applicable law and site terms. No warranty on accuracy or availability.

### What this TruckPaper scraper does

This **TruckPaper scraper** extracts commercial truck and trailer for-sale listings into a clean Apify dataset: asking price, make, model, year, mileage, VIN, horsepower, dealer phone, location, and images. Built as a TruckPaper API alternative for dealers, fleet buyers, appraisers, lenders, and data teams who need Class 8 sleeper / day cab, dump truck, box truck, and semi-trailer comps in **Python**, **Node.js**, or **MCP** — export JSON / CSV / Excel without manual browsing.

Run `listings` for fast catalog pulls (retail cards already include dealer phone and specs) or `details` for PDP street-address enrichment via Vehicle JSON-LD. Enable **`monitorMode`** on an Apify Schedule to track **new inventory** and **price changes** per dealer or category. `retailOnly` (default on) skips AuctionTime / EquipmentFacts cross-lists that pollute asking-price feeds.

### When to use

- Dealer competitive intelligence — watch a rival `AccountCRMID` inventory daily
- Asking-price comps for sleeper trucks, day cabs, dump trucks, box trucks, and semi-trailers
- Fleet sourcing by manufacturer, model, mileage, VIN, or US state
- Outreach lists with published dealer phones (no details mode required for most retail cards)
- Join US truck asking prices with EU stock from [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper)

#### When not to use

- You need authenticated Auction Results **sold** hammer prices (often login-gated)
- You only need European commercial vehicles — start with [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper)
- You need US construction or farm boards — use Sandhills construction / farm workflows separately

### US ↔ EU commercial vehicles workflow

```
US truck asking prices              EU enrichment / auctions
──────────────────────              ───────────────────────

  TruckPaper Scraper ◄── you are here
       │ dealer phones, mileage, VIN, monitor deltas
       ▼
  Truck1 Scraper ─────────────────► EU trucks + trailers
  Machineryline Scraper ──────────► EU heavy equipment
  Troostwijk / Surplex ───────────► auction lots & bids

  Join by make + model + year ──► comps, remarketing, residual checks
```

### Key features

- **Search URL or filters** — paste a search / dealer inventory / category URL, or build one from manufacturer, category id, keywords, state, and `AccountCRMID`
- **Two modes** — `listings` (fast SSR cards with phone + specs) and `details` (Vehicle ld+json address enrichment)
- **Monitor mode** — seed fingerprints, then emit only `new` / `price_change` rows; optional Telegram alerts
- **Dealer phones on cards** — outreach fields without visiting every PDP
- **Retail-only filter** — skip AuctionTime / EquipmentFacts cross-lists
- **Cloudflare-ready** — `curl_cffi` Chrome TLS; Apify Residential (US) recommended
- **Priced-only filter** — skip Call-for-price, Auction labels, and zero-price rows
- **Listing types** — `For Retail`, `For Rent`, and `Auction Results` metadata

### Input

| Field | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `startUrls` | Array | sleeper trucks sample | Search, category, dealer inventory, or detail URLs |
| `searchQuery` | String | — | Keywords for a built search URL |
| `listingType` | String | `For Retail` | `For Retail`, `For Rent`, or `Auction Results` |
| `manufacturer` | String | — | e.g. `FREIGHTLINER`, `PETERBILT`, `KENWORTH` |
| `category` | String | — | Category id (`16045` sleeper, `16013` day cab, `16014` dump) |
| `accountCrmId` | String | — | Dealer `AccountCRMID` inventory watch |
| `state` | String | — | US state filter when building a search URL |
| `runMode` | String | `listings` | `listings` or `details` |
| `pricedOnly` | Boolean | `false` | Keep only rows with a published price |
| `retailOnly` | Boolean | `true` | Skip AuctionTime / EquipmentFacts cross-lists |
| `maxItems` | Integer | `100` | Emit budget (seed run: fingerprint budget) |
| `maxPagesPerUrl` | Integer | `10` | Pages per start URL (~28 listings/page) |
| `monitorMode` | Boolean | `false` | Delta tracking via named KV store |
| `monitorStoreName` | String | `truckpaper-monitor-state` | Distinct name per watch target |
| `proxyConfiguration` | Object | US Residential prefill | Apify proxy settings |

```json
{
  "startUrls": [
    {
      "url": "https://www.truckpaper.com/listings/search?ListingType=For%20Retail&AccountCRMID=17646406"
    }
  ],
  "runMode": "listings",
  "monitorMode": true,
  "monitorStoreName": "tp-dealer-17646406",
  "maxItems": 500,
  "maxPagesPerUrl": 20,
  "pricedOnly": true,
  "retailOnly": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

With `monitorMode: true`, the first run seeds fingerprints and writes **no** dataset rows. Later scheduled runs emit only `changeType: "new"` or `"price_change"`.

### Output

| Field | Description |
| :--- | :--- |
| `id` | Listing id |
| `title` / `make` / `model` / `year` | Truck identity |
| `price` / `currency` / `priceFormatted` | Asking price when published |
| `mileage` / `vin` / `horsepower` | Core truck specs from the card |
| `engineManufacturer` / `engineModel` / `transmission` / `drive` | Powertrain fields |
| `dealerName` / `dealerPhone` / `dealerWebsite` | Dealer contact |
| `accountCrmId` | Dealer account key for inventory watch URLs |
| `location` / `city` / `state` / `postalCode` | Location |
| `isAuctionTime` / `isExternalListing` | Cross-list flags |
| `images` / `specs` | Photos and full spec map |
| `changeType` / `previousPrice` / `monitoredAt` | Monitor deltas only |

```json
{
  "id": "258102945",
  "title": "2007 PETERBILT 379",
  "make": "PETERBILT",
  "model": "379",
  "year": "2007",
  "price": 42000,
  "currency": "USD",
  "priceFormatted": "USD $42,000",
  "condition": "Used",
  "category": "Sleeper Trucks",
  "mileage": "1,037,395 mi",
  "vin": "1XP5DB9X97D682027",
  "horsepower": "475 HP",
  "engineManufacturer": "CATERPILLAR",
  "transmission": "Automatic",
  "drive": "6x4",
  "dealerName": "U.S. Heavy Equipment",
  "dealerPhone": "+12032663040",
  "accountCrmId": "17646406",
  "location": "Bristol, Connecticut 06010",
  "url": "https://www.truckpaper.com/listing/for-sale/258102945/2007-peterbilt-379-sleeper-trucks"
}
```

### Use cases

| Job | How |
| :--- | :--- |
| **Competitor dealer watch** | `accountCrmId` + `monitorMode` on an Apify Schedule |
| **Peterbilt / Freightliner price scan** | Manufacturer + category filters, `pricedOnly` + `retailOnly` |
| **Dealer outreach list** | `listings` mode — phones already on retail cards |
| **Fleet valuation comps** | Filter by make/model/year/mileage; join with EU boards |
| **Cross-market comps** | Join make/model/year with [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper) |
| **MCP / AI research** | Ask an assistant via Apify MCP to run filters and summarize prices |

### 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/truckpaper-scraper').call({
  manufacturer: 'PETERBILT',
  category: '16045',
  runMode: 'listings',
  maxItems: 50,
  pricedOnly: true,
  retailOnly: true,
  proxyConfiguration: {
    useApifyProxy: true,
    apifyProxyGroups: ['RESIDENTIAL'],
    apifyProxyCountry: 'US',
  },
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 3));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("crawloop/truckpaper-scraper").call(
    run_input={
        "accountCrmId": "17646406",
        "runMode": "listings",
        "monitorMode": True,
        "monitorStoreName": "tp-dealer-17646406",
        "maxItems": 300,
        "pricedOnly": True,
        "retailOnly": True,
        "proxyConfiguration": {
            "useApifyProxy": True,
            "apifyProxyGroups": ["RESIDENTIAL"],
            "apifyProxyCountry": "US",
        },
    }
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("changeType"), item.get("title"), item.get("price"))
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~truckpaper-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"manufacturer\":\"PETERBILT\",\"category\":\"16045\",\"maxItems\":25,\"pricedOnly\":true,\"retailOnly\":true}"
```

### 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 (`crawloop/truckpaper-scraper`).

Example prompts:

- "Run TruckPaper Scraper for PETERBILT sleeper trucks, max 40, priced only, and return title, price, mileage, vin, dealerPhone as JSON"
- "Monitor dealer AccountCRMID 17646406 on TruckPaper and list only new or price-changed rows"
- "Scrape TruckPaper day cab listings in TX, then compare asking prices with Truck1 Scraper for the same make and model"

### Suite next step

After US truck asking prices, pull European commercial vehicles with [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper), or European heavy equipment contacts with [Machineryline Scraper](https://apify.com/crawloop/machineryline-scraper).

### FAQ

**Is this a TruckPaper API?**\
There is no official public bulk API for most users. This Actor is a structured scrape / API alternative that returns a dataset you can call from Python, Node.js, cURL, or MCP.

**How do I scrape TruckPaper commercial truck listings?**\
Paste a filtered search or category URL into `startUrls`, set `maxItems`, and run. Or set `manufacturer` + `category` (e.g. Peterbilt sleeper `16045`) and let the Actor build the search URL.

**Do I need details mode for dealer phones?**\
Usually no — retail cards already expose `dealerPhone`, website, and location. Use `details` when you need street address from PDP Vehicle ld+json.

**How do I watch one dealer?**\
Set `accountCrmId` (from any listing card) or paste a dealer inventory search URL, enable `monitorMode`, pick a unique `monitorStoreName`, and schedule the Actor.

**Why are some cards labeled Auction?**\
TruckPaper search mixes retail stock with AuctionTime / EquipmentFacts cross-lists. Leave `retailOnly: true` (default) to keep asking-price comps clean.

**Which proxy should I use?**\
Apify Residential with `apifyProxyCountry: "US"` is recommended — the site sits behind Cloudflare.

**Can I filter Freightliner Cascadia only?**\
Yes — set `manufacturer` to `FREIGHTLINER` and `searchQuery` to `CASCADIA`, or paste an equivalent filtered URL in `startUrls`.

**Can I scrape day cab, dump, or trailer categories?**\
Yes — use category ids such as `16013` (day cab), `16014` (dump), or paste a trailer / reefer / flatbed SEO URL into `startUrls`.

**How do I export TruckPaper data to CSV or Excel?**\
Run the Actor, open the dataset, and download CSV / Excel / JSON from the Apify Console, or pull items via the Apify API / client.

### Related Actors

| Actor | Role |
| :--- | :--- |
| [Truck1 Scraper](https://apify.com/crawloop/truck1-scraper) | European trucks & trailers |
| [Machineryline Scraper](https://apify.com/crawloop/machineryline-scraper) | EU heavy equipment + dealer contacts + monitor |
| [Exapro Scraper](https://apify.com/crawloop/exapro-scraper) | European used industrial machinery |
| [Machineseeker Scraper](https://apify.com/crawloop/machineseeker-scraper) | Machineseeker / Maschinensucher regional boards |
| [Troostwijk Scraper](https://apify.com/crawloop/troostwijk-scraper) | European industrial auction lots |
| [Surplex Scraper](https://apify.com/crawloop/surplex-scraper) | European plant-closure auctions |

# Actor input Schema

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

Search results, category SEO pages, dealer inventory URLs (AccountCRMID), or direct listing detail pages. Example: https://www.truckpaper.com/listings/for-sale/sleeper-trucks/16045

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

Optional keyword search appended as a built search URL (e.g. Cascadia, T680, day cab).

## `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. FREIGHTLINER, PETERBILT, KENWORTH, VOLVO, INTERNATIONAL, MACK).

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

TruckPaper category id (e.g. 16045 sleeper trucks, 16013 day cab, 16014 dump trucks, 16007 box trucks).

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

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

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

Optional state filter when building a search URL (e.g. TX, CA, FL).

## `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 TruckPaper US.

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

listings = fast card fields (price, make/model, mileage, VIN, 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-listed cards that appear in TruckPaper search results (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).

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

Apify Residential Proxies recommended — TruckPaper uses Cloudflare.

## `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
{
  "startUrls": [
    {
      "url": "https://www.truckpaper.com/listings/for-sale/sleeper-trucks/16045"
    }
  ],
  "searchQuery": "FREIGHTLINER CASCADIA",
  "listingType": "For Retail",
  "manufacturer": "PETERBILT",
  "category": "16045",
  "accountCrmId": "17646406",
  "state": "TX",
  "sort": "9",
  "baseUrl": "https://www.truckpaper.com",
  "runMode": "listings",
  "pricedOnly": false,
  "retailOnly": true,
  "maxItems": 100,
  "maxPagesPerUrl": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "concurrencyLimit": 5,
  "monitorMode": false,
  "monitorStoreName": "truckpaper-monitor-state",
  "resetMonitorState": false
}
```

# Actor output Schema

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

Default dataset items: truck/trailer listings with prices, mileage, VIN, and dealer phones.

# 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.truckpaper.com/listings/for-sale/sleeper-trucks/16045"
        }
    ],
    "baseUrl": "https://www.truckpaper.com",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    },
    "monitorStoreName": "truckpaper-monitor-state"
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/truckpaper-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.truckpaper.com/listings/for-sale/sleeper-trucks/16045" }],
    "baseUrl": "https://www.truckpaper.com",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
    "monitorStoreName": "truckpaper-monitor-state",
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/truckpaper-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.truckpaper.com/listings/for-sale/sleeper-trucks/16045"
    }
  ],
  "baseUrl": "https://www.truckpaper.com",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "monitorStoreName": "truckpaper-monitor-state"
}' |
apify call crawloop/truckpaper-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/truckpaper-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/nydBiZrGWPqneV8Kh/builds/FsZtbdCBpicgsX2l1/openapi.json
