# CarGurus Scraper (`memo23/cargurus-scraper`) Actor

Scrape CarGurus.com and CarGurus.ca car listings by US ZIP, Canadian postal code or search URL. Filter by make, model, price, year, mileage and deal rating. Each row has price, deal rating, days on market, VIN, mileage, dealer, phone and photos. Big searches are split into price bands.

- **URL**: https://apify.com/memo23/cargurus-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** E-commerce, Lead generation, AI
- **Stats:** 1 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. 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

## CarGurus Scraper 🚗

Extract vehicle listings from **CarGurus.com** and **CarGurus.ca** at scale — fast, clean, and complete. Search by
any US ZIP code or Canadian postal code, narrow by **make, model, price, year, mileage and deal rating**, or paste any
CarGurus search URL, and get structured data for every car: price, **CarGurus deal rating and
deal score**, expected price vs. listing price, price drops, days on market, VIN, dealer
name/city/phone, and the full photo gallery. Works for used inventory across every make and model.

#### How it works

![How the CarGurus Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-cargurus.png)

***

#### ✨ Why use this scraper?

- **Filters applied by CarGurus, then checked again** — make, model, price, year, mileage and deal rating go to CarGurus as search filters, so only matching cars are fetched. Each row is then held to your exact ranges, so you never pay for a $14,748 car in a $15,000–30,000 search.
- **US and Canada in one actor** — a US ZIP searches cargurus.com, a Canadian postal code searches cargurus.ca, and both can go in the same run. Every row says which `country` and `currency` it came from.
- **Paste any CarGurus search URL** — set filters on cargurus.com or cargurus.ca (body style, color, fuel, anything), copy the URL, and the actor keeps them all.
- **Past CarGurus' ~8,700-per-search ceiling** — a search bigger than that is split into price bands automatically, each with its own reach. One test run pulled 12,000 unique cars from a single Boston search, still in price order.
- **Price drops on every row** — `originalPrice`, `priceDropAmount` and `lastPriceDropAt`, plus `totalPrice` (with dealer fees) and `msrp` where CarGurus has them.
- **Deal rating on every row** — CarGurus' signature `dealRating` (`GREAT_PRICE`, `GOOD_PRICE`, `FAIR_PRICE`, …) plus the numeric `dealScore` (lower is a better deal), so you can rank the market by value.
- **Price analysis built in** — `expectedPrice` and `priceDifferential` show what CarGurus thinks a car *should* cost vs. what it's listed for, on every row.
- **VIN and stock number** — every listing carries the VIN and dealer stock number, ready for cross-referencing with Carfax, autocheck, or your own inventory.
- **Dealer contact** — dealer name, city, state or province, ZIP or postal code, and phone number on every row, no extra fetches.
- **Full photo gallery** — the complete carousel (often 20–40 images per car), not just the cover shot.
- **No browser, no DataDome wall** — reads CarGurus' own mobile-gateway JSON API, so runs are quick (about 1,000 listings in 30 seconds) and don't break when the site redesigns.
- **Organic results only by default** — paid Featured / Priority / Highlight placements are left out so your sort order holds; switch `includeSponsored` on to keep them, flagged with `isSponsored`.
- **Re-runnable & schedulable** — stable listing IDs make change-tracking across runs easy.

***

#### 🎯 Use cases

| Audience | What they get |
|---|---|
| **Dealers & inventory analysts** | Monitor competitor inventory, pricing, and how long cars sit on the market (`daysOnMarket`). |
| **Car flippers & resellers** | Surface underpriced cars by `dealRating` and `priceDifferential` — the listings CarGurus itself flags as good deals. |
| **Market researchers** | Track price trends and depreciation by make / model / ZIP using the built-in expected-price analysis. |
| **Lead-gen teams** | Build dealer contact lists with name, city, and phone number. |
| **VIN-based services** | Feed a Carfax/autocheck pipeline or inventory match tool with VIN + stock number per car. |
| **App & AI builders** | Power a car-shopping app, comparison tool, or AI agent with clean, photo-complete listings. |
| **Data / BI teams** | Feed a warehouse or pipeline with consistent records and stable IDs. |

***

#### 📥 Supported inputs

| Input | Example | Supported |
|---|---|---|
| US ZIP code | `"02116"` — searches cargurus.com within `distance` miles of that ZIP | ✅ |
| Canadian postal code | `"M5V 3L9"` or `"M5V3L9"` — searches cargurus.ca around that postal code | ✅ |
| Several codes in one run | `["02116", "90210", "V6B 1A1"]` — searched in parallel, results deduped; US and Canada can be mixed | ✅ |
| Search radius | `distance: 50` (1–500 miles; converted to km for Canada) | ✅ |
| Make / model | `makes: ["Toyota"]`, `models: ["Camry", "RAV4"]` or `models: ["Ford F-150"]` | ✅ |
| Price / year / mileage ranges | `minPrice`, `maxPrice`, `minYear`, `maxYear`, `minMileage`, `maxMileage` | ✅ |
| Deal rating | `dealRatings: ["GREAT_PRICE", "GOOD_PRICE"]` | ✅ |
| CarGurus search URL | `https://www.cargurus.com/search?zip=02116&makeModelTrimPaths=m7…` | ✅ |
| CarGurus Canada search URL | `https://www.cargurus.ca/search?zip=H2X1Y4&makeModelTrimPaths=m6…` | ✅ |
| Older CarGurus URLs | `/Cars/l-Used-Toyota-Camry-d292`, `…/viewDetailsFilterViewInventoryListing.action?…` | ✅ |
| Sort order | `BEST_MATCH`, `BEST_DEAL`, `PRICE_LOWEST`, `PRICE_HIGHEST`, `MILEAGE_LOWEST`, `MILEAGE_HIGHEST`, `YEAR_NEWEST`, `LISTED_NEWEST`, `LISTED_OLDEST` | ✅ |
| Sponsored listings | `includeSponsored: true` keeps CarGurus' paid placements | ✅ |

**Not supported:** single-listing URLs and CarGurus UK (`cargurus.co.uk`). A ZIP or postal code CarGurus does not recognise is skipped with a
warning in the log rather than silently widened to a nationwide search, and an unknown make or
model stops the run before anything is charged, with the valid names in the log.

***

#### 🔄 How it works

1. You provide **US ZIP codes or Canadian postal codes** with optional filters, or **CarGurus search URLs** from either site.
2. Make and model names are matched to CarGurus' own ids; every filter goes to CarGurus with the search.
3. The actor calls CarGurus' mobile-gateway `search/preflight` endpoint for the first page and the total listing count. A search too big for CarGurus to serve in one go is split into price bands.
4. It fetches the following result pages in parallel (21 cars per page) until `maxItems` or the end of the results, and writes them in page order so your sort order holds.
5. Listings are **de-duplicated** by listing id across searches (one row per vehicle); paid placements and any car outside your ranges are dropped and not charged.
6. Download as JSON / CSV / Excel, or pull via the Apify API.

***

#### ⚙️ Input parameters

| Field | Type | Description |
|---|---|---|
| **zips** | array | US ZIP codes or Canadian postal codes to search around (e.g. `["02116", "M5V 3L9"]`). Needed unless you paste search URLs. |
| **searchUrls** | array | cargurus.com or cargurus.ca search URLs. Each keeps its own filters and sort; the filter fields below are then ignored, and `zips` only fills in URLs from the same country that have no code. |
| **distance** | integer | Search radius in miles (1–500, default 50). Canadian searches use the same radius in km (50 miles = 80 km). |
| **sortType** | select | `BEST_MATCH` (default), `BEST_DEAL` (great deals first), `PRICE_LOWEST`, `PRICE_HIGHEST`, `MILEAGE_LOWEST`, `MILEAGE_HIGHEST`, `YEAR_NEWEST`, `LISTED_NEWEST` (just listed first), `LISTED_OLDEST` (longest on the market first). |
| **makes** | array | Makes as CarGurus spells them, e.g. `["Toyota", "Ford"]`. |
| **models** | array | Models that narrow the makes, e.g. `["Camry", "RAV4"]`, or with the make, e.g. `["Ford F-150"]`. A listed make with none of these models is searched in full. |
| **minPrice** / **maxPrice** | integer | Listing price range, in USD for US searches and CAD for Canadian ones. |
| **minYear** / **maxYear** | integer | Model year range. |
| **minMileage** / **maxMileage** | integer | Odometer range, in miles for US searches and km for Canadian ones. |
| **dealRatings** | array | Any of `GREAT_PRICE`, `GOOD_PRICE`, `FAIR_PRICE`, `POOR_PRICE`, `OVERPRICED`, `NA`. |
| **includeSponsored** | boolean | Keep CarGurus' paid Featured / Priority / Highlight placements (default `false`). They ignore the sort order and are flagged `isSponsored: true`. |
| **maxItems** | integer | Hard cap on total listings across all searches (default 1000). |
| **maxConcurrency** | integer | API calls in flight at once across all searches (default 5, max 20). |
| **proxy** | object | Optional. Leave empty to use the built-in residential proxy (it serves both sites), which switches to a backup pool on its own if it stops answering. An Apify Proxy group or your own proxy URLs are used instead when set. |

**Example — single ZIP, 50 miles, best match:**

```json
{
  "zips": ["02116"],
  "distance": 50,
  "maxItems": 500
}
```

**Example — great and good deals on recent Camrys and RAV4s under $30,000:**

```json
{
  "zips": ["02116"],
  "distance": 100,
  "makes": ["Toyota"],
  "models": ["Camry", "RAV4"],
  "maxPrice": 30000,
  "minYear": 2020,
  "dealRatings": ["GREAT_PRICE", "GOOD_PRICE"],
  "sortType": "BEST_DEAL",
  "maxItems": 500
}
```

**Example — paste searches from cargurus.com:**

```json
{
  "searchUrls": [
    "https://www.cargurus.com/search?zip=10001&distance=50&makeModelTrimPaths=m4&sortType=PRICE&sortDirection=ASC",
    "https://www.cargurus.com/Cars/l-Used-Toyota-Camry-d292"
  ],
  "zips": ["10001"],
  "maxItems": 1000
}
```

**Example — Canada: Toyota RAV4 under C$35,000 around Toronto:**

```json
{
  "zips": ["M5V 3L9"],
  "makes": ["Toyota"],
  "models": ["RAV4"],
  "maxPrice": 35000,
  "maxItems": 200
}
```

**Example — multi-ZIP sweep, cheapest first:**

```json
{
  "zips": ["02116", "10001", "60601", "90001"],
  "distance": 100,
  "sortType": "PRICE_LOWEST",
  "maxItems": 2000,
  "maxConcurrency": 5
}
```

***

#### 📊 Output overview

The dataset contains **one row per vehicle** — no padding rows. Each row is a flat, ready-to-use
object with 50+ fields: vehicle identity, pricing, price drops and deal analysis, photos, dealer details, and
search context. Fields a particular listing doesn't expose come back as `null` rather than being
dropped, so the shape is consistent across every row.

***

#### 📦 Output sample

```json
{
  "listingId": 455901436,
  "listingUrl": "https://www.cargurus.com/Cars/inventorylisting/vdp.action?listingId=455901436",
  "title": "2025 Toyota Camry",
  "year": 2025,
  "make": "Toyota",
  "model": "Camry",
  "trim": "LE FWD",
  "makeId": "m7",
  "modelId": "d292",
  "mileage": 50253,
  "mileageUnit": "MILES",
  "price": 22000,
  "currency": "USD",
  "priceString": "$22,000",
  "totalPrice": 22649,
  "msrp": 26589,
  "expectedPrice": 24119,
  "priceDifferential": 2119,
  "priceDifferentialString": "$500",
  "originalPrice": 27898,
  "priceDropAmount": 5898,
  "lastPriceDropAt": "2026-10-21T20:31:30.000Z",
  "dealScore": 0.63655204,
  "dealRating": "GREAT_PRICE",
  "daysOnMarket": 75,
  "vin": "4T1DAACK6SU527615",
  "stockNumber": "SU527615P",
  "engine": "2.5L I4 Hybrid",
  "dealerName": "Parkway Toyota of Boston",
  "dealerId": 1845167,
  "serviceProviderId": 43980,
  "dealerCity": "West Roxbury",
  "dealerState": "MA",
  "dealerPostalCode": "02132",
  "dealerPhone": "(617) 996-7757",
  "dealerPhoneSms": "+18883346545",
  "dealerLogoUrl": "https://static.cargurus.com/images/site/2021/03/24/15/44/parkway_toyota_of_boston-pic-7378117232147401432-200x200.jpeg",
  "isFranchiseDealer": true,
  "shipsNationwide": null,
  "buyingOption": "CONVERT",
  "howToShop": "PICK_UP_ONLY",
  "salesStatus": "PAYING",
  "inclusionType": "DEFAULT",
  "listingType": "STANDARD",
  "isSponsored": false,
  "distanceMiles": 7.5,
  "distanceKm": 12.1,
  "photoUrl": "https://static.cargurus.com/images/forsale/2026/08/18/05/38/2025_toyota_camry-pic-9161416002660190316-1024x768.jpeg",
  "photoCount": 22,
  "photos": [
    "https://static.cargurus.com/images/forsale/2026/08/18/05/38/2025_toyota_camry-pic-9161416002660190316-1024x768.jpeg",
    "https://static.cargurus.com/images/forsale/2026/08/19/08/15/2025_toyota_camry-pic-3794118653049133111-1024x768.jpeg"
  ],
  "country": "US",
  "searchedZip": "02116",
  "searchUrl": null,
  "scrapedAt": "2026-10-26T20:47:46.196Z"
}
```

***

#### 🗂 Key output fields

| Group | Fields |
|---|---|
| **Vehicle** | `listingId`, `listingUrl`, `title`, `year`, `make`, `model`, `trim`, `makeId`, `modelId`, `vin`, `stockNumber`, `engine` |
| **Pricing** | `price`, `currency` (`USD` or `CAD`), `priceString`, `totalPrice` (with dealer fees), `msrp`, `expectedPrice`, `priceDifferential`, `priceDifferentialString`, `dealScore`, `dealRating`, `daysOnMarket` |
| **Price drops** | `originalPrice`, `priceDropAmount`, `lastPriceDropAt` (null when the price never dropped) |
| **Mileage** | `mileage`, `mileageUnit` (`MILES` in the US, `KILOMETERS` in Canada), `distanceMiles` and `distanceKm` (distance from the searched code) |
| **Dealer** | `dealerName`, `dealerId`, `serviceProviderId`, `dealerCity`, `dealerState`, `dealerPostalCode`, `dealerPhone`, `dealerPhoneSms`, `dealerLogoUrl`, `isFranchiseDealer`, `shipsNationwide`, `buyingOption`, `howToShop`, `salesStatus` |
| **Photos** | `photoUrl`, `photoCount`, `photos[]` (full carousel) |
| **Meta** | `inclusionType`, `listingType` (`STANDARD`, or `FEATURED` / `PRIORITY` / `HIGHLIGHT` for paid placements), `isSponsored`, `country` (`US` or `CA`), `searchedZip` (the ZIP or postal code searched), `searchUrl` (the pasted URL a row came from, else null), `scrapedAt` |

***

#### ❓ FAQ

**Can I scrape a specific make / model / price range?**
Yes. Use `makes`, `models`, the price / year / mileage ranges and `dealRatings`, or set any filter
on cargurus.com and paste the URL into `searchUrls`. Filters run on CarGurus' side, so you only
pay for matching cars.

**Do I get every photo?**
Yes — the full carousel (often 20–40 images) is returned in `photos[]`, with the cover shot in
`photoUrl`.

**Used cars, new cars, or both?**
The mobile-gateway search path returns used inventory. New-car inventory is not on this path.

**How do I get results faster / cheaper?**
Raise `maxConcurrency` (up to 20), lower `maxItems`, or narrow `distance`. At the default settings a
1,000-listing run takes about 30 seconds; 3,000 listings across three ZIPs at concurrency 10 took
under a minute in our tests.

**How many listings can one search return?**
CarGurus stops serving a single search after about 8,700 listings, even when it counts far more.
When your `maxItems` asks for more than that, the actor splits the search into price bands and
reads each one, so a big market can be swept in one run. CarGurus also serves somewhat fewer cars
than its counter shows (about 87% in our tests), so expect totals a bit under the site's number.

**Is there a limit on the free plan?**
Free-plan runs return up to 100 listings. Paid plans have no cap beyond your own `maxItems`.

**Is the dealer phone number included?**
Yes — `dealerPhone` (display format) and `dealerPhoneSms` (click-to-text) are on every row at no
extra cost, straight from the listing tile.

**What is `dealRating`?**
CarGurus' own value verdict: `GREAT_PRICE`, `GOOD_PRICE`, `FAIR_PRICE`, `POOR_PRICE`
(shown as "High price" on the site), `OVERPRICED`, or `NA` / `OUTLIER` when it has no estimate. It's computed by CarGurus from the car's price vs. similar listings, so you don't
have to. `dealScore` is the numeric version, and lower is better: under 1 is a great price, 1–2 a good
price, 2–3 a fair price.

**What is `expectedPrice`?**
What CarGurus' model thinks the car *should* sell for. `priceDifferential` is `expectedPrice -
price`: positive means the car is listed below what CarGurus expects (a potential deal), negative
means above. `priceDifferentialString` is the text CarGurus shows in its app and does not always
match the exact difference.

**Can I search Canada or the UK?**
Canada yes: put a Canadian postal code in `zips` (e.g. `"M5V 3L9"`) or paste a cargurus.ca search
URL. Prices come back in CAD and mileage in km, and each row has `country: "CA"`. Price and mileage
filters for Canadian searches are in CAD and km. The UK site (`cargurus.co.uk`) is not supported.

***

#### 💬 Support

Questions, a bug, or a field you need added? Email **muhameddidovic@gmail.com** or open an issue
on the actor's Apify page.

***

#### 🛠 Additional services

Need a custom scraper, a different car marketplace, or this data delivered to your database / API
on a schedule? I build bespoke scraping and data pipelines — get in touch at
**muhameddidovic@gmail.com**.

***

#### 🔎 Explore more scrapers

Looking for other car marketplaces or directory sites? Check out my other Apify actors —
[Cars.com](https://apify.com/memo23/cars-scraper),
[AutoTrader.com](https://apify.com/memo23/autotrader-com-scraper),
[AutoScout24](https://apify.com/memo23/autoscout24-scraper), and more — or request a new target.

***

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/cargurus-scraper`).

**Purpose:** Extract CarGurus.com (US) and CarGurus.ca (Canada) used-vehicle listings by ZIP or postal code, with price, deal rating, VIN, dealer contact, and the full photo gallery per car.

**Minimal input:**

```json
{
  "zips": ["02116"],
  "distance": 50,
  "maxItems": 20
}
```

**Output:** one row per vehicle — listingId, listingUrl, title, year, make, model, trim, makeId, modelId, mileage, mileageUnit, price, currency, priceString, totalPrice, msrp, expectedPrice, priceDifferential, priceDifferentialString, originalPrice, priceDropAmount, lastPriceDropAt, dealScore, dealRating, daysOnMarket, vin, stockNumber, engine, dealerName, dealerId, serviceProviderId, dealerCity, dealerState, dealerPostalCode, dealerPhone, dealerPhoneSms, dealerLogoUrl, isFranchiseDealer, shipsNationwide, buyingOption, howToShop, salesStatus, inclusionType, listingType, isSponsored, distanceMiles, distanceKm, photoUrl, photoCount, photos \[], country, searchedZip, searchUrl, scrapedAt.

**Behaviors an agent should know:**

- `zips` is an array of US ZIP codes and/or Canadian postal codes (needed unless `searchUrls` is set); a ZIP searches cargurus.com, a postal code cargurus.ca. Codes run in parallel and results are deduped by `listingId`.
- `distance` (1–500 miles, default 50) is the search radius around each code; Canadian searches convert it to km.
- Canadian rows have `country: "CA"`, `currency: "CAD"` and mileage in km; price and mileage filters apply in those units.
- `maxItems` (default 1000) caps total listings across all ZIPs — set it low (≤ 50) for quick, cheap runs.
- `maxConcurrency` (default 5, max 20) controls API parallelism across all ZIPs.
- `sortType` orders results: `BEST_MATCH` (default), `BEST_DEAL`, `PRICE_LOWEST`, `PRICE_HIGHEST`, `MILEAGE_LOWEST`, `MILEAGE_HIGHEST`, `YEAR_NEWEST`, `LISTED_NEWEST`, `LISTED_OLDEST`.
- Paid placements are excluded unless `includeSponsored: true`; then they carry `isSponsored: true`.
- `makes` / `models` / `minPrice` / `maxPrice` / `minYear` / `maxYear` / `minMileage` / `maxMileage` / `dealRatings` filter on CarGurus' side and are re-checked per row. Unknown make or model names fail the run up front.
- `searchUrls` takes cargurus.com or cargurus.ca search URLs with their own filters (filter fields are then ignored).
- Searches over ~8,700 listings are split into price bands automatically when `maxItems` needs more. Unknown ZIPs are skipped.
- `dealScore`: lower is a better deal. `priceDifferential` = `expectedPrice - price` (positive = below expected).
- Free-plan runs return at most 100 listings.
- US and Canada only — no UK (`cargurus.co.uk`) support.
- Used inventory only; new-car inventory is not on this path.
- No detail-page fetch — every field above comes from the search tile, so cost is one API call per ~21 listings.
- Pay-per-event billing — see the Pricing tab on the actor page.

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by
CarGurus, Inc. or any of its subsidiaries or affiliates. All trademarks mentioned are the
property of their respective owners.

The scraper accesses only publicly available vehicle-listing data via CarGurus' mobile-gateway
API — no authenticated endpoints, account-only features, or content behind a CarGurus login.
Users are responsible for ensuring their use complies with CarGurus' Terms of Service, applicable
data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organisation.

***

### SEO Keywords

cargurus scraper, scrape cargurus, cargurus canada scraper, cargurus.ca scraper, cargurus api, cargurus make model filter, cargurus search url scraper, cargurus price drop tracker, apify cargurus, car listings scraper, used car scraper, vehicle data api, car inventory scraper, vin scraper, dealer inventory data, cargurus deal rating scraper, automotive market data, car dealership scraper, vehicle listings extractor, used car market data, car flipping data, car price tracker, cargurus alternative scraper, car photos scraper, deal score scraper, expected price car data

# Actor input Schema

## `zips` (type: `array`):

US ZIP codes or Canadian postal codes to search around, e.g. \["02116", "M5V 3L9"]. A US ZIP searches cargurus.com, a postal code cargurus.ca. Each code is a separate search; listings found under several are written once. With search URLs below, codes are only used for URLs from the same country that have none.

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

Optional. Paste search result URLs from cargurus.com or cargurus.ca after setting filters on the site (make, model, price, body style, anything). Each URL keeps its own filters and sort; the filter fields below are then ignored. Single-listing URLs and cargurus.co.uk are not supported.

## `distance` (type: `integer`):

Radius around each ZIP or postal code in miles. Canadian searches convert it to km (50 miles = 80 km).

## `sortType` (type: `string`):

How CarGurus orders the results.

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

Car makes as CarGurus spells them, e.g. \["Toyota", "Ford"]. Leave empty for all makes.

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

Models to narrow the makes to, e.g. \["Camry", "RAV4"], or with the make, e.g. \["Ford F-150"]. A make with none of these models is searched in full. An unknown name stops the run before anything is charged and the log lists the valid ones.

## `minPrice` (type: `integer`):

Lowest listing price to include, in USD for US searches and CAD for Canadian ones.

## `maxPrice` (type: `integer`):

Highest listing price to include, in USD for US searches and CAD for Canadian ones.

## `minYear` (type: `integer`):

Earliest model year to include, e.g. 2018.

## `maxYear` (type: `integer`):

Latest model year to include.

## `minMileage` (type: `integer`):

Lowest odometer reading to include, in miles for US searches and km for Canadian ones.

## `maxMileage` (type: `integer`):

Highest odometer reading to include, in miles for US searches and km for Canadian ones.

## `dealRatings` (type: `array`):

Only include cars with these CarGurus deal ratings. Leave empty for all.

## `includeSponsored` (type: `boolean`):

CarGurus puts up to 4 paid (Featured / Priority) listings at the top of the first results page. They ignore the sort order. Turn this on to keep them; each is flagged with isSponsored: true.

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

Hard cap on the number of listings collected across all searches. A search bigger than CarGurus serves in one go (about 8,700 listings) is split into price bands automatically.

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

Maximum number of API calls in flight at once. The gateway is unauthenticated — keep this modest.

## `proxy` (type: `object`):

Optional. Leave empty to use the built-in residential proxy (recommended; it serves both sites). An Apify Proxy group or your own proxy URLs set here are used instead.

## Actor input object example

```json
{
  "zips": [
    "02116"
  ],
  "distance": 50,
  "sortType": "BEST_MATCH",
  "includeSponsored": false,
  "maxItems": 1000,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

All listing rows. The Overview and Dealers views pick out the most used 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 = {
    "zips": [
        "02116"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/cargurus-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 = { "zips": ["02116"] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/cargurus-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 '{
  "zips": [
    "02116"
  ]
}' |
apify call memo23/cargurus-scraper --silent --output-dataset

```

## MCP server setup

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