# RVTrader Scraper: Extract RV Listings, Prices & Dealers (`fayoussef/rvtrader-scraper`) Actor

Scrape RV listings from RVTrader.com by search URL or by filters (type, make, model, price, year, mileage, ZIP radius). Returns 55+ fields per listing: price and full price-drop history, VIN, mileage, length, dealer name, phone, website, GPS coordinates and every photo URL.

- **URL**: https://apify.com/fayoussef/rvtrader-scraper.md
- **Developed by:** [youssef farhan](https://apify.com/fayoussef) (community)
- **Categories:** Developer tools, E-commerce, Real estate
- **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 and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

### What does RVTrader Scraper do?

**RVTrader Scraper extracts RV listings from [RVTrader.com](https://www.rvtrader.com) at scale**, the largest RV marketplace in North America, and returns clean structured data you can use immediately. Paste any RVTrader search URL, or build a search from filters (RV type, make, model, price, year, mileage, ZIP radius, state), and the Actor returns **every field the site holds on each listing**: asking price and full price-drop history, VIN, mileage, length, condition, dealer name, phone number, website, GPS coordinates, and direct URLs to all photos.

It talks to the same data source that powers RVTrader's own search results, so you get far more per listing than the page displays, including fields the website never renders. On top of that you get the usual Apify advantages: a REST API, scheduled runs, webhooks and integrations, automatic proxy rotation, run monitoring, and export to JSON, CSV, Excel or XML.

Unlike a browser-based scraper, this Actor collects **42 listings per request** and can page through an entire result set, so a nationwide sweep of thousands of RVs finishes in minutes rather than hours.

### Why use RVTrader Scraper?

- **RV price monitoring.** Track asking prices across the market, and use the `priceHistory` field to see every reduction on a listing with its exact date. Schedule a daily run and you have a price index nobody else has.
- **Dealer lead generation.** Every listing carries the dealer's name, phone number, website and location. Filter for private sellers instead when you buy inventory direct.
- **Competitive inventory intelligence.** Feed a `dealerId` back into the input to pull a competitor's entire inventory, then watch how their stock and pricing move week to week.
- **Market and valuation research.** Compare like-for-like units by year, make, model, trim, mileage and length to build residual-value or depreciation models.
- **Deal sourcing and arbitrage.** Filter for the `price_reduced` and `willing_to_negotiate` badges to surface motivated sellers, or sort by price to find under-market units.
- **Feeding an app or marketplace.** Photo URLs, coordinates and full descriptions come ready to use, so you can build an aggregator, a comparison site, or a lead-routing tool.

### How to use RVTrader Scraper

1. Click **Try for free** and open the Actor's Input tab.
2. Paste one or more RVTrader search URLs. That is the main input: set up the search on rvtrader.com until the results look right, then copy the address bar. If you would rather not paste a link, leave the URL field empty and pick your filters instead (RV type, make, price range, ZIP code and radius, and so on).
3. Set **Max listings** to control the size and cost of the run.
4. Click **Start**. Results stream into the dataset as they arrive, so you can watch them in the Output tab straight away.
5. When it finishes, download the data as JSON, CSV, Excel or XML, or fetch it from the API. To keep it fresh, open the Schedules tab and have it run daily.

That is the whole setup. There are no accounts to create and no API keys to find. On a paid plan there are no proxies to configure either, because residential proxies are built in; free-plan runs use Apify Proxy residential on your own account.

### How to scrape RVTrader data without writing code

You do not need to write any code. Paste an RVTrader URL into the input and press Start. If you would rather describe what you want than paste a link, use the filters: choose **Class C** under RV type, type `Winnebago` under Makes, set a ZIP code and radius, and the Actor builds the search for you.

If you do write code, everything here is available through the [Apify API](https://docs.apify.com/api/v2), the [JavaScript SDK](https://docs.apify.com/sdk/js/) and the [Python SDK](https://docs.apify.com/sdk/python/). You can also call this Actor from an AI agent through [Apify MCP](https://mcp.apify.com), which is why the output ships with a full dataset schema: an agent can read the field descriptions and chain the results into the next step without a human explaining the shape of the data.

### Input

There are two ways to tell the Actor what to scrape, and you pick one:

- **Search by URL (the main input).** Paste rvtrader.com search URLs and exactly those searches run. Whatever is in the URL is the search, so **the filter fields are ignored** whenever a URL is present. The run log says so when it happens.
- **Search by filters.** Leave the URL field empty and describe the search instead. The Actor builds it for you.

Every field is optional. Run it with no input at all and it scrapes the whole national RV inventory, cheapest first. URLs must be on `www.rvtrader.com`: anything else is rejected by name in the log within seconds rather than retried, and if none of the URLs you gave are usable the run stops immediately instead of scraping something you did not ask for.

| Field | What it does |
| --- | --- |
| **RVTrader search URLs** | Paste any rvtrader.com search or browse URL. Every filter already in the URL is carried over. Setting this ignores the filter fields below. |
| **Keyword** | Free-text search over everything RVTrader indexes for a listing, for example `bunkhouse`. |
| **RV type** | Travel Trailer, Fifth Wheel, Class A, Class B, Class C, Toy Hauler, Truck Camper, Pop Up Camper, Destination Trailer, Park Model, Teardrop Trailer, Fish House. |
| **Makes / Models / Trims** | Brand, model and floorplan names, for example `Winnebago`, `Sunseeker`, `24K`. |
| **Condition** | New only, Used only, or any. |
| **ZIP code + radius** | Search around a location from 25 miles out to nationwide. |
| **States** | Restrict to specific states or provinces. |
| **Price / Year / Mileage / Length** | Minimum and maximum ranges. |
| **Max listings** | Hard stop on how many listings the run returns. This is your cost control. |
| **Sort by** | Price, year, mileage, distance, recently listed, or leave empty to collect the whole result set. Filter searches only: a pasted URL keeps its own sort. |
| **More filters** | Seller type, fuel type, sub-type (Super C, Skoolie, Diesel Pusher and more), badges, sleeping capacity, slide-outs, dealer ID, dealer name, city. |
| **Advanced** | Deep pagination, raw endpoint fields, parallel connections, custom proxies. |

```json
{
  "rvClasses": ["Class C"],
  "makes": ["Winnebago", "Jayco"],
  "condition": "Used",
  "priceMin": 30000,
  "priceMax": 90000,
  "yearMin": 2018,
  "zipCode": "10001",
  "radius": "200",
  "maxItems": 500
}
```

### Output

One dataset item per RV listing. Download it as JSON, HTML, CSV, or Excel.

```json
{
  "listingId": "5037865212",
  "url": "https://www.rvtrader.com/listing/2011-Winnebago-View+24K-5037865212",
  "title": "2011 Winnebago View 24K",
  "year": 2011,
  "make": "Winnebago",
  "model": "View 24K",
  "trim": "24K",
  "rvClass": "Class C",
  "condition": "Used",
  "price": 45400,
  "priceHistory": [{ "changedAt": "2026-03-05 06:13:06", "price": 47500 }],
  "lastPriceDropAt": "2026-03-05T06:13:06-05:00",
  "acceptsOffers": true,
  "mileage": 72000,
  "lengthFeet": 24,
  "vin": "WDAPF4CC3A9460411",
  "stockNumber": "466593",
  "sellerType": "Dealer",
  "dealerName": "Pop RVs",
  "dealerId": "3018596",
  "dealerPhone": "9412001260",
  "dealerWebsite": "https://www.poprvs.com",
  "trustedPartner": "5 year trusted partner",
  "city": "Newburgh",
  "state": "New York",
  "stateCode": "NY",
  "zipCode": "12550",
  "latitude": 41.5391,
  "longitude": -74.0491,
  "badges": ["history_report", "price_reduced"],
  "photoCount": 63,
  "mainPhoto": "https://cdn-media.tilabs.io/v1/media/69e0b5b0d2c106bb5d0a389a.jpg",
  "photos": [
    {
      "id": "69e0b5b0d2c106bb5d0a389a",
      "original": "https://cdn-media.tilabs.io/v1/media/69e0b5b0d2c106bb5d0a389a.jpg",
      "large": "https://cdn-media.tilabs.io/v1/media/69e0b5b0d2c106bb5d0a389a.jpg?width=1600&quality=90",
      "thumbnail": "https://cdn-media.tilabs.io/v1/media/69e0b5b0d2c106bb5d0a389a.webp?width=400&height=300"
    }
  ],
  "tagline": "2011 Winnebago View 24K with one slide-out and a spacious rear bathroom!",
  "descriptionText": "2011 Winnebago View 24K, Stock #466593. Reason for selling is ..."
}
```

### Data fields

| Field | Description |
| --- | --- |
| `listingId`, `adId`, `url` | RVTrader's stable listing identifier and the public listing page. |
| `title`, `year`, `make`, `model`, `trim`, `modelGroup` | What the RV is. |
| `rvClass`, `category`, `condition` | RV type, narrower sub-type, and New or Used. |
| `price`, `msrp`, `salePrice`, `rebate` | Every price the listing carries. |
| `priceHistory`, `lastPriceDropAt` | Each recorded price change with its timestamp. |
| `acceptsOffers`, `priceOnRequest` | Whether the seller takes offers or hides the price. |
| `mileage`, `lengthFeet`, `vin`, `stockNumber` | Unit specifics. Mileage is null on towables. |
| `sellerType`, `dealerName`, `dealerId`, `dealerGroupName` | Who is selling. |
| `dealerPhone`, `dealerPhones`, `dealerWebsite`, `sellerListingUrl` | How to reach them. `dealerPhones` separates the real line from call-tracking numbers. |
| `city`, `state`, `stateCode`, `zipCode`, `latitude`, `longitude`, `mapUrl` | Where the RV is. |
| `mainPhoto` | The listing's lead photo as one ready-to-use URL, at full original resolution. |
| `photos`, `photoCount`, `floorplanImage` | Every photo in three sizes, plus the floorplan diagram. |
| `description`, `descriptionText`, `tagline` | Seller copy, as HTML and as plain text. |
| `badges`, `hasHistoryReport`, `isPremium`, `trustedPartner` | Merchandising and trust signals. |
| `listedAt`, `scrapedAt`, `queryLabel` | When it was listed, when you collected it, and which search found it. |
| `adFeatures`, `adAttributes` | Which paid ad features the listing carries. |
| `dealerFeatures`, `endpointFields` | The complete untouched source row. Enable **Include raw endpoint fields** to get these. |

### How much does it cost to scrape RVTrader?

This Actor uses **pay per event**, so you pay for results rather than for run time. There is a small charge when a run starts and a charge for each listing delivered to your dataset. A listing that was already in your dataset from an earlier part of the same run is never charged twice.

**Proxies are included on paid plans**, with nothing to configure. Free-plan runs use Apify Proxy residential on your own account instead, so a free trial run draws on your own Apify proxy usage. You can always supply your own proxies under Custom proxy URLs.

**Max listings** is therefore your exact cost ceiling. Set it to 100 while you test, then raise it.

Free plan users can retrieve up to **50 listings per run** so you can evaluate the output before committing. [Subscribe to an Apify plan](https://apify.com/pricing?fpr=youssef) to lift that and to run larger, faster, scheduled jobs.

### Tips for faster and cheaper runs

- **Narrow the search before raising the limit.** A ZIP code plus a 200 mile radius costs a fraction of a nationwide sweep and usually answers the same question.
- **Leave Sort by empty when you want everything.** RVTrader caps any *sorted* search at 420 listings. With no sort selected, the Actor walks the whole result set by reopening the search on a rising price cursor.
- **Pick a sort when you only want the top N.** "Recently listed" plus a Max listings of 100 is the cheapest way to monitor new inventory.
- **Leave raw endpoint fields off** unless you need them. They roughly triple dataset size.
- **Leave parallel connections at 4.** Connections open only as the work needs them, so a small search still opens just one and a big one opens several at once.
- **Schedule instead of re-running big jobs.** A daily narrow run keeps your data current for far less than a weekly nationwide sweep.

### FAQ

#### Is there an RVTrader API?

RVTrader does not offer a public API for listing data. This Actor is the practical alternative: it returns the same data as a structured JSON feed you can call from the [Apify API](https://docs.apify.com/api/v2), a scheduled run, or an AI agent.

#### Is scraping RVTrader legal?

This Actor collects only publicly available listing information, the same content any visitor sees without logging in. Scraping public data is generally lawful in the US and EU, but the law depends on what you do with the data. It does not collect private personal data, and dealer contact details are published by the dealers themselves for exactly this purpose. Review RVTrader's terms and consult a lawyer for your specific use case, especially before republishing content commercially.

#### How many RV listings can I scrape in one run?

There is no fixed ceiling other than your **Max listings** setting. RVTrader caps a single search at 420 results, so the Actor pages past that automatically by splitting the search into price windows. Very large sweeps are best split by state, which the States filter does for you.

#### Can I scrape a single dealer's whole inventory?

Yes. Take the `dealerId` from any listing that dealer has and put it in the **Dealer ID** input, or use **Dealer name** if you only know the name. The run then returns just that dealer's stock.

#### Can I get RV photos?

Yes. `mainPhoto` gives you the listing's lead image as a single URL, which is what you want for a spreadsheet, a table view, or a quick visual scan. `photos` carries the full gallery, each in three sizes: the original, a large web-ready version, and a thumbnail. All of them download with any HTTP client and need no authentication. Originals are full resolution and can exceed 4 MB, so use the large or thumbnail variants if size matters.

#### Does it include the VIN?

The `vin` field carries the manufacturer serial number whenever the seller published it. Some private listings leave it blank, and some dealers deliberately hide it.

#### Can I monitor RV price drops?

Yes, and this is one of the strongest reasons to use it. Every listing carries a `priceHistory` array with each price change and its date, plus `lastPriceDropAt`. Combine that with the `price_reduced` badge filter and a daily schedule to watch the market move.

#### Will my run resume if it gets interrupted?

Yes. Progress is checkpointed to the key-value store, so a run that migrates between servers or is aborted and restarted continues where it stopped instead of rescraping and recharging you.

#### Why does the run take a moment before the first results appear?

RVTrader is protected by a security challenge that has to be solved in a real browser before any data can be fetched. The Actor does that once per connection at startup, which takes a few seconds, and then collects data quickly.

### Limitations and disclaimer

- The data reflects what RVTrader shows at the moment of the run. Listings are added, edited and sold constantly.
- A sorted search is limited to 420 listings by RVTrader itself. Clear the sort to collect more.
- Fields the seller left empty come back as `null`. Towables have no mileage, and many private listings have no VIN.
- Specification tables from individual listing pages (tank sizes, engine details, standard features) are not included, because this Actor reads the search feed rather than each detail page.
- This project is not affiliated with, endorsed by, or connected to RVTrader.com or Trader Interactive.

### Support and custom work

Found a bug or a field you need? Open a ticket on the Actor's **Issues** tab and it gets looked at.

- 💼 Need a custom scraper or a private variant of this one? Email **youssefarhan24@gmail.com**
- 🌐 Got another site you want scraped? [Suggest it here](https://automationbyexperts.com/apify)
- ⚡ Need higher limits and scheduled runs? [Pick an Apify plan](https://apify.com/pricing?fpr=youssef)

# Actor input Schema

## `searchUrls` (type: `array`):

Paste any rvtrader.com search or browse URL and every filter already in it is carried over, so what you see on the site is what you get. Add as many as you like. This is the main input: when it is set, the filter fields below are ignored and the URLs alone decide what is scraped. Leave it empty to use those filters instead. URLs must be on www.rvtrader.com.

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

Stop after this many listings, counted across every URL or filter combination in the run. This is what you are billed for, so it is the safest cost control.

## `keyword` (type: `string`):

Free-text search over everything RVTrader indexes for a listing, which includes the title and description but also floorplan and feature names, so matches are broader than a plain text search. All words must match, so keep it to one or two, for example bunkhouse.

## `rvClasses` (type: `array`):

Leave empty for every type.

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

Brand names as RVTrader spells them, for example Winnebago, Jayco, Forest River. Leave empty for every make.

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

Model names, for example Sunseeker or View 24K. Each model is scraped as its own query, so adding several multiplies the run time.

## `condition` (type: `string`):

New, Used, or both.

## `zipCode` (type: `string`):

Search around this ZIP code. Leave empty to search the whole country.

## `radius` (type: `string`):

Only used when a ZIP code is set.

## `states` (type: `array`):

Restrict to these states or provinces. Each one is scraped as its own query, which also helps when a result set is very large.

## `priceMin` (type: `integer`):

Listings priced below this are skipped. Listings with no price are treated as 0.

## `priceMax` (type: `integer`):

Listings priced above this are skipped.

## `yearMin` (type: `integer`):

Oldest model year to include.

## `yearMax` (type: `integer`):

Newest model year to include.

## `mileageMax` (type: `integer`):

Motorised RVs only; towables carry no mileage.

## `sortBy` (type: `string`):

Leave empty to collect the whole result set. Picking a sort order means the newest or cheapest listings come first, but RVTrader caps any sorted query at 420 listings, so a sorted run cannot return more than that per query. Applies to filter searches only: a pasted URL keeps whatever sort the URL itself carries.

## `sellerType` (type: `string`):

Limit to dealer inventory or to private sellers.

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

Motorised RVs only. Leave empty for every fuel type.

## `rvCategories` (type: `array`):

Narrower body styles that sit under the main RV types.

## `badges` (type: `array`):

Keep only listings carrying one of these RVTrader badges.

## `trims` (type: `array`):

Trim or floorplan codes, for example 24K. Each trim is scraped as its own query.

## `lengthMin` (type: `integer`):

Shortest overall length to include, in feet.

## `lengthMax` (type: `integer`):

Longest overall length to include, in feet.

## `sleepsMin` (type: `integer`):

Minimum sleeping capacity.

## `slideoutsMin` (type: `integer`):

Minimum number of slide-outs.

## `dealerId` (type: `string`):

Scrape one dealer's whole inventory. The ID is in the dealerId field of any listing this actor returns.

## `dealerName` (type: `string`):

Exact dealer name, for example Pop RVs.

## `city` (type: `string`):

Exact city name, for example Newburgh.

## `deepPagination` (type: `boolean`):

RVTrader hard-caps every search at 420 listings. With this on, the actor reopens the search on a rising price cursor until the whole result set is collected. Turn it off to stop at the first 420.

## `includeRawEndpointFields` (type: `boolean`):

Adds dealerFeatures (88 internal dealer entitlement flags) and endpointFields (the complete untouched RVTrader row) to every item. Useful for auditing, but it roughly triples dataset size and slows the run.

## `maxConcurrency` (type: `integer`):

How many searches run in parallel. Connections are opened only as the work needs them, so a small search still opens just one. 4 is a good balance.

## `customProxyUrls` (type: `array`):

Optional. Bring your own residential proxies, one URL per line as http://user:pass@host:port. Paid plans already include proxies, so leave this empty unless you have a reason. Free runs go through Apify Proxy residential on your own account, so setting your own here avoids that. Proxies must be sticky, meaning one URL keeps one exit IP for several minutes, and only US and Canadian exits reach RVTrader at all.

## Actor input object example

```json
{
  "searchUrls": [
    {
      "url": "https://www.rvtrader.com/Class-C/rvs-for-sale?type=Class%20C%7C198069&zip=10001&radius=75"
    }
  ],
  "maxItems": 1000,
  "condition": "Any",
  "radius": "200",
  "sellerType": "Any",
  "deepPagination": true,
  "includeRawEndpointFields": false,
  "maxConcurrency": 4
}
```

# Actor output Schema

## `listings` (type: `string`):

Every scraped RVTrader listing with pricing, specs, dealer contact details, location and photo URLs.

## `resumeState` (type: `string`):

Progress checkpoint that lets an interrupted or migrated run continue where it stopped.

# 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 = {
    "searchUrls": [
        {
            "url": "https://www.rvtrader.com/Class-C/rvs-for-sale?type=Class%20C%7C198069&zip=10001&radius=75"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fayoussef/rvtrader-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 = { "searchUrls": [{ "url": "https://www.rvtrader.com/Class-C/rvs-for-sale?type=Class%20C%7C198069&zip=10001&radius=75" }] }

# Run the Actor and wait for it to finish
run = client.actor("fayoussef/rvtrader-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 '{
  "searchUrls": [
    {
      "url": "https://www.rvtrader.com/Class-C/rvs-for-sale?type=Class%20C%7C198069&zip=10001&radius=75"
    }
  ]
}' |
apify call fayoussef/rvtrader-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/68imwdvS820PU4BtL/builds/bLMbLMyVBaIpVkvEw/openapi.json
