Craigslist Scraper & Tracker - Cars, Housing, Price Drops & MCP avatar

Craigslist Scraper & Tracker - Cars, Housing, Price Drops & MCP

Pricing

from $0.70 / 1,000 listings

Go to Apify Store
Craigslist Scraper & Tracker - Cars, Housing, Price Drops & MCP

Craigslist Scraper & Tracker - Cars, Housing, Price Drops & MCP

Craigslist scraper, tracker and API for cars, apartments, housing, jobs and for sale by keyword, city, state or link: price, owner or dealer, photos, car and rental details. Only changes returns new listings, price drops and gone listings, with Slack, Discord or Teams alerts and MCP.

Pricing

from $0.70 / 1,000 listings

Rating

0.0

(0)

Developer

Akhil rajesh

Akhil rajesh

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

an hour ago

Last modified

Share

Craigslist Scraper & Tracker

Scrape Craigslist listings (cars and trucks, apartments and housing, jobs, and everything for sale) by keyword, city and category, or from Craigslist search links: title, price and currency, posted date, place with map point, owner or dealer, photos, a car's odometer and a rental's bedrooms and size. Read listings' own pages too for the full text, first-posted and updated dates, and every attribute: a car's year, make, model, condition, title status and transmission; a rental's bathrooms and features. Search one city, several, or a whole state in one run.

One price, no extras: $1.00 per 1,000 listings, with platform usage included and no row cap on Apify's free plan. (Apify's Store page lists platform usage too, because the live API below adds its own; ordinary runs never do.)

It is also a Craigslist tracker and monitor. Schedule it with Only changes and each run returns only what moved since the last one: new listings, price drops, price increases, listings gone (sold or deleted) and ads posted again, each with every price the tracker has seen for the listing, posted to Slack, Discord or Microsoft Teams if you like. It runs as a live API and MCP server for AI agents too.

Why this scraper

  • It tracks changes, not just listings. Most Craigslist scrapers return the same listings every run, and you work out what changed. This one keeps a history per search and returns only new listings, price drops and rises, and listings that left, each one once.
  • Reposts aren't new listings. Craigslist sellers delete an ad and post it again to bring it back to the top. A new listing with the same title at the same map point as one that left is one relisted change, with the old listing's id and price, not a new listing plus a gone one. Copies of the same ad that Craigslist itself groups are shown once.
  • Gone means gone. A listing missing from a search is checked on its own page first: Craigslist's "page not found" reports it gone at once, while one that was only edited out of your search isn't reported at all.
  • Craigslist's own filters, not a guess. Price range, owner or dealer, has photos, titles only, distance from a ZIP code, make and model, year, odometer and bedrooms go to Craigslist with the search, so a run reads only what matches.
  • Every listing, fast. The Actor reads Craigslist's own search feed: up to 10,000 listings per search, 1,080 at a time. A 1,000-listing search takes a few seconds.
  • Whole states in one run. Name CA or Texas and each Craigslist area in it is searched (up to 100 searches a run).
  • No contact details, no runaway bills. Phone numbers and emails are never read. Every run stops at Max results (1,000 unless you set it) or at your maximum cost per run, and searches Craigslist can't run are free.
Typical Craigslist scrapersThis Actor
New listings, price drops, gone listings since the last runYou compare runs yourself (some small monitors do new listings)Built in (Only changes), with reposts paired
Alerts to Slack, Discord, TeamsRareYes
Price historyNoneEvery change row carries the prices your tracker saw
Craigslist's own filters (price, owner/dealer, distance, make and model, year, miles, bedrooms)SomeYes, sent with the search
Full text, attributes, first-posted and updated datesSomeYes, from listing pages (up to 200 a run)
A whole state in one runSomeYes
MCP server for AI agentsRareIts own (4 tools)
Price per 1,000 listingsAbout $1.30 to $6.00, some plus a fee per run or per email$1.00, less on paid plans, listing pages included

Use cases

  • Craigslist alerts: a schedule every hour for "Toyota Tacoma" or "road bike" in your city that posts each new listing and price drop to Slack or Discord, before anyone else calls.
  • Used car deals: cars by owner under a price, by make and model, year and odometer, and every price drop.
  • Rental watch: new apartments and rooms in your area with bedrooms, size and features, and rent drops over time.
  • Resellers and flippers: underpriced furniture, electronics or free stuff in your area, the moment they're posted.
  • Market research: how many listings a search has and their median price, across a city or a whole state (in the run summary).
  • AI agents: ask an assistant "which Honda Civics under $8,000 are for sale by owner in the SF bay area?" through the MCP server.

How to use it in 4 steps

  1. Add Searches: keywords such as honda civic or couch, or Craigslist search links such as https://sfbay.craigslist.org/search/cta?query=civic.
  2. Add Locations: Craigslist areas (SF bay area, New York, Los Angeles, Toronto), a part of one (Manhattan, NY), or a state (CA) for every area in it. Pick a Category if you like (cars, apartments, furniture); a category without a keyword reads the whole category.
  3. Set Max results and any filters, and run it.
  4. To track changes, switch on Only changes since the last run, add an Alert webhook URL if you want chat alerts, and schedule it.

What you get

One row per listing (type: "listing"). Example (a real row, Honda Civics by owner in the SF bay area, with its listing page read; shortened):

{
"type": "listing",
"id": "7988741523",
"search": "'honda civic' in cars & trucks, SF bay area",
"title": "2013 Honda Civic ( Smogged/ Back up Camera)",
"price": 3700,
"currency": "USD",
"postedAt": "2026-10-23T20:44:04Z",
"location": "Concord",
"areaName": "SF bay area",
"subareaName": "east bay area",
"latitude": 37.989,
"longitude": -122.005,
"category": "cars & trucks - by owner",
"sellerType": "owner",
"odometer": 201952,
"odometerUnit": "mi",
"imageCount": 5,
"year": 2013,
"makeModel": "honda civic",
"condition": "excellent",
"titleStatus": "clean",
"transmission": "automatic",
"fuel": "gas",
"drive": "fwd",
"bodyType": "sedan",
"postalCode": "94519",
"firstPostedAt": "2026-10-23T20:44:04Z",
"description": "Run excellent no mechanical issues, clean interior and exterior, very well maintained ...",
"summary": "2013 Honda Civic ( Smogged/ Back up Camera) (201,952 mi; $3,700), by owner, Concord, posted 2026-10-23.",
"url": "https://www.craigslist.org/view/d/concord-2013-honda-civic-smogged-back/gx51JGtT6XCmS7akibHVix"
}

Every row from a search has the title, price and currency, posted date, place and map point, the Craigslist area and its part, the category and seller type, photo links, and for cars the odometer, for housing the bedrooms and size. A listing page (Listing pages to read, or the Listings input) adds the full text, first-posted and updated dates, the postal code, every labelled attribute (attributes) and, for a car, the year, make and model, condition, cylinders, drive, fuel, colour, title status, transmission and type; for housing the bathrooms, availability, rent period and features (features: "cats are OK", "laundry in bldg", "off-street parking"...). A map address is kept for housing and dealers, and left out for private sellers' items.

Prices: price is in the area's currency (currency: USD, CAD, GBP...; monthly rent for rentals), and empty when the ad gives none. Dates: postedAt is the listing's last posting (a renewal moves it); firstPostedAt, from its page, is its first.

With Only changes, each row also has change; price changes have previousPrice, changeAmount and changePercent; and every change row has trackedPrices (the prices the tracker saw, [{"date", "price"}], the latest 6) and firstSeenDate:

changemeaning
newListinga listing that wasn't in the search at the last run
priceDrop / priceIncreasethe price moved since the last run
removedgone: its page answers "not found" (deleted or expired), or it was missing two runs in a row
relistedthe same ad posted again under a new id (the same title at the same map point; relistOf is the old id, previousPrice its price)
firstRunthe first run's baseline: the listings there now

The dataset has views for Listings, Changes, Cars and trucks, Housing and Listing pages (a view picks columns: every view lists every row, so filter on type or change if you need to).

How to use it

Searches, locations and category

A keyword is searched the way Craigslist's search box does (in titles and text; Search titles only narrows it), in each Location and the Category you set. Each keyword in each area is one search: ["honda civic", "toyota corolla"] in ["SF bay area", "Sacramento"] is four searches. A location is a Craigslist area by its name (SF bay area, new york city, los angeles, chicago, toronto, london, UK) or its host (sfbay), a part of an area (Manhattan, NY, city of san francisco, east bay area), a city with its state (Bakersfield, CA), a US state or Canadian province (CA, Texas, Ontario: every area in it), or a country (Canada). A category is Craigslist's name (cars & trucks, cars & trucks - by owner, apartments / housing for rent) or a plain word (cars, apartments, rooms, furniture, free stuff, jobs); empty means everything for sale.

A pasted Craigslist search link keeps its own area, category, keyword and filters (any of Craigslist's filter parameters), with this Actor's filters added on top.

Results come newest first unless you pick another Order (relevance, price low to high, price high to low). Craigslist lists at most 10,000 listings per search; Max listings read per search (1,000 by default) sets how far each search is read.

Listings

Craigslist listing links (craigslist.org/view/d/<title>/<id>, or an older link such as sfbay.craigslist.org/sfc/cto/d/<title>/7954213800.html), each read from its own page. A listing that is gone gets a free notFound row. (A post id alone can't be opened: Craigslist needs the link.)

Filters

Sent to Craigslist with each search: minimum and maximum price, owner or dealer, only listings with photos, search titles only, distance from a ZIP or postal code, and for cars the make and model, minimum and maximum year and maximum odometer, for housing the minimum and maximum bedrooms. Applied by the Actor: posted (or renewed) within N days, and words to leave out of titles (wanted, parts, broken). Hide duplicates (on) shows one listing per group of copies Craigslist itself groups; Include nearby areas (off) keeps the listings Craigslist adds to a small search from neighbouring areas.

Tracking changes on a schedule (Craigslist tracker)

  1. Switch on Only changes since the last run. Optionally pick the Changes to return.
  2. Run it once: the first run returns the listings there now as firstRun (up to Max results) and saves them as the baseline.
  3. Schedule it (Apify Console, Schedules). Each later run returns only the changes.

How it decides:

  • Each search is read whole, up to Max listings read per search, and every listing is compared with the last run.
  • A listing missing from a search read whole is checked on its own page (up to 50 a run): Craigslist's "page not found" reports it gone at once; a listing still up there (edited out of your search) is left alone. Without a page check it is reported gone when it is missing two runs in a row.
  • A search read only in part (past Max listings read per search) can't tell a gone listing from one past the cut, so it reports no gone listings, and an older listing that moves into its window is recorded quietly rather than reported new.
  • In a search read whole, a listing that wasn't there last run is new, however old: an ad edited into your search, or whose price dropped under your maximum, is a new match. A new listing with the title and map point of a listing that left is reported once as relisted.
  • Each listing's prices are kept as the tracker sees them (the latest 6).
  • Histories are kept per search and filters (two trackers with different filters don't mix), in the key-value store craigslist-tracker-history, or one you name in History name.
  • Only what a run returns moves the history: if Max results or your spending limit stops a run, the changes it didn't return come with the next run. The most important come first: price drops, new listings, gone listings, reposts, price increases.

Alerts in Slack, Discord or Microsoft Teams

Paste an incoming-webhook URL in Alert webhook URL (Slack, Discord, Microsoft Teams, or any HTTPS endpoint that takes JSON, such as Zapier, Make or n8n). It switches on Only changes. The first run posts one short "alerts are set up" message; each later run posts its changes (new listings and price drops by default, or those you pick in Alert on), up to 50 per run, most important first, each with the photo, price move, place and link. The URL is treated as a secret and masked in logs. If posting fails, the run still succeeds and its status says why.

Run summary for pipelines

Each run saves a RUN_SUMMARY record in its key-value store: per search, Craigslist's count, when Craigslist made its list (listedAt), listings read, whether it was read whole, the median price, duplicates hidden and nearby listings left out; plus the changes, what didn't load and why, and the filters used. Every listing row also has a one-sentence summary, ready for a report, an alert or an AI agent.

Craigslist API: use it from code or from an AI assistant

Start a run and get the rows in one call (replace <YOUR_TOKEN>; a call that waits gives up after 5 minutes, so start bigger runs without waiting and read the dataset afterwards):

curl -X POST "https://api.apify.com/v2/acts/akhil_rajesh~craigslist-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"searches": ["road bike"], "locations": ["SF bay area"], "maxResults": 100, "maxPrice": 800}'

Or from Python with apify-client:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("akhil_rajesh/craigslist-scraper").call(run_input={
"searches": ["honda civic"], "locations": ["Los Angeles", "Orange County, CA"], "category": "cars",
"maxResults": 300, "minYear": 2015, "maxMiles": 120000, "sellerType": ["owner"],
})
for row in client.dataset(run.default_dataset_id).iterate_items():
print(row["summary"])

For AI agents: MCP server and live API

The Actor also runs as a live endpoint (Apify Standby): an MCP server that agents call directly, and plain HTTP endpoints. Once a Standby run is up, a request is answered in seconds; the first request starts one. Authenticate with your Apify API token in the Authorization: Bearer <token> header.

MCP server (Streamable HTTP): https://akhil-rajesh--craigslist-scraper.apify.actor/mcp

{"mcpServers": {"craigslist": {"type": "http", "url": "https://akhil-rajesh--craigslist-scraper.apify.actor/mcp",
"headers": {"Authorization": "Bearer <YOUR_APIFY_TOKEN>"}}}}

In Claude Code:

$claude mcp add --transport http craigslist https://akhil-rajesh--craigslist-scraper.apify.actor/mcp --header "Authorization: Bearer <YOUR_APIFY_TOKEN>"

A client that can't send headers can use https://akhil-rajesh--craigslist-scraper.apify.actor/mcp?token=<YOUR_APIFY_TOKEN>; keep that URL private, as it carries your token. Through Apify's MCP server (https://mcp.apify.com, for Claude, ChatGPT, Cursor and other clients), add the tools with https://mcp.apify.com?tools=akhil_rajesh/craigslist-scraper (they appear as akhil_rajesh--craigslist-scraper--search_listings and so on), then ask in plain words, for example "find road bikes under $500 from owners in the SF bay area". Add them that way rather than through Apify's generic call-actor tool, which returns the rows only as text. Apify's MCP server doesn't offer Actors with a live endpoint to agents that pay per call with x402 or Skyfire: connect with an Apify account or API token.

ToolWhat it returns
search_listingsListings for up to 3 searches (each keyword in each area) or Craigslist links, with price, posted date, place, owner or dealer, a car's odometer or a rental's bedrooms and a one-line summary; Craigslist's filters on price, seller, distance, make and model, year, miles and bedrooms
get_listingsListings read from their own pages by link: full text, both dates, attributes
find_areasCraigslist's areas for a place, state or country (free)
run_actorThe Actor's whole input in one call

HTTP endpoints, such as GET https://akhil-rajesh--craigslist-scraper.apify.actor/listings?searches=road bike|gravel bike&locations=SF bay area&max=100&maxPrice=800 (separate several searches, locations or listings with |; defaults in brackets). The Actor's Endpoints tab in Apify Console lists them too, and lets you try them.

EndpointParameters
GET /listingssearches, locations, category, max (100), minPrice, maxPrice, seller, sort, postedWithinDays, exclude, photos, titlesOnly, postal, distance, makeModel, minYear, maxYear, maxMiles, minBeds, maxBeds, nearby, listingPages (0)
GET /listinglistings (links)
GET /areasq (a place, state or country; free)
POST /runThe Actor's whole input as the JSON body

Answers carry the rows, rowsByType, notFound (searches or listings Craigslist can't show: free), notLoaded (what Craigslist didn't answer), notRead (what a limit left out: not charged) and notes. A request that reads nothing gets an error and nothing is charged: HTTP 400 for an argument it can't read (a tool error over MCP), 503 when Craigslist didn't answer or the run was busy (send it again), 402 when your spending limit for the run is reached (it lifts when the run ends, after 2 minutes without requests). A 503 can also carry rows, when the platform stopped the run while a request was being read: those were stored and charged, and notRead names the rest.

Limits per request: an MCP tool call reads up to 3 searches, 200 listings and 10 listing pages, about 350 kB of rows, within 50 seconds, and asks for 50 listings unless told otherwise (MCP clients stop waiting at 60 seconds, and Apify's MCP server drops answers over about 1 MB); an HTTP request reads up to 10 searches, 2,000 listings, 40 listing pages and about 6 MB within 170 seconds. A state is one search per area, so it is cut to these limits too. What a limit leaves out is named in notRead and isn't charged. A request that has started runs to its end even if you stop waiting: Apify's Standby proxy keeps it open, so its rows are read and charged. Ask for what you need. Tracking (Only changes) and alerts belong to scheduled runs: the live endpoint answers each request on its own, so it ignores those fields.

How much does it cost?

You pay $1.00 per 1,000 listings, less on paid Apify plans, plus a start fee of $0.00005 per run. Platform usage is included in runs of the Actor: there is no compute charge on top, and no row cap on Apify's free plan. (The Store page's pricing box mentions platform usage because of the live endpoint, which charges its own; ordinary runs never do.) Listing pages are included in the listing's price. Not-found rows are free. With Only changes you pay only for the changes returned. The live endpoint (MCP server and HTTP API) charges listings at the same prices, plus the Standby run's platform usage while it serves you and until it has been idle for 2 minutes (a short session costs a fraction of a cent).

Apify planPer 1,000 listings
Free$1.00
Starter$0.90
Scale$0.80
Business and above$0.70
RunListingsCost (Free plan)
A keyword in one city (about 300 listings)300about $0.30
A category's newest 1,000 listings1,000about $1.00
A tracker of 3 searches every hour, about 10 changes a run240 a dayabout $0.24 a day
50 listings read from their own pages50about $0.05

Apify's free plan ($5 of monthly credit) covers about 5,000 listings. To cap spending, lower Max results or set a maximum cost per run in the run options; the Actor stops cleanly at the limit (and with Only changes, the rest comes with the next run).

Good to know

  • Speed: a search's whole list comes in one request, and its details 1,080 listings at a time: a 1,000-listing search reads in a few seconds. A listing page takes about 2 seconds.
  • Craigslist's own limit: Craigslist lists at most 10,000 listings per search. Narrow a bigger one with a category, a filter or a part of the area.
  • Freshness: Craigslist serves a search's results from its cache for up to 15 minutes, as it does on its own site: the same search asked again in that time gets the same answer. So a tracker finds nothing new more often than every 15 minutes; each search's listedAt in the run summary says when Craigslist made its list.
  • Refusals: a run that meets a refusal asks again a few times, then fails without charging; listing pages refused once aren't asked again in that run.
  • What isn't collected: phone numbers, emails, and private sellers' map addresses. Contact a seller through the listing's own page.

FAQ

Can I get Craigslist alerts for new listings? Yes: switch on Only changes, paste a Slack, Discord or Teams webhook in Alert webhook URL, and schedule it (every 15 to 60 minutes is typical: Craigslist caches a search for up to 15 minutes). Each new listing and price drop is posted once.

Can it track price drops on Craigslist? Yes. Craigslist doesn't show an earlier price, so the tracker remembers each listing's price and reports every move, with trackedPrices (every price it saw).

Does it count reposted ads as new? No. An ad deleted and posted again (the same title at the same map point) comes once as relisted, with the old id and price, and Craigslist's own duplicate copies are shown once.

How do I know a listing sold? Craigslist doesn't say "sold"; the ad is deleted or expires. With Only changes, a listing that leaves the search is checked on its own page and reported removed once Craigslist says it's not found.

Can I search a whole state or several cities? Yes: put CA, Texas or several areas in Locations. Each area is searched on its own (up to 100 searches a run).

Does it work for cars and rentals? Yes: cars (or cars & trucks - by owner) with Craigslist's make, model, year and odometer filters, and apartments or rooms with the bedrooms filter. Listing pages add a car's condition, title status and transmission, and a rental's bathrooms and features.

Can I paste a Craigslist search link? Yes, old-style (sfbay.craigslist.org/search/cta?...) or new (craigslist.org/search/area/sfbay?cat=cta&...): its area, category, keyword and filters are kept.

Does it get the seller's phone number or email? No, this Actor never collects contact details. The listing's link leads to Craigslist's own reply button.

Does it work outside the US? Yes, in all of Craigslist's 707 areas, including Canada, the UK and Europe, with each area's currency.

Do I need a proxy? No: Craigslist answers Apify's servers directly. You can use your own proxies; Apify's residential proxies aren't available in this Actor, as they're billed per GB on top of the result price.

Is it legal? The Actor reads public listings through the same search Craigslist's own pages use, at a modest pace, without logging in, and never collects contact details. Craigslist's terms restrict automated access and commercial use of its content: use the data in line with them and the laws that apply to you.

Other Actors by this developer

Disclaimer

This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by craigslist, Inc. It reads publicly available listings at a modest pace and never collects contact details. Use the data in line with Craigslist's terms and the laws that apply to you.