Craigslist Scraper: Listings, Prices & Alerts avatar

Craigslist Scraper: Listings, Prices & Alerts

Pricing

from $0.47 / 1,000 listings

Go to Apify Store
Craigslist Scraper: Listings, Prices & Alerts

Craigslist Scraper: Listings, Prices & Alerts

Scrape Craigslist postings from any of its 707 areas, a whole country or a ZIP code radius, no login, past the 10,000 row cap. Rows hold title, price, place, coordinates, posted time, images, description, VIN, odometer, bedrooms and pay. New post alerts; JSON, CSV, Excel or API; pay per posting.

Pricing

from $0.47 / 1,000 listings

Rating

0.0

(0)

Developer

Automation Craft

Automation Craft

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

21 hours ago

Last modified

Share

Craigslist Scraper: Listings, Prices & Alerts

Craigslist Scraper turns Craigslist postings into clean rows: one row per posting with the title, price, place, coordinates, posted and updated time, category, every image link and, with details (on by default, same price), the full description and every attribute Craigslist shows (cars: make and model, year, odometer, VIN, title status, fuel, transmission; housing: bedrooms, bathrooms, size, laundry, parking, pets; jobs: pay, employment type). Search any of Craigslist's 707 areas and 103 sub areas, whole countries (the United States in six searches), or a ZIP code or coordinates with a radius of up to 1,000 miles, in any of 228 categories, with every Craigslist filter. Paste search links or posting links if you have them. No login, no browser.

Searches larger than Craigslist's 10,000 row limit are split into price slices on their own, and every search ends with a coverage row that says how many postings Craigslist counted and how many were read (a run of very many searches that find little writes the coverage rows past its free row budget as counts in the summary). Name a monitor and schedule the Actor: each run delivers and bills only postings it has not delivered before, tracks price changes, reposts and removed postings, and can send them to Telegram, Slack, Discord, WhatsApp or your webhook.

Who uses it

  • Car dealers, flippers and buyers watching cars and trucks by owner or by dealer, with make and model, year, odometer, title status and VIN, across one area or the whole US.
  • Landlords, property managers and renters comparing rents, bedrooms, size, pets, laundry and parking in a city or within a radius of a ZIP code.
  • Lead and sales teams reading dealer and company postings, which come with their phone numbers and addresses as posted, and ranking postings with a lead score.
  • Analysts and developers who need Craigslist as rows in JSON, CSV or Excel through the Apify API, with the same field names in every category and country.

Features

FeatureSettingsEvent billed
Areas by hostname, name or sub area ("sfbay", "SF bay area", "sfbay/sby", "south bay area"); all 707 areas and 103 sub areasareasListing
Whole countries: "US" is six searches of 1,000 miles that cover every US area (each posting once, other countries left out); any other country is every area of itcountriesListing
US ZIP codes or coordinates with a radius of 1 to 1,000 miles, across every arealocations, radiusMilesListing
228 categories by code or name (sections, groups, "by owner" and "by dealer" leaves); for sale when none is givencategoriesListing
Keywords in Craigslist's own syntax (iphone -case, `(hondatoyota)`, quotes), each its own searchkeywords
Pasted search links of every form (area, sub area, city with a ZIP code or coordinates), every parameter checkedsearchUrlsListing
Posting links (classic and /view/d/ links) or posting ids of 22 letters and digits, read with their detailspostingUrlsListing
Every Craigslist filter: price, posted today, with images, titles only, hide duplicates, free stuff, sold by owner or dealer, condition, delivery, crypto; cars (make and model, year, odometer, title status, transmission, fuel, body type, drive, cylinders, paint, monthly payment); housing (bedrooms, bathrooms, size, housing type, laundry, parking, rent period, availability, cats, dogs, furnished, no smoking, wheelchair access, air conditioning, EV charging, no application fee, no broker fee, private room, private bath); jobs (employment type, telecommuting, internship, non profit); paid gigs; event, garage sale and open house datessee Inputno charge
Any other Craigslist filter by its own name, with a value by code or labelfiltersno charge
Row filters: words to keep or leave out, a posted window, postings you already have, custom rules on output fields, nearby area postings in or outincludeKeywords, excludeKeywords, postedWithinHours, postedWithinDays, postedAfter, postedBefore, excludePostingIds, customFilters, includeNearbyAreasno charge
7 sorts; caps per run and per search; how deep each search is readsort, maxItems, maxItemsPerSearch, maxRowsPerSearchno charge
Past 10,000 rows a search: whole dollar price slicessplitLargeSearches (on)no charge
Continue an interrupted run without paying for a posting twiceresumeFromDatasetIdno charge
Full details: description, every image, every attribute, decoded VIN data, repost mark, updated time, map accuracyincludeDetails (on)included in Listing
A monitor: only postings new to it, run after runmonitorNameListing (new postings only) and Results page
Price and field changes, removed and reappeared postingstrackChanges, trackFields (with a monitor)Listing update
Every known posting again; reposts marked or left outemitUnchanged, markReposts, skipRepostsListing
Notifications: Telegram, Slack, Discord, WhatsApp Cloud API, webhook (HMAC SHA-256 signature, extra headers)see The monitor and notificationsfree
Labels in 15 languages; image size, description format and length, compact rows, empty fields left out, raw Craigslist datalanguage, imageSize, descriptionFormat, descriptionMaxLength, compactOutput, excludeEmptyFields, includeRawDataincluded
A lead score from 0 to 100 with the signals behind italwaysincluded
A private poster's phone numbers, e-mail addresses, street address and exact coordinates (off by default)includePersonalDatafree
A coverage row per search, free status rows for misses, a run summary and an HTML run report (key REPORT)alwaysfree

Quick start

  1. Pick one or more Craigslist areas (for example sfbay, newyork or houston), or type US in Whole countries.
  2. Pick categories (for example cta cars and trucks, apa apartments, jjj jobs; for sale when left empty) and, if you like, keywords.
  3. Optional: pick filters (price, sold by owner or dealer, car year and odometer, bedrooms, pets).
  4. Set Maximum postings and press Start.
  5. Download the rows as JSON, CSV or Excel, or read them through the API.

Example input, the Actor's own prefill (cars and trucks in the San Francisco bay area):

{
"areas": ["sfbay"],
"categories": ["cta"],
"maxItems": 20,
"proxyConfiguration": { "useApifyProxy": true }
}

Cars by owner in Houston, 2015 or newer, at most 100,000 miles, automatic:

{
"areas": ["houston"],
"categories": ["cto"],
"yearMin": 2015,
"odometerMax": 100000,
"transmission": ["automatic"],
"maxItems": 100
}

Two bedroom apartments in New York at 4,000 or less that take dogs:

{
"areas": ["newyork"],
"categories": ["apa"],
"bedroomsMin": 2,
"bedroomsMax": 2,
"dogsOk": true,
"maxPrice": 4000,
"maxItems": 100
}

Every Corvette for sale in the United States, search rows only:

{
"countries": ["US"],
"categories": ["cta"],
"keywords": ["corvette"],
"includeDetails": false,
"maxItems": 1000
}

Bicycles within 10 miles of a San Francisco ZIP code:

{
"locations": ["94103"],
"radiusMiles": 10,
"categories": ["bia"],
"maxItems": 100
}

What you get

One row per posting (type: "listing"), one coverage row per search (type: "search"), free status rows for anything that did not end as a posting (type: "status"), with change tracking a removed row per posting a monitor no longer finds (type: "removed"), and one run summary at the end (type: "summary").

Fields and how often Craigslist fills them

Measured on real platform runs of 2026-10-16 (includePersonalData off, the default):

  • Search only: 1,000 New York "for sale" rows with details off (run apJfW3J8kLZhF929K; 995 by owner, 1 by dealer, 4 in categories without a seller type).
  • Cars with details: 300 Houston "cars & trucks" rows with details (run cBQaUvrLBTa2OUZIe; 93 by owner, 207 by dealer).
  • Housing with details: 15 New York apartment rows with details (run iRJvtGJl2KZCJgAYA), filtered to 2 bedrooms, dogs OK and at most 4,000, so bedrooms, price and dogsOk are full by the filter.
FieldWhat it holdsSearch only (1,000)Cars with details (300)Housing with details (15)
postingId, postingUuid, urlCraigslist's posting id, its 22 character id, the posting's link100 %100 %100 %
titlethe posting's title100 %100 %100 %
price, priceText, currencythe price as a number, as Craigslist writes it, and the area's currency99.3 %92.0 %100 %
category, categoryName, section, sellerTypethe category code and name, its section, owner or dealer (from the "by owner" and "by dealer" categories)100 %; seller type 99.6 %100 %100 %; no seller type in housing
area, areaName, subArea, subAreaName, region, countrythe Craigslist area and sub area, the state or region, the country100 %100 %; sub area 0 % (Houston)100 %
place, neighborhoodthe place text of the posting, the neighbourhood100 %, 4.7 %74.7 %, 0 %100 %, 0 %
latitude, longitude, coordinatesRoundedthe posting's map point (rounded to 2 decimals for private postings, see Privacy)100 %100 %100 %
locationTypepin (the poster placed the pin) or area (Craigslist's approximate place), with details100 % (pin 162, area 138)100 %
postedAt, updatedAt, hoursOnline, daysOnlinewhen the posting went up and was last updated; its age at the runposted 100 %100 %100 %
images, firstImage, imageCountevery image link (search rows carry the images Craigslist lists there)99.4 % (median 8)98.0 % (median 18)100 %
descriptionthe poster's full text, with details100 % (median 690 characters)100 %
attributes, attributeLabelsevery attribute as Craigslist shows it, by key and with its label100 % (median 11)100 %
makeModel, year, titleStatus, fuel, transmissioncar attributes100 %
odometermiles (from the search row, or the posting's attribute)99.7 % on 1,100 search only car rows (San Francisco bay area, run bjhibWCvbvPftItJJ)100 %
bodyType, cylinders, paintColor, drive, conditioncar attributes93.7 %, 85.7 %, 82.7 %, 80.7 %, 63.7 %
vin, vinDatathe VIN and Craigslist's decoded VIN data (make, plant, engine)36.0 % (owner 12 of 93, dealer 96 of 207), 35.3 %
bedrooms, sqft, bathrooms, housingType, laundry, parking, rentPeriodhousing attributes (size in square feet, square meters in metric areas)100 %
moveInDate, catsOk, dogsOk, furnished and the other housing flagshousing attributesmove in date 60 %
compensation, jobTitle, companyName, employmentTypejobs and gigsnot in these samplesnot in these samplesnot in these samples
repostOfthe id of an earlier posting this one reposts (Craigslist's own mark), with details45.3 %60 %
hasContactInfowhether the posting offers a way to reply100 % (a flag)100 %
streetAddress, phoneNumbers, emailsthe posted street address and the phone numbers and e-mail addresses written in the texts: dealers and companies always, private posters only with includePersonalDataaddress 150, phones 181 of 207 dealer rows; 0 of 93 owner rows (off); e-mails 00 (off)
leadScore, leadSignalsa score from 0 to 100 and the signals behind it100 %100 %100 %
missingFieldsthe core fields (title, price, place, coordinates, posted time, first image) Craigslist left empty on this postingset by the Actorset by the Actorset by the Actor
searchKey, searchLabel, source, isNearby, duplicateGroup, detailsIncluded, monitorName, actorRunId, actorTaskId, deliveryId, scrapedAtwhat found the posting (search, or postingUrl for posting links), whether it came from a nearby area, Craigslist's duplicate bundle, whether details were read, the runset by the Actorset by the Actorset by the Actor
change, possibleRepostOf, isRepostwith a monitor: what changed since the last delivery; an earlier posting of the same itemmonitor runsmonitor runsmonitor runs

Rows with details also carry descriptionHtml (the description as HTML, with descriptionFormat), notices (Craigslist's own notices on the posting), seeMyOther (whether the poster links to their other postings) and createdAt (when Craigslist created the record). A removed row carries type, postingId, a null url, reason, message, lastPrice, firstSeenPrice, priceChangeCount, firstSeenAt, daysTracked, monitorName and scrapedAt; monitors of posting links and runs with a posted window write no removed rows (they do not see every posting of a search).

The lead score adds up plain facts of the row: sold by owner (25), a way to reply (20), a price (15), posted within 24 hours (15), images (10), a description of 80 characters or more (10), not a repost (5).

Sample row (a real row of the prefill run on 2026-10-16; some fields left out)

A private posting, so its link carries no title slug and its coordinates are rounded (see Privacy).

{
"type": "listing",
"postingId": "7984331352",
"postingUuid": "1Sh6LvHnmb9De8zQPmLsna",
"url": "https://www.craigslist.org/view/d/posting/1Sh6LvHnmb9De8zQPmLsna",
"title": "2011 Honda Civic Coupe * Gas Saver * Runs Excellent",
"price": 3950,
"priceText": "$3,950",
"currency": "USD",
"category": "cto",
"categoryName": "cars & trucks - by owner",
"sellerType": "owner",
"area": "sfbay",
"areaName": "SF bay area",
"subArea": "eby",
"subAreaName": "east bay area",
"region": "CA",
"country": "US",
"place": "vallejo / benicia",
"latitude": 38.11,
"longitude": -122.24,
"coordinatesRounded": true,
"locationType": "pin",
"postedAt": "2026-10-16T00:56:44.000Z",
"updatedAt": "2026-10-16T00:56:45.000Z",
"imageCount": 15,
"firstImage": "https://images.craigslist.org/00L0L_bpz4YBw1osH_0CI0hT_1200x900.jpg",
"odometer": 203000,
"detailsIncluded": true,
"makeModel": "Honda Civic LX",
"year": 2011,
"titleStatus": "clean",
"fuel": "gas",
"transmission": "automatic",
"drive": "fwd",
"cylinders": "4 cylinders",
"paintColor": "blue",
"bodyType": "coupe",
"condition": "good",
"repostOf": "7954770517",
"hasContactInfo": true,
"streetAddress": null,
"phoneNumbers": null,
"emails": null,
"leadScore": 95,
"searchLabel": "cta (cars & trucks) in sfbay (SF bay area)",
"source": "search",
"missingFields": [],
"scrapedAt": "2026-10-16T00:57:31.145Z"
}

searchKind, searchLabel, searchCategory, searchKeyword, searchPlace, searchRadiusMiles, sort, postingsOnCraigslist (Craigslist's own count), searchCapRows, rowsRead, slices, slicesWalked, countCalls, postingsBeyondReach, callsMade, rowsSeen, distinctPostingsSeen, postingsDelivered, alreadyDelivered, knownToMonitor, filteredOut and filteredOutBy (per filter), nearbyAreaRows, deletedOrGone, detailsFailed, newPostingsMayLieBeyond (a monitor), complete, stoppedBy, moreRowsOffered and a note.

Removed rows (trackChanges)

postingId, reason (notFoundByCompleteSearches), message, lastPrice, firstSeenPrice, priceChangeCount, firstSeenAt, daysTracked, monitorName, scrapedAt.

Free status rows

A setting or an item the Actor refused (invalid), an area or category name that matches several entries (ambiguous, with the candidates), a posting link Craigslist does not know or a search it does not serve (not_found), a posting deleted by its author (deleted), a posting or a search that could not be read (failed), a search whose filters Craigslist did not apply as sent (search_not_applied), a posting link a monitor already delivered (skipped), a notification that failed (notification_failed), a run the platform restarted (resumed), and the reason a run stopped (limit_reached, source_unavailable, monitor_unavailable). A run writes 20 such rows plus one per billed event, at most 200 of one kind; past that it counts the rest in the summary. Coverage rows share that budget.

How searches are read

  • Past 10,000 rows. Craigslist serves at most the newest 10,000 rows of one search. When a search holds more and your caps want more, it is split into whole dollar price slices (each planned with a call of 360 rows, halved while a slice holds more than 9,000), and each slice is read from the top. Postings without a price fall in no slice: they are reached only among the newest 10,000, and the coverage row counts every posting left beyond reach. In a test of 2026-10-16 the San Francisco bay area cars search counted 15,588 postings and was read in 2 price slices.
  • Every filter checked. Craigslist ignores a parameter it does not know and answers an option value outside its list with an empty page, without an error. The Actor sends only Craigslist's own filter names and values, refuses a pasted link with any other, and compares Craigslist's echo of the search with what it sent on every answer; a search that differs ends with a free search_not_applied row and nothing billed from that answer. Every row is also checked against the filters its own fields show (area, sub area, country, price, seller type, images, the car and housing attributes), again on the posting when details are read, and a posting edited between the search and the read is checked against the keyword again.
  • Nearby areas. When a search has few local postings, Craigslist adds postings of nearby areas after them and does not count them. They are left out free unless you turn on includeNearbyAreas, and delivered ones carry isNearby: true.
  • The whole US. Craigslist has no country search. countries: ["US"] runs six searches of 1,000 miles (Craigslist's largest radius) around Louisville, Provo, New Orleans, Detroit, Anchorage and Honolulu, which hold every US area within 800 miles of a centre; a posting found by two circles is delivered once, and postings of Canadian or Mexican areas inside a circle are left out free.
  • One row per posting. A posting found by several searches in one run is delivered and billed once.
  • Fresh answers. Craigslist keeps each search answer for 15 minutes for every client; the Actor asks for a fresh one on every call. In a test of 2026-10-15 the newest "for sale" posting was 17 to 49 seconds old in three cities.
  • Access. Requests leave through one Apify datacenter exit per run (a new one only when the proxy itself fails; when the proxy's address cannot be checked three times, or every session lands in a network Craigslist refuses, the run reads from its own container's address and the summary says so), two at a time, 2 a second by default, and only through doors Craigslist's robots.txt allows. A refusal is asked once more on the same exit after a pause; a second refusal ends the run's reading with a free source_unavailable row. No captcha is ever solved.

How much does it cost to scrape Craigslist?

You pay per posting row delivered, with the full details included, plus a small start fee per run. Platform usage and the datacenter proxy are included.

EventFreeBronzeSilverGold
Listing (per 1,000 postings, details included)$0.66$0.60$0.55$0.47
Results page (per 1,000 units of 360 rows a monitor checks; monitor runs only)$0.70$0.64$0.58$0.50
Listing update (per 1,000 changes and removed rows; monitor runs with trackChanges only)$0.66$0.60$0.55$0.47
Actor start (per run)$0.007$0.007$0.007$0.007

Platinum and Diamond plans pay the Gold price. The Actor start event is a flat $0.007, charged once per run, with no plan discount. The Store pricing card shows these same prices per 1,000 events: "$0.60 / 1,000" on the Listing row means one posting costs $0.0006, and "$0.64 / 1,000" on the Results page row means each 360 rows a monitor checks cost $0.00064.

  • 1,000 postings with details cost $0.66 + $0.007 = $0.667 on Free, $0.60 + $0.007 = $0.607 on Bronze, $0.55 + $0.007 = $0.557 on Silver and $0.47 + $0.007 = $0.477 on Gold.
  • The prefill run (20 postings with details) costs 20 x $0.00066 + $0.007 = $0.0202 on Free and 20 x $0.00047 + $0.007 = $0.0164 on Gold.
  • An hourly monitor over one search on Bronze reads the newest 360 rows each run: 24 runs a day cost 24 x ($0.007 + $0.00064) = $0.18336 a day, plus $0.0006 per new posting. A run that finds 12 new postings costs $0.007 + $0.00064 + 12 x $0.0006 = $0.01484.
  • What is never billed: postings left out by your filters, nearby area postings left out, a posting found twice in one run, postings a monitor already delivered (unless change tracking finds a change, or you ask for every known posting), deleted and unknown postings, a search Craigslist does not serve or whose filters it did not apply, refused inputs, search calls and posting reads themselves (outside a monitor; in a monitor run each search call is a Results page), coverage, status and summary rows, the run report and the notifications.
  • Limits: set Maximum postings (100 when left empty) and, in the run options, a maximum charge for the run: the Actor stops before it would pass either, and a row whose events do not all fit is withheld whole. Maximum postings counts postings, changes and removed rows together. A run also spends a small allowance on work that delivers nothing billable (searches whose rows your filters leave out, failed reads), USD 0.0008 plus a share of every paid event it delivers; past it the run stops with a free row that says so.

Input

SettingWhat it does
areasCraigslist areas by hostname (sfbay, newyork, houston), name (SF bay area) or sub area (sfbay/sby, sby, south bay area); up to 1,000
countriestwo letter codes; US is the whole United States in six searches; any other country (CA, GB, AU, DE, FR, MX, IN and the rest) is every area of it
locations, radiusMilesUS ZIP codes (94103) or coordinates (37.77, -122.42), searched across every area within the radius (1 to 1,000 miles, 25 by default)
categories228 codes or names (sss for sale, cta cars and trucks, cto by owner, ctd by dealer, apa apartments, jjj jobs, ggg gigs, bbb services, eee events); sss when none is given
keywordswhat to search for, in Craigslist's own syntax; each keyword is its own search
searchUrlsCraigslist search links copied from your browser; each keeps its own filters and sort; a parameter that is not Craigslist's own refuses the link with a free row
postingUrlsposting links or 22 character posting ids, up to 5,000, each read with its details; a deleted or unknown posting is a free row
resumeFromDatasetIdthe dataset of an earlier run of this Actor: its postings are left out, free (up to 200,000 rows read)
named filterssort, minPrice, maxPrice, postedToday, hasImage, titlesOnly, hideDuplicates, freeOnly, sellerType, conditions, deliveryAvailable, cryptoAccepted; cars makeModel, yearMin to yearMax, odometerMin to odometerMax, titleStatus, transmission, fuel, bodyTypes, drive, cylinders, paintColors, monthlyPaymentMin to monthlyPaymentMax; housing bedroomsMin to bedroomsMax, bathroomsMin to bathroomsMax, sqftMin to sqftMax, housingTypes, laundry, parking, rentPeriods, availability, catsOk, dogsOk, furnished, noSmoking, wheelchairAccess, airConditioning, evCharging, noApplicationFee, noBrokerFee, privateRoom, privateBath; jobs employmentTypes, telecommuting, internship, nonProfit; gigs gigPay; date and dateTo (events, garage sales and open houses, one search per day, at most 31 days)
filtersany other Craigslist filter by its own name and value, such as {"mobile_os": "apple iOS"}; an unknown name refuses the run with a free row
row filtersincludeNearbyAreas, includeKeywords, excludeKeywords (whole words in the title and place, and the description when read), postedWithinHours, postedWithinDays, postedAfter, postedBefore (need the newest or oldest sort), customFilters (up to 20 rules), excludePostingIds (up to 5,000)
sortnewest (default), oldest, price_low, price_high, distance (needs a ZIP code or coordinates), relevance (needs a keyword), upcoming (events, garage sales, open houses)
maxItems, maxItemsPerSearch, maxRowsPerSearch, splitLargeSearchescaps, and how far each search is read (Craigslist answers 360, 1,080, 3,240 or 10,000 rows from the top)
includeDetailseach posting's description, every image and attribute (on by default, same price; off is faster)
language, imageSize, descriptionFormat, descriptionMaxLength, includeRawData, compactOutput, excludeEmptyFieldshow rows are written; language sets Craigslist's labels (15 languages), codes stay the same
includePersonalDataa private poster's phone numbers, e-mail addresses, street address and exact coordinates (off by default; see Privacy)
monitor and notificationsmonitorName, trackChanges, trackFields, emitUnchanged, markReposts, skipReposts, notificationLimit, notifyOnlyChanges and the channel settings below
failIfIncomplete, maxFailedRequestsPercent, requestsPerSecond, proxyConfigurationfail the run when a search was not read to its end or too many reads failed; the pace (0.5 to 3 a second, 2 by default); Apify datacenter (default) or your own proxy links

A run holds up to 300 searches (places x categories x keywords x days, plus one per search link) and up to 5,000 posting links. A filter that does not fit a searched category (bedrooms on cars, for example) refuses the run with a free row.

The monitor and notifications

Name a monitor (monitorName) and schedule the Actor (every hour, for example). The monitor remembers every posting it delivered in a named store this Actor creates for itself, up to 60,000 postings, so each run delivers and bills only postings it never delivered before; known postings are skipped for free. A monitor reads the newest 360 rows of each search by default (set maxRowsPerSearch to read 1,080, 3,240 or 10,000), does not split searches, and pays a Results page for each 360 rows it reads (at least one per search); when the coverage row says newPostingsMayLieBeyond, read more rows or run more often. One monitor name belongs to one set of settings: a run with other settings delivers nothing and gets a free row saying so.

  • Change tracking (trackChanges): a known posting whose price changed, or whose price was taken away or put back, comes back with change (changeType: "priceChanged", previous price, difference, first seen price, price history, drop in percent since first seen), billed as a Listing update. With trackFields a change of the title, the images, the location (place, neighbourhood, map point), the odometer, bedrooms, square feet, pay, monthly payment or the sale, event or open house dates counts too (changeType: "updated", changedFields): the facts every search row shows, compared on it, so tracking them reads nothing more. A change of the description or the attributes alone is not tracked: it would need every known posting read again on every run. A posting the monitor reported as removed that shows up again is reappeared.
  • Removed postings: when every search of the run was read to its end (for a monitor, a search that holds no more postings than its window), a posting the monitor tracks that the run did not meet gets a removed row. When more than half of the tracked postings (and more than 5) are missing at once, none are reported and the run says so in a free row.
  • Snapshots and reposts: emitUnchanged delivers known postings again (billed as Listing); markReposts marks a new posting that reposts one the monitor delivered (Craigslist's own "repost of" mark, or the same area, category, title and price under a new id) with possibleRepostOf, and skipReposts leaves it out free. Both need details.
  • Notifications (free, with or without a monitor) after the rows were delivered and billed: Telegram (your own bot, one message per posting), Slack and Discord incoming webhooks and WhatsApp Cloud API (one message per run), each naming up to notificationLimit postings (10 by default, up to 30); a webhook (webhookUrl) gets JSON batches of 100 postings in a short form (id, link, title, price, currency, price text, place, area, category, seller type, miles, bedrooms, posted time, image, search label, change), up to 1,000 a run, signed in the header x-signature-sha256 with webhookSecret, with your own webhookHeaders. With a monitor, unchanged postings are left out of the messages (notifyOnlyChanges, on by default). A failed call never fails the run: it is a free notification_failed row, without your address or token.

A feed of new postings (in place of Craigslist RSS)

Craigslist's RSS feeds refuse automated readers, so this Actor never uses them. To get a stream of new postings:

  1. Pick your search (areas, categories, keywords, filters) and give it a monitorName, such as sfbay-tacoma.
  2. Add a webhookUrl (Zapier, Make, n8n or your own endpoint), or a Telegram, Slack, Discord or WhatsApp channel.
  3. Save the input as a task and schedule it in Apify (every 15 minutes or every hour).

Each run then sends only postings the monitor has not seen. If a tool of yours reads RSS, Apify's API serves any dataset in RSS format (format=rss on the dataset items endpoint); the feed then holds the run's coverage, status and summary rows next to the postings.

Past the 10,000 row cap

Leave splitLargeSearches on (the default) and set maxItems to what you want: a search that Craigslist counts above 10,000 is read slice by slice by price, each slice from the top, and the coverage row gives Craigslist's count, the slices read and anything left beyond reach. A monitor does not split; give it narrower searches (a sub area, a category, a price range) instead.

Privacy and personal data

Many Craigslist postings come from private persons. With includePersonalData off (the default), every posting that is not in a "by dealer" category and names no company is treated as private: phone numbers, e-mail addresses, street addresses written with a house number and a street word (4512 Main St, Hauptstraße 12, Calle Mayor 12) or with a house number and a state code (123 Broadway, New York, NY 10001), exact coordinates written into the text (37.123456, -122.654321, in either order, also inside a map link), and names written right after a contact word (in lower case, the common first names) (

ask for John
) or before a phone number are replaced in its title, description, place, neighbourhood and attribute values (with [phone number removed], [e-mail removed], [address removed], [postal code removed], [coordinates removed], [name removed]); an address or a name written in another way (123 Broadway alone, without a street word or a state) stays as the poster wrote it. A phone number is found by its shape when it has a country code or ten digits or more; a shorter local number (284-1234) is found when a contact word (call, text, contact...) stands before it in the same few lines, and may stay when none does. A number written partly in words and glued to its digits (832-four nine six-0367) is masked whole; one written only in words is not detected. Near a contact word the rule leans to privacy: a number of 6 digits or more there without a unit (miles, sq ft), a label (Mileage:, Stock #:) or a currency sign may be masked as a phone number too. Before the masks, a private posting's texts are written in plain characters (every kind of space as a space, dashes as hyphens, curly apostrophes straight, digits of any script as 0 to 9), and are delivered that way. Its streetAddress, phoneNumbers, emails and raw fields are null, its coordinates are rounded to 2 decimals (about 1 km), and its link is written without the title slug. In the Houston cars run above, 18 of 93 owner postings carried such a mask. With it on, nothing is masked or rounded. Postings of dealers and companies are business data and are always delivered as written. Craigslist shows no poster name, and the reply contact behind its reply button is never read. Images are delivered as links; they belong to the people who posted them. You are responsible for a lawful use of personal data, privacy laws included.

This Actor is not affiliated with or endorsed by Craigslist. Craigslist is a trademark of its owner. It is an unofficial tool that reads public postings without logging in, through the doors Craigslist's robots.txt allows. Craigslist's terms of use forbid collecting its content with scrapers, crawlers or scripts. You are responsible for a lawful use of the data, for complying with privacy laws for any personal data, and for keeping a scheduled monitor to what you need.

What this Actor does NOT do

  • No reply e-mail or phone number from behind the reply button. Craigslist shows the reply contact only after a captcha; the Actor never opens it. hasContactInfo says whether a posting offers one; the posting's link (url) is where a buyer replies.
  • No tracking of description or attribute changes alone. Change tracking compares the facts every search row shows; the description and the attributes would need every known posting read again on every run.
  • No posting, flagging, messaging, saved searches or anything else that needs a Craigslist account. No login.
  • No private poster's phone numbers, e-mail addresses, street address field or exact coordinates unless you turn on includePersonalData. Addresses and names written in the texts are masked in the forms Privacy names. Dealers' and companies' contacts are always delivered.
  • No captcha solving and no new exit to get past a refusal. A second refusal in a row ends the run's reading with a free source_unavailable row.
  • No RSS feeds and no sitemaps. Searches go through Craigslist's search, postings through its posting pages.
  • No more than 10,000 rows from one Craigslist search answer. Past that the search is split by price (not in a monitor); postings without a price are reached only among the newest 10,000, and the coverage row counts what is left.
  • No postal codes outside the US. Give coordinates for a radius search elsewhere, or the areas themselves.
  • No view counts. Craigslist shows none, and reading a posting counts nothing.
  • No image downloads. Images are links in the size you pick.
  • No translation. language sets Craigslist's labels; descriptions come as the poster wrote them.
  • No export into Notion, Airtable or other apps from inside the run. Those exports need your own account at each app; connect the run's dataset with Apify's integrations or MCP connectors, authorised in your own Apify settings.
  • No preloaded snapshot. Every run reads Craigslist live; the data is as fresh as the run.

FAQ

Does Craigslist have an API?

Craigslist offers no API to read or search its postings: its official interfaces serve the list of areas and categories and the bulk posting of ads. This Actor reads the same public postings any visitor sees, with no login, and gives them to you as rows you can read through the Apify API (examples below).

This Actor reads only public postings without logging in, never uses the reply button, flagging or posting, and masks the phone numbers, e-mail addresses and street addresses it finds in private postings unless you turn personal data on. Craigslist's terms of use forbid collecting its content with scrapers, so you are responsible for a lawful use of the data, privacy laws included (see Legal).

How do I search all of Craigslist at once?

Put US in Whole countries: the Actor runs six searches of 1,000 miles that together cover every US area, delivers each posting once and leaves out postings of other countries. Other countries are searched area by area, and a ZIP code or coordinates with a radius of up to 1,000 miles searches every area around a point.

How do I get alerts for new Craigslist listings?

Name a monitor and schedule the Actor, every hour for example. Each run delivers and bills only postings the monitor has not delivered before, and can send them to Telegram, Slack, Discord, WhatsApp or your webhook; no Craigslist account is needed.

What can I use instead of Craigslist RSS feeds?

Craigslist refuses its RSS feeds to automated readers (HTTP 403 in our tests), so this Actor never uses them. A scheduled monitor with a webhook gives a stream of new postings, and Apify's API can serve a run's dataset in RSS format for a feed reader (see A feed of new postings).

Why does this Actor run with limited permissions?

It needs nothing beyond its own storages: it reads Craigslist's public postings and writes to its own dataset and key-value store, plus the named store of a monitor you set with monitorName, which the Actor creates for itself. Limited permissions keep it from touching anything else in your account.

API

Each example starts a run and waits for its rows (the run-sync endpoint suits short runs; use maxItems to keep them short).

curl -X POST "https://api.apify.com/v2/acts/automation_craft~craigslist-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"areas": ["sfbay"], "categories": ["cta"], "maxItems": 20}'
const res = await fetch('https://api.apify.com/v2/acts/automation_craft~craigslist-scraper/run-sync-get-dataset-items', {
method: 'POST',
headers: { Authorization: 'Bearer <YOUR_API_TOKEN>', 'Content-Type': 'application/json' },
body: JSON.stringify({ areas: ['sfbay'], categories: ['cta'], maxItems: 20 }),
});
const rows = await res.json();
console.log(rows.filter((r) => r.type === 'listing'));
import requests
res = requests.post(
"https://api.apify.com/v2/acts/automation_craft~craigslist-scraper/run-sync-get-dataset-items",
headers={"Authorization": "Bearer <YOUR_API_TOKEN>"},
json={"areas": ["sfbay"], "categories": ["cta"], "maxItems": 20},
timeout=330,
)
postings = [r for r in res.json() if r["type"] == "listing"]

Changelog

See the Changelog tab. 0.1: first release.

More data tools by Automation Craft