CarMax Used Car Listings & Price Drop Alerts
Pricing
from $0.70 / 1,000 car listing scrapeds
CarMax Used Car Listings & Price Drop Alerts
Search CarMax.com used-car inventory by make and model near a ZIP code and get one flat row per car: price, price drop, mileage, store, shipping fee, trim, colours, engine, MPG, features, VIN, URL. Newest listings first. For new-inventory and price-drop alerts.
Pricing
from $0.70 / 1,000 car listing scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
10 days ago
Last modified
Categories
Share
Search CarMax's used-car inventory by make, and
optionally model, near a US ZIP code and get one flat row per car: price, the
price before a drop, mileage, the store it is at and how far that is, the
shipping fee to bring it to you, when CarMax made it available, trim, colours,
engine, MPG, the feature list, VIN and the carmax.com link. Run it on a
schedule sorted newest listings first and diff on stock_number to get a
CarMax new-inventory alert, or filter on price_dropped for a price-drop
alert on the cars you are watching.
No account, no API key, no login, no browser. One request returns up to 100 cars.
Input
| Field | Notes |
|---|---|
make | Required. As it appears in a carmax.com address: toyota, ford, land-rover, mercedes-benz. Case and spaces do not matter. |
model | Optional. camry, cr-v, f150, mustang-mach-e. Spelling that differs from CarMax's only in punctuation (F-150, Mustang Mach-E) is mapped onto CarMax's. Empty means every model. |
zipCode | Required. Five-digit US ZIP. Distance, shipping fee and arrival dates are measured from the store CarMax assigns to it. |
radius | nationwide (default), 25, 50, 75, 100, 250 or 500 miles from the ZIP. |
sort | new-arrival (default, newest listings first), price-asc, price-desc, mileage-asc, mileage-desc, year-desc, year-asc, distance-asc, best-match. |
maxItems | Cars to read (default 100, up to 10,000). 100 per request. |
proxyConfiguration | Apify proxy by default. |
A make or model CarMax does not know
CarMax answers a make or model it has never heard of with HTTP 200 and its
whole 64,000-car inventory, unfiltered, and a model that does not belong to
the make drops the make filter too. Left alone, make: toyta would return and
bill 100 arbitrary cars. The actor reads the filters CarMax says it applied
(selectedFacets) and, when they are not the ones asked for, either maps the
spelling onto CarMax's own list or stops the run with the list of valid makes
(or the models of that make). Nothing is charged for the rows it refuses.
The ZIP code and the radius
- A ZIP CarMax does not recognise (
00000, letters) is answered with HTTP 200 and a store CarMax picks itself (Kansas City). The actor compares the ZIP CarMax echoes with the one you gave and stops the run if they differ. - The radius is honoured at 25, 50, 75, 100, 250 and 500 miles. Measured for Honda from ZIP 90001 (Los Angeles): 142, 395, 485, 546, 803 and 1,312 cars against 6,111 nationwide. CarMax silently ignores 5 miles and any other distance and answers nationwide, so only the honoured ones are offered.
About the sorts
The sorts are CarMax's own and the actor checks each one: CarMax answers a sort
name it does not know with HTTP 200 and its default "best match" order, so the
actor reads the sort the response says it applied and fails the run (at no
charge) rather than return mis-ordered rows. date-desc, the name some
write-ups use for newest-first, is one of those ignored names; the working one
is newarrival, which this actor sends for new-arrival.
new-arrival orders by made_saleable_at, the time CarMax made the car
available (newest in the 2026-10-12 probe: 2026-10-11 19:38 UTC, descending
from there). Cars marked coming soon are listed before they are for sale;
they have no made_saleable_at, is_coming_soon is true and
is_saleable is false. Filter them out if you only want cars you can buy.
Output
Prices are US dollars, distances and mileage are miles.
| Field | Notes |
|---|---|
query | The make (and model) searched, as CarMax URL segments: ford or ford/f150. |
stock_number, url, vin | CarMax's stock number (the number in https://www.carmax.com/car/<stock_number>), the link, and the VIN. Compare runs on stock_number. |
year, make, model, trim, body, series | As CarMax shows them. trim is null on cars CarMax lists without one (15 of 332 sampled); series is null on most cars. |
price | CarMax's listed price, before taxes, title, registration and shipping. |
original_price, price_dropped | price_dropped is CarMax's own flag. original_price is the price before the drop and is null unless CarMax sends it - 1 of 332 sampled cars - never 0. A car can be cheaper than last week without CarMax flagging it; for a price history, diff price between runs. |
mileage | Odometer, miles. |
store_id, store_name, store_city, state, state_code, distance_miles | The store the car is at and the distance from your ZIP. distance_miles is 0.0 for a car at your ZIP's own store. |
made_saleable_at | When CarMax made the car available (ISO 8601 UTC). Null for cars that are coming soon (24 of 332 sampled). |
is_new_arrival, is_coming_soon, is_saleable, is_reserved, is_available_to_transact | CarMax's flags. is_available_to_transact is whether it can be bought online from your ZIP. |
transfer_type, transfer_fee, transfer_text | How the car reaches you: test-drive (at your store), shipping-from (shipped in), available-elsewhere, coming-soon. transfer_fee is the shipping fee in dollars, 0.0 for a car already there or shipped free, and null when CarMax sends none (63 of 332 sampled: coming-soon and available-elsewhere cars and some at your store). transfer_text is CarMax's line verbatim ($1999 Shipping, Free Shipping). |
transfer_min_days, transfer_max_days, transfer_arrival | Estimated transfer time and CarMax's arrival text (10/13 - 10/16, Tuesday). The arrival text moves with the day the run happens, so do not diff on it. Null when CarMax sends no estimate. |
exterior_color, interior_color, transmission, drive_train, engine_type, engine_size, cylinders, horsepower, torque | As CarMax words them. interior_color is null on 3 of 332 sampled cars, horsepower and torque on 20. |
mpg_city, mpg_highway | Null where CarMax prints none (22 of 332 sampled, mostly electric cars), never 0. |
ev_range_miles | Original battery range, on electric cars. Null on the rest. |
vehicle_size, vehicle_types, packages, features | CarMax's size class, categories, option packages and the full feature list. Empty list when there are none. |
prior_use | Prior use CarMax discloses: Rental, Fleet, Leased Vehicle. Empty when none is disclosed. |
badge | CarMax's card badge: Popular, Coming soon, Fast shipping, Price drop. Null on most cars. |
image_url | The hero photo as CarMax sends it (400 px wide; change width in the URL for another size). |
Honest nulls
A field CarMax did not send is null, never 0 or "". original_price,
made_saleable_at, transfer_fee, trim, series, mpg_city,
mpg_highway, ev_range_miles and badge are null when the source has
nothing.
Reading a result as an alert
- New inventory: sort
new-arrival, keepis_coming_soonfalse, diff onstock_numberagainst the last run. Newest-first means the first page holds what changed since yesterday. - Price drops: keep rows with
price_droppedtrue, or diffpriceperstock_numberbetween runs. - Nearby only: set a radius. Nationwide lists every store's cars, with the
shipping fee to bring each to you in
transfer_fee.
Pricing
Pay per event:
- $0.002 per run (
actor-start), charged only after your input is validated, so a run that fails on bad input costs nothing. - $0.0007 per car row written (
listing-scraped), i.e. $0.70 per 1,000 cars.
How it fetches
It calls the JSON API behind CarMax's own search page
(www.carmax.com/cars/api/search/run), up to 100 cars per request. Measured
2026-10-12 from an Apify datacenter exit: HTTP 200 with JSON and no key, no
cookie and no login, held over a 30-minute session. CarMax's edge (Akamai)
answers some requests with an "Access Denied" page and HTTP 403: 15 of 92 probe
requests (about 1 in 6; none in the first 24). It is not tied to a parameter:
one URL was refused in one batch and answered in the next, while two others
(a take=6 newest-first search for an unknown make, and mileage-high-to-low
with take=6) were refused every one of the three times they were sent and
answered once take changed. The actor treats a 403, 429 or 5xx as a refusal,
rotates to a fresh address and retries; a refusal costs time and is never
charged. An HTTP 400 is permanent and is not retried. How often a production
run sees a refusal at volume is unmeasured.
Things worth knowing, all measured:
- Page size.
takeup to 100 works; 101 and above is HTTP 400. Each response carries about 200 KB of filter data on top of the cars, so the actor asks for 100 at a time. - Totals.
totalCountis exact but drifts by a few between requests as cars are sold and listed (64,327 to 64,348 within the same minute). A walk can show a car twice across a page boundary; it is returned once. - Depth. Offsets 5,000 and 6,000 into a 6,113-car make answered normally; an offset past the end is HTTP 200 with no cars, which ends the walk.
- Not offered. CarMax's price, year, mileage and colour filters, and its free-shipping filter, are not inputs; this actor searches by make, model, ZIP and radius.