# MotoSport Scraper: Powersports Parts, Tires and Gear (`recordsdata/motosport-scraper`) Actor

Scrape motosport.com, the US powersports store: aftermarket parts, tires by size, riding gear and OEM parts with part numbers, USD prices, sale and stock status, vehicle fitment and brands, plus monitoring of new items and price changes. No login, no proxy. Export JSON, CSV or Excel.

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

## Pricing

from $22.00 / 1,000 part, gear or oem parts

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

![RecordsData](https://api.apify.com/v2/key-value-stores/AAm3a1h3Z9nYfrvh9/records/banner?v=3)

## MotoSport Scraper: Powersports Parts, Tires, Gear and OEM Part Prices

> MotoSport Scraper is an Apify Actor that extracts products from motosport.com, the US powersports store: aftermarket parts, riding gear, accessories, motorcycle and ATV tires (one row per size) and OEM parts with manufacturer part numbers. Each row has the USD price, sale price, stock, variants and the vehicles the part fits. No login, browser or proxy is needed.

Export the result as JSON, CSV, Excel, XML or HTML, or read it through the Apify API. A run of 3 results takes about 4 seconds in the cloud (median 3.8 s over 18 test runs) and uses about 40 to 70 MB of memory.

### What can you scrape from MotoSport?

- **Parts, gear and accessories (`part`)**: one row per aftermarket product. On 2026-10-19 the store listed 28,981 aftermarket products from 681 brands (helmets, gloves, boots, chains, sprockets, brakes, exhausts, tools, bags and more). Each row has the brand, category path, lowest and highest variant price, list price and discount when on sale, rating, photos and up to 200 variants with size, color, part number, price and quantity left.
- **Tires (`tire`)**: one row per tire size, with the size read into numbers: width, aspect ratio, construction (bias or radial), rim diameter, and load index and speed rating when the size label shows them. Front, rear or combo is read from the name. About 1,300 tire products are listed.
- **OEM parts (`part` with `partOrigin` oem)**: the manufacturer catalog of 470,246 parts for Honda, Yamaha, Kawasaki, Suzuki, KTM, Husqvarna, Can-Am, GasGas and others, with part number, part name, price and shipping time.
- **Vehicle fitment (`fitment`)**: one row per part and vehicle model it fits, with make, model, model code and years. OEM parts add the part group.
- **Brands (`brand`)**: one row per brand with the product count, riding styles and product lines.
- **Price and stock changes (`part` rows with `changeType`)**: with monitoring on, a product whose price moved or that went in or out of stock comes back with the previous price and the difference.

### Why use this MotoSport scraper?

- **Built for one store**: sizes, part numbers, variants and fitment are read from the product page itself, not guessed from a generic page layout.
- **Three ways in**: paste product or brand addresses, read a whole brand, or walk the store catalog in sitemap order and filter it.
- **Checked filters**: price range, in stock, on sale, product kind (part, tire, OEM), category, brand, search words and vehicle make, model and year are applied to every row before it is delivered. Narrow filters read more pages, never return rows that do not match.
- **Prices in US dollars**: the actor pins the store to the US, so a run from any country returns USD.
- **Monitoring**: scheduled runs deliver only new products, or only products whose price or stock changed.
- **Clean, typed output**: numbers are numbers, empty fields are left out instead of filled with `null`, and every run has the same column order.

### How to scrape MotoSport in four steps

1. Create a free account at [console.apify.com](https://console.apify.com) and open the actor.
2. Choose **Where to read from**: addresses and part numbers (lookup), one or more brands, or the whole catalog.
3. Add product addresses, brands, or filters such as price range, product kind and search words, and set the maximum number of items.
4. Click **Start**, then download the dataset from the **Storage** tab.

A minimal input that returns the first 100 Dunlop tires with one row per size:

```json
{
  "mode": "brand",
  "brands": ["dunlop"],
  "productKinds": ["tire"],
  "fetchDetails": true,
  "maxItems": 100
}
```

### Three ways to point the scraper at MotoSport

| You choose | The actor returns |
|---|---|
| **Lookup**: product addresses, brand addresses, OEM part addresses or OEM part numbers | Exactly those products. A bare slug such as `fox-racing-2027-v-core-helmet` works too |
| **Brand**: one or more brands (name, slug or address) | Every product of the brand from its listing pages (60 per page, exact paging), optionally with the full product page |
| **Catalog**: the aftermarket or the OEM section | The store catalog in sitemap order, filtered, from any start position, until the item limit or the scan time limit |

Addresses can be a product (`https://www.motosport.com/dunlop-american-elite-front-tire`), an OEM part (`https://www.motosport.com/oem-parts/part-number/704900813`) or a brand (`https://www.motosport.com/fox-racing`). A bad address returns one free error row.

By default brand mode reads the listing pages only: title, brand, price range, sale flag, rating and photo, which is fast. Switch on **Read each product page (slower)** (or choose a filter that needs it, such as tires, category, stock or fitment) to get variants, part numbers, stock and description.

### What data do you get from MotoSport?

Every row has a `recordType`: `part`, `tire`, `fitment`, or `brand`. Fields that do not apply or that the page does not give are left out.

| Field | Description |
|---|---|
| `recordType`, `sourceSite`, `country` | Row type, `motosport.com`, `US` |
| `listingId`, `productId`, `styleId`, `url`, `slug`, `imageUrl` | Product style code (part rows), size id (tire rows) or part number (OEM rows), site product id, canonical address, address slug, main photo |
| `title`, `brand`, `productType`, `categoryPath` | Product name, brand, the store category (Helmet Offroad, Tire, OEM Parts) and its path |
| `vehicleType`, `partOrigin`, `condition` | `part` or `tire`, `aftermarket` or `oem`, `new` |
| `sku`, `partNumber`, `partNumbers`, `partName` | Store SKU, manufacturer part number (single variant), all variant part numbers, OEM part name |
| `price`, `priceMax`, `listPrice`, `discountPercent`, `onSale`, `currency` | Lowest variant price, highest variant price, list price before the sale, discount percent, sale or clearance flag, `USD` |
| `available`, `stockStatus`, `quantityAvailable`, `shipsIn` | In stock flag, `in stock` or `out of stock`, units left when the page shows it, OEM shipping time |
| `variantCount`, `variants`, `size`, `color` | Number of variants, each with id, part number, size, color, price, stock and quantity; size and color for a single-variant product |
| `tirePosition`, `tireSize`, `tireWidthMm`, `tireAspectRatio`, `tireConstruction` | Front, rear or combo; the size label; metric width and aspect ratio; bias, radial or bias belted |
| `tireDiameterInches`, `tireWidthInches`, `rimInches`, `loadIndex`, `speedRating` | Inch sizes (such as 26x11-12), rim size, load index and speed rating when printed |
| `fitmentRequired` | True when the store asks for a vehicle before it shows stock or fit |
| `make`, `model`, `modelCode`, `vehicleGroup`, `yearFrom`, `yearTo`, `years`, `partGroups` | Fitment rows: the vehicle make and model, store model code, year range and list of years, OEM part groups |
| `rating`, `reviewCount`, `isNew` | Average rating, number of reviews, new arrival flag from brand pages |
| `productCount`, `ridingStyles`, `productLines` | Brand rows: number of products, riding styles, product lines |
| `description`, `images`, `imageCount` | Description text, photo links, number of photos |
| `previousPrice`, `priceChange`, `priceChangePct`, `changeType` | Monitoring: the earlier price, the difference, percent, and `price-drop`, `price-increase`, `back-in-stock` or `out-of-stock` |
| `sellerName`, `sellerUrl`, `isPrivateSeller` | Always `MotoSport`, the store address, `false` (the store is the only seller) |
| `detailLevel`, `scrapedAt`, `error` | `listing` or `full`, time of the read, and `error` only on a free error row |

#### Sample output

A real `tire` row from a cloud run:

```json
{
  "imageUrl": "https://content.motosport.com/images/items/large/ATX/ATX0003/X001.jpg",
  "title": "Artrax CTX Radial Tire",
  "recordType": "tire",
  "listingId": "ATX0003-X001-Y001",
  "productId": "122783",
  "url": "https://www.motosport.com/artrax-ctx-radial-tire",
  "sourceSite": "motosport.com",
  "country": "US",
  "listingType": "sale",
  "vehicleType": "tire",
  "slug": "artrax-ctx-radial-tire",
  "styleId": "ATX0003",
  "sku": "AT-CTX-26-11-14",
  "partNumber": "1308-26111400-CL77",
  "brand": "Artrax",
  "productType": "Tire",
  "categoryPath": ["Tires"],
  "partOrigin": "aftermarket",
  "condition": "new",
  "price": 102.77,
  "onSale": false,
  "currency": "USD",
  "available": true,
  "stockStatus": "in stock",
  "tireSize": "26x11-14",
  "tireConstruction": "bias",
  "tireDiameterInches": 26,
  "tireWidthInches": 11,
  "rimInches": 14,
  "fitmentRequired": false,
  "rating": 4.8,
  "reviewCount": 299,
  "imageCount": 1,
  "sellerName": "MotoSport",
  "sellerUrl": "https://www.motosport.com",
  "isPrivateSeller": false,
  "detailLevel": "full",
  "scrapedAt": "2026-10-19T09:37:30.732Z"
}
```

A real `part` row for a product on sale (description, photos, most variants and part numbers left out):

```json
{
  "title": "Fox Racing 2027 Flexair Gloves",
  "recordType": "part",
  "listingId": "FXRZ5L4",
  "url": "https://www.motosport.com/fox-racing-2027-flexair-gloves",
  "vehicleType": "part",
  "sku": "FXRZ5L4",
  "partNumbers": ["33725-001-S", "33725-110-S", "33725-130-S"],
  "brand": "Fox Racing",
  "productType": "Gloves",
  "categoryPath": ["Riding Gear", "Gloves"],
  "partOrigin": "aftermarket",
  "price": 39.99,
  "priceMax": 49.95,
  "listPrice": 49.95,
  "discountPercent": 19.94,
  "onSale": true,
  "currency": "USD",
  "available": true,
  "stockStatus": "in stock",
  "variantCount": 21,
  "variants": [
    { "id": "FXRZ5L4-X001-Y001", "partNumber": "33725-001-S", "size": "Small", "color": "Black", "price": 49.95, "available": true, "quantityAvailable": 4 }
  ],
  "fitmentRequired": false,
  "imageCount": 10,
  "detailLevel": "full"
}
```

A real OEM `part` row:

```json
{
  "title": "Can-Am OEM LH REAR FENDER DECAL",
  "recordType": "part",
  "listingId": "704900813",
  "url": "https://www.motosport.com/oem-parts/part-number/704900813",
  "make": "Can-Am",
  "partNumber": "704900813",
  "partName": "LH REAR FENDER DECAL",
  "brand": "Can-Am OEM",
  "productType": "OEM Parts",
  "partOrigin": "oem",
  "price": 12.49,
  "onSale": false,
  "currency": "USD",
  "available": true,
  "stockStatus": "in stock",
  "shipsIn": "4-9 Days",
  "detailLevel": "full"
}
```

A real `fitment` row (one part, one vehicle model):

```json
{
  "title": "Dunlop Geomax MX14 Rear Tire",
  "recordType": "fitment",
  "listingId": "DUN1WVB:alta:redshiftmx",
  "url": "https://www.motosport.com/dunlop-geomax-mx14-rear-tire",
  "vehicleType": "tire",
  "make": "Alta",
  "model": "REDSHIFT MX",
  "modelCode": "redshiftmx",
  "vehicleGroup": "Alta Dirt Bikes",
  "yearFrom": 2017,
  "yearTo": 2018,
  "years": [2018, 2017],
  "sku": "DUN1WVB",
  "brand": "Dunlop",
  "productType": "Tire",
  "price": 50.99,
  "currency": "USD"
}
```

A `brand` row (product lines shortened):

```json
{
  "title": "Fox Racing",
  "recordType": "brand",
  "listingId": "fox-racing",
  "url": "https://www.motosport.com/fox-racing",
  "brand": "Fox Racing",
  "productCount": 1027,
  "ridingStyles": ["Dirt Bike", "ATV", "Utility ATV", "UTV", "Street Bike", "Cruiser"],
  "productLines": ["180", "Flexair", "V1", "V3 RS", "Vue", "360"]
}
```

### MotoSport prices, sales and stock

- `price` is the lowest price over the variants and `priceMax` the highest, so a glove sold in 21 size and color variants can show 39.99 and 49.95. `listPrice` is the price before the sale for the sale variants, and `discountPercent` is computed from it. `onSale` is true when a list price is higher than the price or the store marks the product Clearance.
- Tires have no list price on the page, so a tire row is never flagged as on sale. Sales apply to parts, gear and OEM parts.
- `available` and `quantityAvailable` come from the page stock message. Products that need a vehicle to be chosen first (about a quarter of the aftermarket catalog in a 80-product sample, mostly single-variant fitment parts) show no stock until then: the row leaves `available` out, and the **In stock only** filter does not return them.
- Prices follow the visitor country on motosport.com. The actor pins the store to the United States, so every row is in USD.

### Monitor MotoSport price and stock changes

Switch on **Only new items (monitor)** and the actor remembers every product it delivered in a named key-value store of your own account (`motosport-seen`). Scheduled runs of the same search return only products it has not delivered before. Add **Also return price and stock changes** and a product whose price or stock status changed since the last run comes back with `previousPrice`, `priceChange`, `priceChangePct` and `changeType`. Rows skipped by monitoring are never charged.

### How does it compare with other options?

On 2026-10-19 the Apify Store had no actor for motosport.com. The practical alternatives are a generic e-commerce scraper or copying pages by hand.

| | MotoSport Scraper | A generic e-commerce scraper |
|---|---|---|
| Tire sizes | One row per size with width, aspect ratio, rim and construction as numbers | A product page reads as one item with the size list as text |
| OEM catalog | 470,246 parts by part number, part name, make and shipping time | Needs a separate address list and field mapping |
| Vehicle fitment | One row per part and vehicle model with years | Not part of a generic page layout |
| Variants | Size, color, part number, price, stock and quantity left per variant | Depends on the layout the tool guesses |
| Price monitoring | Built in, with previous price and type of change | Usually left to you |

### MotoSport data use cases

#### Price tracking and MAP checks

Track the prices of a brand or a category every day, find new sales and clearance items, and compare MotoSport with your own shop or other retailers.

#### Tire finder and size catalog

Build a tire database by size: every width, aspect ratio and rim size per brand, with price and stock, for ATV, dirt bike, street and cruiser tires.

#### OEM part lookup and fitment tables

Look up Honda, Yamaha, Can-Am or Kawasaki part numbers in bulk, and get the vehicle models and years each part fits.

#### Assortment and market research

Count the products and product lines per brand, find which brands the store carries for each riding style, and watch new arrivals.

### Automating the MotoSport Scraper

Schedule runs from the Apify Console, then send the dataset to Make, Zapier, n8n, Airbyte, Google Sheets, Slack or any webhook. With **Only new items** on, a daily schedule only delivers what changed.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('RecordsData/motosport-scraper').call({
    mode: 'brand',
    brands: ['fox-racing'],
    onSaleOnly: true,
    maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0].title, items[0].price, items[0].listPrice);
```

### Use with AI agents (MCP)

Connect the Apify MCP server to Claude, Cursor or another MCP client and this actor appears as a tool: `https://mcp.apify.com?tools=RecordsData/motosport-scraper`.

Example prompt: "List the Dunlop tires on motosport.com with rim size 17, with size, price and stock." The agent sends `{ "mode": "brand", "brands": ["dunlop"], "productKinds": ["tire"], "fetchDetails": true, "maxItems": 100 }` and filters the rows by `rimInches`.

### Limits and responsible use of MotoSport data

The actor reads public product pages without logging in, one request at a time at about five requests per second at most, and slows down if the store answers with a block signal. It follows the `robots.txt` of the site and does not read the store search or the checkout. The terms of use of motosport.com restrict automated data collection, so check that your use is allowed before you rely on the data. The actor collects public product data only, no personal data.

- **Store pages that need a browser are not read.** Ride and category pages such as `/motorcycle/...` are served only to a full browser, so they cannot be used as addresses. Use product, brand and OEM part addresses, or the catalog mode.
- **Search words are checked, not searched.** The store search is not used. In brand and lookup mode the words must appear in the brand or product name of each row. In catalog mode the list is first narrowed by words in the product address (a product named "Michelin" is found for "michelin"), so a product whose address lacks the word can be missed. Tires are found in the catalog by the word tire in the address.
- **Narrow filters read many pages.** A catalog scan reads about 1 product page per second at 256 MB and about 3 per second at 1024 MB of memory. **Maximum scan time** (default 1800 seconds) stops the run and keeps the rows found. Filters on stock, sale, category, vehicle or tires need the product page, so use brand mode when you know the brand.
- **Vehicle filters read the fitment list** of each product, one more request per product. OEM fitment is read from the part page, aftermarket fitment only for products that ask for a vehicle.
- Listing-level rows (brand mode without the full page) cannot tell a tire from other parts, so their `vehicleType` is `part`. Use **Product kinds** or **Read each product page (slower)** to get tire rows.
- Photos and descriptions belong to MotoSport and its brands; you are responsible for how you use them. Reviewer names are never read, only the rating and review count.
- Free Apify plans are limited to 10 results per run.

### Frequently Asked Questions

#### Can I scrape MotoSport prices and stock?

Yes. Every product row has the USD price (lowest and highest variant), the list price and discount when on sale, the in-stock flag and, for many variants, the quantity left. Run it on a schedule with the monitor on to track changes.

#### Can I get MotoSport tires by size?

Yes. Tire products are returned as one row per size, with `tireSize` as printed (for example `130/80-17` or `26x11-12`) and numeric width, aspect ratio, rim diameter and construction. Choose **Product kinds** tire in brand or catalog mode.

#### How do I get OEM part numbers and the vehicles they fit?

Give part numbers or OEM part addresses in lookup mode, or run catalog mode with the OEM section. Add **Fitments** to **What to collect** to get one row per vehicle model with years and part group.

#### Which vehicles does an aftermarket part fit?

Parts that need a vehicle on the site (tires, brakes, chains and similar) have a fitment list. Add **Fitments** to **What to collect**: each row has the make, model, model code and years. Universal parts have no list and return one free error row when you asked for their fitment.

#### Do I need a proxy, a login or an API key?

No. The store answers plain requests from Apify servers. A proxy setting exists but is off by default, and the actor does not need an account on the store.

#### Is it legal to scrape MotoSport?

The actor reads publicly visible product pages and no personal data. The terms of use of motosport.com restrict automated collection, so you are responsible for checking that your use is allowed. Contact: contact.punkrecordsdata@gmail.com.

#### How many products can I get in one run?

A brand run returns all products of the brand (Fox Racing has 1,027), 60 per listing page. A catalog run walks the 28,981 aftermarket products or the 470,246 OEM parts in order, bounded by **Maximum items** and **Maximum scan time**, and **Catalog start position** lets a later run continue where the last one stopped.

#### Why do some products have no stock information?

Products that need a vehicle to be chosen show no stock message on the page, so `available` is left out. The **In stock only** filter returns only rows with a stock answer.

#### How do I get only products on sale?

Switch on **On sale only**. The filter uses the sale and clearance flags and the list price of each product, so tires (which have no list price on the page) are not returned.

#### How do I get only new products or price changes since my last run?

Switch on **Only new items**, and add **Also return price and stock changes** to also receive products whose price or stock changed. The state is kept in your own key-value store.

#### What happens when the search finds nothing or the input is wrong?

A search with no matches ends the run with a message and no charge. A wrong address, unknown brand or unreadable page returns one free error row with the reason, and the other addresses are still processed.

### Recommended Actors

More RecordsData scrapers for vehicle markets are in the [RecordsData collection](https://apify.com/RecordsData), including classified-ad scrapers for used cars and motorcycles.

**Need help?** contact.punkrecordsdata@gmail.com. Reviews on the actor page help other people find it.

> **Disclaimer:** this is an independent tool, not affiliated with MotoSport. It collects only publicly available data.

# Actor input Schema

## `mode` (type: `string`):

Lookup reads the product pages, OEM part numbers and brand pages you list in Addresses and Part numbers. Brand reads every product of the brands you list in Brands. Catalog scans the whole store in sitemap order (about 29,000 aftermarket products or about 500,000 OEM parts) and keeps what passes your filters.

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

Used in lookup mode. Product pages (motosport.com/dunlop-american-elite-front-tire), OEM part pages (motosport.com/oem-parts/part-number/704900813) or brand pages (motosport.com/fox-racing). A bare product slug works too. Pages that the site only serves to a full browser (the /motorcycle/, /atv/ or /dirtbike/ storefront pages) return a free error row.

## `partNumbers` (type: `array`):

Used in lookup mode. Manufacturer part numbers of the OEM catalog, for example 704900813 or 23461-166-600. A number the store does not carry returns a free error row.

## `brands` (type: `array`):

Used in brand mode, and as a filter on the brand of each row in the other modes. A name (Fox Racing), the store slug (fox-racing) or the address (motosport.com/fox-racing). An unknown brand returns a free error row with close matches.

## `recordTypes` (type: `array`):

Products (one row per aftermarket or OEM part, and one row per tire size), fitments (one row per part and vehicle model it fits) and brands (one row per brand with its product count, riding styles and product lines). Several choices are read in the order listed here.

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

Stops after this many rows (all record types together). Free plans are limited to 10 items per run.

## `searchQueries` (type: `array`):

Optional. Words to look for, for example dunlop tire, 120/70-17 or fox gloves. Every word of one text must appear (any order, case ignored; numbers match as whole numbers) in the brand or product name; a row passes when any of the texts matches. In catalog mode the list is first narrowed by the words in each product address, then confirmed on the product page.

## `productKinds` (type: `array`):

Optional. Keep only aftermarket parts and gear, tires (one row per size) or OEM parts. Empty keeps all kinds the source holds. In catalog mode, tires are found by the word tire in the product address.

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

Optional. Words of the product category the store assigns, for example Helmets, Gloves, Tire, Brakes. A product passes when its category or category path contains the word. Needs the product page, so brand mode reads each page.

## `minPrice` (type: `number`):

Optional. Lowest price in US dollars. A product with several prices passes when its price range overlaps the wanted range.

## `maxPrice` (type: `number`):

Optional. Highest price in US dollars.

## `inStockOnly` (type: `boolean`):

Skips products and tire sizes the store shows as out of stock. Needs the product page.

## `onSaleOnly` (type: `boolean`):

Keeps only products with a reduced price (a list price above the selling price). Needs the product page.

## `vehicleMake` (type: `string`):

Optional. Only parts the store lists for this vehicle make, for example Honda, Yamaha, Polaris, Can-Am, KTM. Parts without a published fitment list are left out. Needs one extra request per product.

## `vehicleModel` (type: `string`):

Optional. Only parts listed for this model, for example CRF450R, Ranger 570 or YZ250F. Best together with the make.

## `vehicleYear` (type: `integer`):

Optional. Only parts listed for this model year, for example 2022.

## `catalogSection` (type: `string`):

Used in catalog mode. Aftermarket reads the aftermarket product pages (parts, tires, gear). OEM reads the manufacturer part pages by part number.

## `catalogOffset` (type: `integer`):

Used in catalog mode. Skips this many entries of the sitemap before reading, so a later run can continue where an earlier run stopped.

## `includeDescription` (type: `boolean`):

Adds the product description as plain text. Turn it off for smaller rows.

## `fetchDetails` (type: `boolean`):

In brand mode the listing already gives title, brand, price range and rating. Turn this on to read every product page for stock, sizes, part numbers and description. Each product costs about 1 second more.

## `onlyNew` (type: `boolean`):

Skips every item seen in an earlier run with the same filters and monitor name, so scheduled runs return only what is new and you pay only for those.

## `trackPriceChanges` (type: `boolean`):

With only new items on, a product already seen comes back when its price or stock changed, with the previous price, the change and a price-drop, price-increase, out-of-stock or back-in-stock label.

## `stateKey` (type: `string`):

Name of the memory used by only new items. Use one name per saved search. Empty derives a name from your filters.

## `resetSeen` (type: `boolean`):

Clears the memory of this monitor before the run, so everything counts as new again.

## `concurrency` (type: `integer`):

How many product pages are read at the same time. The default is safe; the actor also paces every request.

## `maxScanSeconds` (type: `integer`):

Stops reading after this time and keeps the rows found so far. A catalog scan reads about 1 product page per second at 256 MB of memory (about 3 per second at 1024 MB), so 30 minutes cover about 2,000 products at 256 MB.

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

Optional. Empty means direct requests, which work. Add a proxy only if your own network needs one.

## Actor input object example

```json
{
  "mode": "lookup",
  "startUrls": [
    "https://www.motosport.com/dunlop-american-elite-front-tire",
    "https://www.motosport.com/oem-parts/part-number/704900813"
  ],
  "recordTypes": [
    "products"
  ],
  "maxItems": 10,
  "inStockOnly": false,
  "onSaleOnly": false,
  "vehicleMake": "",
  "vehicleModel": "",
  "catalogSection": "aftermarket",
  "catalogOffset": 0,
  "includeDescription": true,
  "fetchDetails": false,
  "onlyNew": false,
  "trackPriceChanges": false,
  "stateKey": "",
  "resetSeen": false,
  "concurrency": 3,
  "maxScanSeconds": 1800,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Key fields per row

## `fullData` (type: `string`):

Complete dataset with all fields

# 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 = {
    "mode": "lookup",
    "startUrls": [
        "https://www.motosport.com/dunlop-american-elite-front-tire",
        "https://www.motosport.com/oem-parts/part-number/704900813"
    ],
    "recordTypes": [
        "products"
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("recordsdata/motosport-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 = {
    "mode": "lookup",
    "startUrls": [
        "https://www.motosport.com/dunlop-american-elite-front-tire",
        "https://www.motosport.com/oem-parts/part-number/704900813",
    ],
    "recordTypes": ["products"],
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("recordsdata/motosport-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 '{
  "mode": "lookup",
  "startUrls": [
    "https://www.motosport.com/dunlop-american-elite-front-tire",
    "https://www.motosport.com/oem-parts/part-number/704900813"
  ],
  "recordTypes": [
    "products"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call recordsdata/motosport-scraper --silent --output-dataset

```

## MCP server setup

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