Cars.com Scraper - Vehicles, Prices, Dealers & Deals avatar

Cars.com Scraper - Vehicles, Prices, Dealers & Deals

Pricing

from $1.00 / 1,000 vehicle results

Go to Apify Store
Cars.com Scraper - Vehicles, Prices, Dealers & Deals

Cars.com Scraper - Vehicles, Prices, Dealers & Deals

Scrape cars.com listings by make, ZIP and radius. 90+ fields per car: price, MSRP, monthly payment, mileage, VIN, deal rating, price drop, photos, dealer name, rating and location. Search and URL modes, 11 sort orders, price/year/mileage filters, optional CARFAX flags and dealer phone.

Pricing

from $1.00 / 1,000 vehicle results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

20

Total users

6

Monthly active users

7 days ago

Last modified

Share

Cars.com Scraper: Prices, Deals, Mileage, VIN & Dealer Data

Cars.com Scraper turns cars.com into a clean vehicle data feed. Search by make, ZIP and radius, or paste any cars.com search or vehicle URL, and get a normalized record per car with price, MSRP, estimated monthly payment, deal rating, mileage, VIN, the primary photo, gallery thumbnails and photo count, and the dealer's name, rating and location. Two modes (search and URL), 11 sort orders, and price, year, mileage and stock-type filters. An optional detail pass adds interior color, transmission, the full equipment list, price history and the dealer phone number. Export to JSON, CSV or Excel, or pull results straight into your app through the API.

Why This Scraper?

  • Two ways in. Build searches from makes, ZIP and filters, or paste cars.com search and vehicle URLs directly. Filter fields are ignored in URL mode, so pasted links are used exactly as given.
  • 90+ fields per vehicle, including deal rating, price versus market explanation, price drop, monthly payment estimate and photo count.
  • A normalized contract on every row. Price and currency, mileage and unit, dealer city, state and ZIP, ISO dates, and a NEW, USED or CERTIFIED condition, so you never parse a display string like "$2.6K" or "17,417 mi." yourself.
  • Explicit detail status on every row. Every vehicle carries a detailLoaded / detailError pair, so you can tell an enriched row from a base row without guessing from null fields.
  • Optional detail enrichment adds full specifications, the equipment list, seller type, price history with the original list price and days on market, ownership, title, accident and recall flags, and the dealer phone number.
  • 11 sort orders and price, year, mileage and stock-type filters to narrow a search before you pay for results.
  • Built for schedules. Incremental mode returns only new and changed listings on recurring runs, and a blocked connection is reported in the run's status message instead of looking like an empty search.

Use Cases

  • Dealer and inventory monitoring: track price drops, days on market and deal ratings across your own or a competitor's stock.
  • Car shopping and deal-finding tools: filter by price, year, mileage and stock type to power a search site or alert bot.
  • Market and pricing research: build historical datasets of asking prices, MSRP and market-average deltas across makes, models and regions.
  • Lead generation: collect dealer names, ratings, phone numbers and inventory details across a defined market.
  • Vehicle history and condition analysis: pull ownership, accident and title flags alongside price and mileage for due diligence.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
listingId00000000-0000-4000-8000-000000000001
vin1FAKEVIN000000001
year / make / model / trim2025 / Toyota / Crown / Limited
vehicleConditionCERTIFIED (also NEW, USED)
priceAmount / priceCurrency39298 / USD
msrpAmount40985 (null when the seller does not publish one)
mileageValue / mileageUnit17417 / mi
priceDropAmount2692 (only on listings with a recent price drop)
dealDeltaAmount-805 (negative means priced below the local market average; only on listings the site rates a great deal)
dealerNameExample Toyota of Springfield
dealerCity / dealerState / dealerZipIrvine / CA / 92618
dealerDistanceMiles10 (miles from your search ZIP; null in URL mode)
isShippable / shippingNotefalse / null
imageUrl / imageCounthttps://platform.cstatic-images.com/large/in/v2/example.jpg / 24
urlhttps://www.cars.com/vehicledetail/00000000-0000-4000-8000-000000000001/
detailLoaded / detailErrortrue / null
stockNumberSTK0001 (Fetch full details only)
daysOnMarket10 (Fetch full details only)
scrapedAt2026-09-13T12:00:00+00:00
changeTypeNEW (Incremental mode only; also UPDATED, UNCHANGED, REAPPEARED, EXPIRED)

With Fetch full details on, each row also gets sellerType (DEALER or PRIVATE), dealer_phone, engine, transmission, interior_color, doors, cylinders, mpg_city and mpg_highway, features (the full published equipment list), priceHistory (one entry per published price change, oldest first), originalListPrice and priceBelowOriginalAmount, and vehicleHistory (oneOwner, cleanTitle, noAccidents, serviceRecords, openRecall, personalUseOnly, reportSource). These keys are present on every row and stay null when detail enrichment is off, so the row shape never changes between runs. cars.com does not publish per-vehicle coordinates, so this actor does not return a latitude and longitude pair either; use dealerZip, which is present on every row, to geocode instead.

How to Use

  1. Pick a mode: search (build from makes, ZIP and filters) or url (paste cars.com search or vehicle links).
  2. In search mode, set Makes, ZIP code and Search radius, then narrow with Stock type, price, year or mileage filters as needed. In url mode, paste one or more links; the filter fields are ignored. If you switch to url mode and leave the URLs field untouched, the run scrapes the three example links (one search-results page, one make page and one vehicle page), so clear it first to scrape only your own links.
  3. Turn on Fetch full details if you need interior color, transmission, the equipment list, price history or the dealer phone number. It adds a small charge per vehicle.
  4. Set Max items to control run size and cost, then click Start.

Search by make and ZIP:

{
"mode": "search",
"makes": ["toyota"],
"zip": "90001",
"maximumDistance": 50,
"stockType": "used",
"sortBy": "list_price",
"maxItems": 50
}

Filter by price, year and mileage:

{
"mode": "search",
"makes": ["honda", "kia"],
"zip": "10001",
"priceMin": 15000,
"priceMax": 28000,
"yearMin": 2020,
"mileageMax": 40000,
"maxItems": 100
}

Supported URL shapes (url mode):

ShapeExample
Search results (filtered)https://www.cars.com/shopping/results/?stock_type=used&makes[]=toyota&zip=90001&maximum_distance=50
Category, make and condition pageshttps://www.cars.com/shopping/suv/, https://www.cars.com/shopping/toyota/, https://www.cars.com/shopping/new/, https://www.cars.com/shopping/certified-preowned/ (page 2 onward works too)
Vehicle detail pagehttps://www.cars.com/vehicledetail/54b070d6-e344-46b9-9e1d-9c25007a729e/

Any other link (dealer pages, research pages, the old for-sale search address, other sites) is skipped and the run log shows a warning naming the link. If none of your links can be scraped, or the list is empty, the run ends as failed with a message saying so, never as a successful run with no items. A vehicle link stops working once that car is sold.

Each row's source_context records which start produced it: seed_type is location (search mode with a ZIP), search (search mode by make or all makes) or url (a pasted link), seed_value is the ZIP, make or pasted link, and seed_id is a short stable hash of seed_value.

Paste cars.com URLs (filters ignored):

{
"mode": "url",
"urls": [
"https://www.cars.com/shopping/results/?stock_type=used&makes[]=tesla&zip=94103&maximum_distance=100"
],
"fetchDetails": true,
"maxItems": 80
}

Recurring monitoring of the same search:

{
"mode": "search",
"makes": ["toyota"],
"zip": "90001",
"maximumDistance": 50,
"incrementalMode": true,
"maxItems": 500
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/cars-com-scraper").call(run_input={
"mode": "search", "makes": ["toyota"], "zip": "90001", "maxItems": 50
})
for vehicle in client.dataset(run["defaultDatasetId"]).iterate_items():
print(vehicle["listingId"], vehicle["priceAmount"], vehicle["priceCurrency"], vehicle["mileageValue"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/cars-com-scraper').call({ mode: 'search', makes: ['toyota'], zip: '90001', maxItems: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips every listing already collected there, so you do not pay twice.
  • Incremental mode (incrementalMode) is for scheduled runs over the same search. The first run returns every listing as NEW. Later runs compare against the saved state: changed listings return UPDATED (with changedFields naming exactly what moved), and unchanged listings are suppressed and not billed unless emitUnchanged is on. EXPIRED is opt-in via emitExpired and is only produced once a run has scanned the tracked search all the way to the end, never when Max items or Max pages capped it, and never on a resumed run. REAPPEARED only happens to a listing a previous run already marked EXPIRED: if it is found again later, it comes back as REAPPEARED instead of NEW, keeping its original firstSeenAt. What is compared: every returned vehicle field (price, mileage, dealer, badges, photos, price history, features and the rest); a listing is UPDATED when any of them moves. Never compared: scrape timestamps, search-level metadata (total results, search instance id), ad-tracking blobs, days on market (it ticks up daily) and the detail-fetch status flags; they are still returned in the output. Use ignoreFieldsForChanges to add your own noisy fields: a name matches that field at any depth (for example galleryImages or badges), and a dotted path such as dealer.rating matches one exact nested field. Changing the ignore list never causes a one-time wave of UPDATED rows. Likewise, version 1.1.7 now fills the source_context start details, dealer, rating, location, price text, monthly payment, badges, deal and price-drop notes, photos and similar card fields that earlier versions returned empty on some pages; for a search you already track, that empty-to-filled fill is applied silently once (the listing stays UNCHANGED and is not billed), while a later change to any of those values, or any other field, still returns UPDATED. stateKey names or shares one monitoring campaign; leave it empty and the actor derives one from your search and filter settings. With Incremental mode off, output is exactly as before.

Send results into your apps (MCP connectors)

Optionally pipe each run's results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape; the Apify dataset is never changed, and a connector failure never fails the run.

What gets written to the connector: a condensed, human-readable summary of each vehicle, not the full JSON. Each item becomes one entry with a title and its key fields (price, mileage, VIN, body style, stock type, dealer, dealer rating, location, URL) flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify, Settings, API & Integrations (Notion, Linear, Airtable or Apify).
  2. Select it in the mcpConnectors input field. Notion gets a rich page created per vehicle; other connectors get a best-effort write or digest.
  3. For Notion, also set notionParentPageUrl to the page under which vehicle pages are created.

maxNotifyListings caps how many items are sent to each connector per run. Leave mcpConnectors empty to skip connector export entirely.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch (build from makes, ZIP and filters) or url (use pasted cars.com URLs).
makesarray["tesla"]Vehicle makes to search; each make is scraped as its own search. An empty array searches all makes.
modelsarraynoneOptional model names to narrow the search, applied across the selected makes.
zipstringnone (prefill: 90001)US ZIP code to center the search on. Leave empty for a nationwide search.
maximumDistanceinteger50Search radius in miles around the ZIP.
stockTypestringallall, used, new, or cpo (certified pre-owned).
priceMinintegernoneMinimum price (USD).
priceMaxintegernoneMaximum price (USD).
yearMinintegernoneMinimum model year.
yearMaxintegernoneMaximum model year.
mileageMaxintegernoneMaximum odometer reading.
sortBystringbest_match_descOne of 11 sort orders (price, mileage, year, distance, best deal, newest).
urlsarraythree example links (a search, a make page, a vehicle)cars.com search or vehicle detail URLs (url mode). Filter fields above are ignored in this mode.
fetchDetailsbooleanfalseVisit each vehicle page for interior color, transmission, fuel type, ownership/title/accident flags and the dealer phone number. Adds a small per-vehicle charge.
maxItemsinteger20Stop after collecting this many vehicles, across all searches or URLs. 0 = unlimited.
maxPagesintegernone (an internal safety bound of 1000 applies if left empty)Optional cap on result pages per search. If you set it, each search stops at this page count even before Max items is reached. Leave it empty to rely on Max items.
resumeFromRunIdstringnoneContinue one specific previous run or dataset: listings already collected there are skipped. For recurring monitoring of the same search, use Incremental mode instead.
incrementalModebooleanfalseTurn on for scheduled or recurring runs over the same search. See "Resume and recurring updates" above.
stateKeystringnoneName a monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Auto-derived from the search and filter settings when left empty.
emitUnchangedbooleanfalseAlso return (and bill) listings unchanged since the last run, marked UNCHANGED.
emitExpiredbooleanfalseAlso return (and bill) listings from a previous run no longer found, marked EXPIRED, once a run has fully scanned the search.
ignoreFieldsForChangesarraynoneField names excluded from change detection (any depth; dotted path for one nested field). They are still returned, they just never mark a listing UPDATED.
proxyobjectApify Residential, country USConnection settings.
maxResidentialMBinteger0Kept for backward compatibility with saved inputs. No longer enforced: it does not cap residential traffic. Use maxItems to bound a run.
mcpConnectorsarraynoneOptional MCP connectors to pipe results into (Notion, Linear, Airtable, Apify).
notionParentPageUrlstringnoneNotion parent page URL or id for the Notion connector.
maxNotifyListingsinteger50Cap on items written to each connector per run.

Output views.

The dataset has six views, selectable on the Output tab or with ?view=<name> through the API: Overview, Normalized contract (filled on every row), Detail enrichment (needs Fetch full details), Changes (incremental), Deals and price signals, and Vehicle specs, dealer and photos. Change columns are empty on runs without Incremental mode.

Output Example

Sample shape: values are illustrative placeholders, not from a live listing.

{
"listingId": "00000000-0000-4000-8000-000000000001",
"vin": "1FAKEVIN000000001",
"url": "https://www.cars.com/vehicledetail/00000000-0000-4000-8000-000000000001/",
"title": "2025 Toyota Crown Limited",
"year": 2025,
"make": "Toyota",
"model": "Crown",
"trim": "Limited",
"bodyStyle": "Sedan",
"mileage": 17417,
"drivetrain": "All-wheel Drive",
"fuelType": "Hybrid",
"exterior_color": "Heavy Metal",
"interior_color": "Black",
"transmission": "Automatic",
"stockType": "Used",
"cpoIndicator": true,
"price": 39298,
"msrp": 40985,
"monthlyPayment": "$599",
"price_drop": "$2.6K",
"deal_rating": "great-deal",
"deal_badge_text": "Great Deal",
"price_vs_market": "This vehicle is priced $805 below the average market price of similar vehicles in the area at $40,103.",
"dealerName": "Example Toyota of Springfield",
"dealerRating": 4.5,
"dealer_phone": "(000) 000-0000",
"location": "Irvine, CA (38 mi)",
"imageUrl": "https://platform.cstatic-images.com/large/in/v2/example.jpg",
"imageCount": 24,
"galleryImages": ["https://platform.cstatic-images.com/large/in/v2/example.jpg"],
"carfax_1_owner": true,
"carfax_clean_title": true,
"carfax_no_accidents": true,
"badges": [
{ "label": "Great Deal", "variant": "great-deal", "description": "Priced below the average market price." }
],
"vehicleCondition": "CERTIFIED",
"priceAmount": 39298,
"priceCurrency": "USD",
"msrpAmount": 40985,
"monthlyPaymentAmount": 599,
"priceDropAmount": 2692,
"marketAverageAmount": 40103,
"dealDeltaAmount": -805,
"mileageValue": 17417,
"mileageUnit": "mi",
"dealerCity": "Irvine",
"dealerState": "CA",
"dealerZip": "92618",
"dealerDistanceMiles": 38,
"isShippable": false,
"shippingNote": null,
"sellerType": "DEALER",
"stockNumber": "STK0001",
"engine": "2.5L I-4 port/direct injection",
"doors": 4,
"cylinders": 4,
"features": ["Apple CarPlay", "Backup Camera", "Heated Seats"],
"listedAt": "2026-09-03",
"daysOnMarket": 10,
"originalListPrice": 40985,
"priceBelowOriginalAmount": 1687,
"priceHistory": [
{ "date": "2026-09-03", "event": "LISTED", "changeAmount": null, "price": 40985 },
{ "date": "2026-09-09", "event": "PRICE_INCREASE", "changeAmount": 1005, "price": 41990 },
{ "date": "2026-09-10", "event": "PRICE_DROP", "changeAmount": 2692, "price": 39298 }
],
"vehicleHistory": {
"oneOwner": true,
"cleanTitle": true,
"noAccidents": true,
"serviceRecords": true,
"openRecall": false,
"personalUseOnly": true,
"reportSource": "autocheck"
},
"detailLoaded": true,
"detailError": null,
"scrapedAt": "2026-09-13T12:00:00+00:00"
}

Plan Requirement

cars.com challenges automated traffic on every connection type, including residential, so this actor does not work on a plain datacenter connection and no single proxy setting is guaranteed to pass on its own. The default Proxy setting (Apify Residential, country US) is the connection this actor is built around, and the actor handles the site's check itself on that connection. Residential proxy access is not included on Apify free plans. When the selected connection is unavailable to your account, the run log prints this notice and continues on a backup connection:

The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs.

Once a run is served over the backup connection, the log says "Served over the backup connection (the default connection was unavailable)." Some pages may still be unavailable there. If no page can be loaded the run ends as failed, never as a silent empty success, with one of these status messages:

  • Connection refused for the account: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid."
  • Residential unavailable and backup failed: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested cars.com pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again."
  • Requests failed: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."

For consistently good coverage keep Proxy on Residential with country US on a paid plan, or supply your own proxy URLs. maxResidentialMB is kept only so saved inputs still load; it does not cap traffic, so use Max items to bound a large run.

FAQ

How much does it cost?

This actor uses Apify's pay-per-event pricing. On the Free plan the rates are $0.08 per run start, $0.002 per vehicle returned, and $0.0008 per vehicle only when Fetch full details is on; paid plans get lower tiered rates. The Pricing tab always shows the current rates for your plan. Use Max items to cap the cost of any run.

This actor collects only publicly available vehicle listing data. You are responsible for how you use it: follow cars.com's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing facts such as price, mileage and VIN are generally treated differently from photos and dealer branding, which may carry their own rights.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and changed listings by default, and unchanged ones are suppressed and not billed unless you turn on Emit unchanged.

What is the difference between Resume and Incremental mode?

Resume (resumeFromRunId) continues one specific interrupted run by its run or dataset ID, a one-time action. Incremental mode remembers a recurring search on its own and classifies every listing as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against its own saved state on every scheduled run. Use Resume once, right after a run got cut off; use Incremental mode for ongoing monitoring of the same search.

Why did my run return no items?

If the connection is refused before any page can be read, the run ends as failed with a status message explaining the connection problem, so "no listings match your filters" is never confused with "the connection could not reach cars.com". Only the run-start fee is charged; no items are pushed. Check that Proxy is set to Residential with country US, then run it again in a few minutes.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the mcpConnectors field to push results into Notion, Linear or Airtable.

๐Ÿ”— Want more car data?

Pair this actor with these related scrapers from the same team:

๐Ÿš— Autotrader US
Scrape US car listings from Autotrader by make, model, ZIP, price, year, body style...
๐Ÿš— mobile.de Scraper
Scrape mobile.de vehicle listings with 30+ fields including price, mileage, registration...
๐Ÿš— AutoTrader UK Scraper
Pull structured vehicle listings from autotrader.co.uk at scale. Search by filters or use...
๐Ÿš— AutoScout24 Scraper
From $0.8/1K. A lean, production-grade scraper for autoscout24.com. Point it at a search...
๐Ÿš— Willhaben.at Scraper
From $1/1K. Scrape Willhaben.at listings into clean JSON with 40+ structured fields...
๐Ÿš— Carsales.com.au Scraper
Scrape structured vehicle listings from Carsales.com.au from $1 per 1K results. Built to...

๐Ÿ‘‰ Browse all abotapi scrapers

๐Ÿ’ฌ Support

  • ๐Ÿž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • ๐Ÿ› ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • โญ Enjoying it? A quick review on the actor page helps other users find it.