Cars.com API: Used Car Listings and Price Evaluations
Cars.com runs its APIs for partners such as dealers and resellers, not as a public developer product. To read Cars.com listings as JSON, call GET /v1/cars-com/search with six required parameters: zip, radius_miles, stock_type, sort, page and page_size. Each successful call costs 1 credit. From there, listing, dealer and media open one car by listing_id and zip, and price-eval returns price evaluations for an area.
Does Cars.com have a public API?
Not one you can sign up for. Cars.com uses APIs to share listing, inventory, pricing and lead data with its own partners: a Google Cloud case study says it exposes more than 100 APIs and first used its API platform to make listing and performance data available to reseller partners (Google Cloud, 2026). There's no self-serve key for outside developers.
Its terms of service also say you may not use automated means such as robots, crawlers or spiders to collect data from the site (2026). If you need Cars.com data for a commercial product, a partnership with Cars.com is the route that gives you rights to it. The Cars.com API returns what the site shows as JSON for analysis, with the same key as the rest of the catalogue; whether your use is allowed depends on those terms and the law that applies to you, and Perceptlayer can't advise on it.
Which Cars.com endpoints are there?
Eight GET endpoints, each 1 credit per successful call. Two give you valid inputs (taxonomy and facets), two work on an area (search and price-eval), and four open one car. The per-car endpoints all take the listing_id from a search plus a zip, so keep the zip you searched with alongside each listing ID.
| Endpoint | Returns | Required |
|---|---|---|
/v1/cars-com/taxonomy |
The vehicle taxonomy | none |
/v1/cars-com/facets |
Search facets for an area | zip |
/v1/cars-com/search |
A page of listings | zip, radius_miles, stock_type, sort, page, page_size |
/v1/cars-com/price-eval |
Price evaluations | zip, radius_miles, sort, page, page_size |
/v1/cars-com/listing |
One listing | listing_id, zip |
/v1/cars-com/dealer |
The listing's dealer | listing_id, zip |
/v1/cars-com/media |
The listing's media | listing_id, zip |
/v1/cars-com/model-reviews |
Reviews of the car's model | listing_id, zip |
Start with taxonomy. It takes no parameters and returns the site's vehicle taxonomy, which is where the make and model slugs come from, so you send makes[] and models[] that match rather than guessing at spellings. We haven't recorded a taxonomy response, so run it in the playground on the Cars.com API page to see the exact slugs.
How do you search Cars.com listings?
Send all six required parameters to GET /v1/cars-com/search. This request asks for used cars within 50 miles of ZIP 60601 in Chicago, best matches first, 20 to a page. It's the request behind the recorded response below:
curl "https://api.perceptlayer.com/v1/cars-com/search?zip=60601&radius_miles=50&stock_type=used&sort=BEST_MATCH_DESC&page=1&page_size=20" \
-H "X-API-Key: $API_KEY"
Keys start with sk_live_ and go in the X-API-Key header. Get a free API key; the authentication docs cover the rest.
Which search parameters can you use?
Six are required and seven optional. Types and allowed values come from the endpoint definition; nothing else is documented, so don't rely on a maximum page_size until you've tested one.
| Parameter | Type | Required | Notes |
|---|---|---|---|
zip |
string | yes | US ZIP code at the centre of the search |
radius_miles |
integer | yes | Search radius in miles |
stock_type |
string | yes | all, used, new or cpo |
sort |
string | yes | BEST_MATCH_DESC, DISTANCE, MILEAGE, MILEAGE_DESC, YEAR, YEAR_DESC, LISTED_AT_DESC, LIST_PRICE_DESC |
page |
integer | yes | Start at 1 |
page_size |
integer | yes | Listings per page |
makes[], models[] |
list of strings | no | Up to 64 characters each |
year_min, year_max |
integer | no | Model year bounds |
fuel_slugs[] |
list of strings | no | Fuel types, as slugs |
transmission_slugs[] |
list of strings | no | Transmissions, as slugs |
seller_type[] |
list of strings | no | dealership, private_seller, online_seller |
List parameters repeat in the query string. For used Toyota and Honda cars from 2020 onwards, sold by dealerships, add makes[]=toyota&makes[]=honda&year_min=2020&seller_type[]=dealership, using the make slugs taxonomy returns. stock_type=cpo limits results to certified pre-owned cars.
What does a search response contain?
The recorded response for the Chicago request above has a metadata object and a listings array. metadata reports total_entries 10,000 across total_pages 500. A round 10,000 may be a cap on what one search reports rather than the size of the market, so narrow by radius, make or year to see past it. The first listing, trimmed with …:
{
"success": true,
"data": {
"metadata": { "page": 1, "page_size": 20, "total_pages": 500, "total_entries": 10000, "sort": "BEST_MATCH_DESC", "has_more": true },
"listings": [
{
"listing_id": "5fac55c4-0214-4693-ba58-5e80581e5cb7",
"vin": "SCCLEKMX0RHB45170",
"price": 90412,
"price_currency": "USD",
"mileage": 9457,
"year": 2024,
"make": "Lotus",
"model": "Emira",
"trim": "First Edition",
"body_style": "Coupe",
"fuel": "Gasoline",
"drivetrain": "Rear-wheel Drive",
"certified_preowned": false,
"stock_type": "USED",
"seller_type": "dealership",
"price_badge": "GOOD",
"predicted_price": 89702,
"listed_at": "2026-09-11T14:47:18",
"location_zip": "60515",
"dealer": { "id": "08cb8b0e-0d9b-5eba-9354-55618dd089a2", "name": "Napleton Aston Martin" },
…
},
…
]
}
}
The vin is the field to deduplicate on and to join with other sources, since listing_id is Cars.com's own. location_zip is the car's location, which can differ from the ZIP you searched. Fields such as city_mpg appear on some listings and not others, so treat everything beyond the core price, mileage and vehicle fields as optional.
How do you open one listing?
Pass the listing's ID and the search's ZIP to GET /v1/cars-com/listing. The same two parameters open the dealer, the photos and the model reviews, so a full profile of one car is four calls. Most projects need only listing; fetch dealer when you're aggregating by seller and media when you need the images.
curl "https://api.perceptlayer.com/v1/cars-com/listing?listing_id=$LISTING_ID&zip=60601" \
-H "X-API-Key: $API_KEY"
This Python script pages through a search and saves each page as it arrives, stopping at a fixed page budget so a large market can't run away with your credits:
import json
import os
import requests
URL = "https://api.perceptlayer.com/v1/cars-com/search"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}
BASE = {"zip": "60601", "radius_miles": 50, "stock_type": "used",
"sort": "LISTED_AT_DESC", "page_size": 20}
MAX_PAGES = 10
spent = 0
for page in range(1, MAX_PAGES + 1):
r = requests.get(URL, params={**BASE, "page": page}, headers=HEADERS, timeout=60)
if r.status_code != 200:
print("page", page, r.json()["error"]["code"])
break
spent += int(r.headers["X-Credits-Used"])
with open(f"cars-60601-p{page}.json", "w") as f:
json.dump(r.json(), f)
print("credits used:", spent)
We haven't run this script live for this article. With sort=LISTED_AT_DESC, the first pages hold the newest listings, so a daily run that reads the first few pages catches new stock without re-reading the whole market.
What does price-eval return?
GET /v1/cars-com/price-eval returns price evaluations for the listings in an area. It takes the same area and paging parameters as search, zip, radius_miles, sort, page and page_size, plus an optional boolean no_accidents, but no make, model or stock filters. It works on the market around a ZIP, not on one listing.
curl "https://api.perceptlayer.com/v1/cars-com/price-eval?zip=60601&radius_miles=50&sort=BEST_MATCH_DESC&page=1&page_size=20&no_accidents=true" \
-H "X-API-Key: $API_KEY"
We haven't recorded a price-eval response, so look at a page in the playground before you rely on any field. Note that search listings already carry the site's verdict: in the recorded search, each listing has a price_badge (GOOD or GREAT on the first three) and a predicted_price, such as 89,702 against a list price of 90,412. Treat an evaluation as the site's view of a listing's price at the time of the call, not as a valuation of your own. If you need a model you control, the article on used car listing data for price analysis covers the listing fields that predict price.
What does paging a metro area cost?
One credit per successful call, so the cost is the number of pages, which is listings ÷ page_size, rounded up. Read the market size from your first page rather than guessing it. The recorded search for used cars within 50 miles of 60601 reports total_pages 500 at page_size 20:
| Step | Calls | Credits |
|---|---|---|
taxonomy, once |
1 | 1 |
search, all 500 pages |
500 | 500 |
listing for 200 cars you shortlist |
200 | 200 |
| Total | 701 | 701 |
That's 701 credits, inside the 1,000 free credits a month. A daily check of the first 5 pages of newest listings is 5 × 30 = 150 credits a month on top. Failed calls cost nothing and return X-Credits-Used: 0. The credits docs explain the balance, and pricing has what credit packs cost. For another US source, the CarGurus guide covers its search and dealer data.
To try it now, run a search for your own ZIP in the playground on the Cars.com API page.
APIs in this post
Frequently asked questions
How much does the Cars.com API cost?
Each of the 8 endpoints costs 1 credit per successful call, and failed calls cost nothing. Paging the recorded Chicago search's 500 pages is 500 credits, and each listing you open is one more. Every verified account gets 1,000 free credits a month, and the pricing page has what credit packs cost.
Why do the listing endpoints need a ZIP code?
listing, dealer, media and model-reviews all require zip alongside listing_id in their endpoint definitions. Store the ZIP you searched with next to each listing ID, and send the same pair when you open the listing. A call without zip fails with invalid_parameters and costs nothing.
Can I search private sellers only?
Yes. Add seller_type[]=private_seller to the search. The other values are dealership and online_seller, and you can repeat the parameter to include more than one. Private sellers are people, so use those listings for market analysis and don't contact sellers from the data without a lawful basis.
What does stock_type=cpo mean?
cpo is certified pre-owned: used cars sold with a certification, usually through a manufacturer's programme. The other values are used, new and all. stock_type is required on search, so every search names one; use all when you want every listing in the radius.
How do I get valid make and model values?
Call /v1/cars-com/taxonomy, which takes no parameters and costs 1 credit, and use the slugs it returns in makes[] and models[]. facets with a zip shows the values available in one area. Fetch taxonomy once and cache it rather than calling it before every search.