# Cycle Trader Listings Scraper — Prices & Dealers (`crawloop/cycle-trader-scraper`) Actor

Scrape Cycle Trader motorcycle listings: price, mileage, year, make, model, seller type, and dealer phone. Paste a search URL or filter by ZIP, make, and condition.

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

## Pricing

from $4.00 / 1,000 cycle trader listings

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/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

## Cycle Trader Listings Scraper

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by Trader Interactive or Cycle Trader. Data is read from publicly accessible search and listing 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.

Cycle Trader Listings Scraper reads public motorcycle and powersports search results and saves one row per listing: price, mileage, year, make, model, condition, seller type, location, and the dealer phone when the page shows one. Paste a search URL or set a ZIP, make, and condition. This Cycle Trader scraper is an API alternative for those pages: run it from Python, Node.js, or MCP and export JSON.

Dealers and pricing desks use it to watch inventory near a ZIP. A listing page can be opened when you need the full description; the search card is enough for price and mileage.

### Which Actor in this suite

| Actor | What it returns |
| :--- | :--- |
| Cycle Trader Listings Scraper ◄── you are here | Motorcycle price, mileage, seller, and location |
| [Equipment Trader Scraper](https://apify.com/crawloop/equipmenttrader-scraper) | Construction and farm equipment listings |
| [Machinery Trader Scraper](https://apify.com/crawloop/machinerytrader-scraper) | Machinery dealer inventory and price changes |

### When to use

- You price used and new motorcycles from a ZIP, make, or a search URL you already filtered.
- You want dealer name, phone, mileage, and a price drop in one dataset.
- You need JSON for a spreadsheet, a scheduled job, or an AI assistant.

Skip this Actor for private messages, account data, or a national dump of every listing in one run. Each search page holds about 42 cards, and the site counter stops at 10 pages.

### Key features

- Search URL, or ZIP, radius, make, keyword, condition, seller type, price, and year
- Price, previous price, mileage, VIN, color, photos, and dealer phone from the search card
- Optional listing page for the full description
- One row per listing
- US residential proxy. A datacenter IP is blocked
- JSON dataset for API, Python, Node, and MCP

### Input

| Field | Required | Description |
| :--- | :--- | :--- |
| `startUrls` | No | Cycle Trader search or category URLs. Listing URLs are skipped. |
| `zip` / `radius` | No | US ZIP and miles. Radius defaults to 50 when a ZIP is set. |
| `make` | No | Brand, for example Harley-Davidson or Honda. |
| `keyword` | No | Extra keyword on the search URL. |
| `condition` | No | `New` or `Used`. |
| `sellerType` | No | `dealer` or `private`. |
| `minPrice` / `maxPrice` | No | Asking-price range in USD. |
| `minYear` / `maxYear` | No | Model-year range. |
| `maxItems` | No | Rows to save. Default 50. |
| `maxPages` | No | Pages per URL, 1–10. Default 1. |
| `scrapeDetails` | No | Open each listing page for the full description. Default off. |
| `proxyConfiguration` | No | US residential. Required for a successful page. |

```json
{
  "startUrls": [
    {
      "url": "https://www.cycletrader.com/motorcycles-for-sale?zip=90210&radius=50"
    }
  ],
  "maxItems": 20,
  "maxPages": 1,
  "scrapeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

Make and ZIP without a pasted URL:

```json
{
  "zip": "90210",
  "radius": "50",
  "make": "Harley-Davidson",
  "condition": "Used",
  "maxItems": 20
}
```

### Output

| Field | Description |
| :--- | :--- |
| `id` | Listing id |
| `url` | Public listing URL |
| `title` | Year, make, and model |
| `year` / `make` / `model` / `trim` | Identity fields |
| `price` / `previousPrice` / `currency` | Asking price in USD, plus the prior price when a drop is shown |
| `mileage` | Odometer miles |
| `condition` | New or Used |
| `category` | Category such as Cruiser |
| `sellerType` | Dealer or Private |
| `dealerName` / `dealerPhone` | Dealer name and the public phone, when shown |
| `city` / `state` / `zip` / `location` | Where the unit is listed |
| `vin` | VIN or serial printed on the listing |
| `color` | Color |
| `images` / `imageCount` | Photo URLs and count |
| `description` | Text from the card, or the full description when listing pages are on |
| `listedAt` | When the listing was created |
| `badge` | Card badge such as Reduced |
| `detailEnriched` | True when a listing page added a longer description |
| `source` | `cycletrader` |

```json
{
  "id": "5040031344",
  "url": "https://www.cycletrader.com/listing/2008-Harley-Davidson-SOFTAIL+CROSS+BONES-5040031344",
  "title": "2008 Harley-Davidson SOFTAIL CROSS BONES",
  "year": 2008,
  "make": "Harley-Davidson",
  "model": "SOFTAIL CROSS BONES",
  "price": 11900,
  "previousPrice": 14200,
  "currency": "USD",
  "mileage": 16346,
  "condition": "Used",
  "sellerType": "Private",
  "location": "Anaheim, CA",
  "zip": "92804",
  "vin": "5HD1JM5468Y061944",
  "imageCount": 20,
  "source": "cycletrader"
}
```

### Use cases

- A dealer compares Harley-Davidson asking prices inside 50 miles of a ZIP.
- A lender checks mileage, year, and price on current Cycle Trader inventory.
- A marketplace analyst exports a make search to CSV and refreshes it on a schedule.

### Integration examples

Replace `YOUR_TOKEN` and the Actor id after you open the Actor in Apify Console.

#### Node.js

```javascript
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_TOKEN" });
const run = await client.actor("crawloop/cycle-trader-scraper").call({
  zip: "90210",
  radius: "50",
  make: "Honda",
  maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("crawloop/cycle-trader-scraper").call(run_input={
    "zip": "90210",
    "radius": "50",
    "make": "Honda",
    "maxItems": 20,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~cycle-trader-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"zip\":\"90210\",\"radius\":\"50\",\"make\":\"Honda\",\"maxItems\":20}"
```

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

Example prompts:

- "Run Cycle Trader Listings Scraper for used Honda motorcycles within 50 miles of 90210 and return the top 20 rows as JSON"
- "Scrape Cycle Trader listings for Harley-Davidson and summarize price, mileage, and location"
- "Chain Cycle Trader Listings Scraper then Equipment Trader Scraper for a dealer who stocks both motorcycles and construction equipment"

### Suite next step

After the motorcycle search, run [Equipment Trader Scraper](https://apify.com/crawloop/equipmenttrader-scraper) for construction and farm equipment from the same dealer-inventory workflow, or [Machinery Trader Scraper](https://apify.com/crawloop/machinerytrader-scraper) for machinery comps.

### FAQ

**Does this log in?**
No. It reads public search pages and, when you turn listing pages on, public listing pages.

**Why is a residential proxy required?**
The site answers a datacenter IP with an AWS WAF challenge. The default proxy is US residential.

# Actor input Schema

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

Cycle Trader search or category URLs. Listing pages are skipped. Leave empty to use the filters below.

## `zip` (type: `string`):

US ZIP. Builds a search URL when set. Radius defaults to 50 miles.

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

Search radius in miles. Used with ZIP.

## `make` (type: `string`):

Brand name, for example Harley-Davidson or Honda. A Cycle Trader make id (Name|id) is accepted as-is.

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

Optional keyword added to the search URL.

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

New or Used.

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

Dealer or private seller.

## `minPrice` (type: `string`):

Lowest asking price in USD.

## `maxPrice` (type: `string`):

Highest asking price in USD.

## `minYear` (type: `string`):

Oldest model year.

## `maxYear` (type: `string`):

Newest model year.

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

How many listings to save. Each search page has about 42 cards.

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

Search pages per URL. Cycle Trader exposes up to 10 pages in the page counter.

## `scrapeDetails` (type: `boolean`):

Visit each listing page for the full description. Search cards already include price, mileage, photos, and dealer phone when the site shows them.

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

US residential is required. A datacenter IP is blocked by AWS WAF.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.cycletrader.com/motorcycles-for-sale?zip=90210&radius=50"
    }
  ],
  "maxItems": 50,
  "maxPages": 1,
  "scrapeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# 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.cycletrader.com/motorcycles-for-sale?zip=90210&radius=50"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/cycle-trader-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.cycletrader.com/motorcycles-for-sale?zip=90210&radius=50" }] }

# Run the Actor and wait for it to finish
run = client.actor("crawloop/cycle-trader-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.cycletrader.com/motorcycles-for-sale?zip=90210&radius=50"
    }
  ]
}' |
apify call crawloop/cycle-trader-scraper --silent --output-dataset

```

## MCP server setup

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