Craigslist Scraper at a glance
Craigslist Scraper is a ready-to-run Apify actor from abotapi for collecting ecommerce data. Its documented output includes kind, recordid, postingid, postinguuid and url, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.00 per 1,000 results on the Apify Free plan and from $1.20 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Ecommerce, Automation, Lead Generation
- Pricing
- $2.00 per 1,000 results (Free plan), from $1.20 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 24 options
Scrape Craigslist postings in any of 700+ cities worldwide: price, title, posting text, attributes, photos, coordinates, neighbourhood and posted date. Search by city, section, keyword and price, or paste search and posting links. Incremental monitoring, resume, MCP export.
What Craigslist Scraper can do
- A whole search in one read. Craigslist answers an entire search's result set in a single read, so a search with several thousand matches comes back complete and you are never charged twice for the same posting.
- Coordinates, neighbourhood and posted time on every row, not only on postings read in full. You are not charged extra to know where a posting is or when it went up.
- The section's real attributes, once you read a posting in full. Cars come back with make and model, year, odometer, title status, fuel, transmission, drivetrain, paint and body type. Housing comes back with bedrooms, bathrooms, move-in date, laundry, parking and pet rules. Jobs come back with compensation, employment type and job title.
- Every city, not just the US. Name a city as sfbay, as SF bay area, or by pasting any link from it. London, Toronto, Berlin, Sydney, Tokyo and 700 more resolve the same way.
- Change monitoring across scheduled runs. Classify every posting as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED, with state kept separately per search so two monitoring campaigns never collide.
- MCP connector export. Pipe a copy of every posting into Notion or another connector you already use, without changing the dataset output.
Choose what to collect
These inputs let you configure Craigslist Scraper - Cars, Housing, Jobs & For Sale. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | Search reads postings from the cities and section you pick. URL mode reads the exact craigslist links you paste. |
citiesarray | City search: one or more craigslist cities, by site name (sfbay, newyork, london), by display name (SF bay area, new york, vancouver, BC) or by pasting any link from that city. 700+ cities across 79 countries are recognised. See the README for how cities are named. |
categorystring | City search: the craigslist section to read, by code or by name. The source requires a section, so this is never empty: leave it alone and the for sale section (sss) is used. Whole sections: sss (for sale), hhh (housing), jjj (jobs), ggg (gigs), bbb (services), ccc (community), eee (events), rrr (resumes). Narrower examples: cta (cars+trucks), apa (apartments / housing for rent), bia (bikes), ela (electronics), fua (furniture), sof (software / QA / DBA). |
querystring | City search: keyword to match in the posting. Leave empty to browse the whole section. |
minPriceinteger | City search: lowest price to return, in the city's own currency. Postings with no price are not returned once a price bound is set. |
maxPriceinteger | City search: highest price to return, in the city's own currency. Postings with no price are not returned once a price bound is set. |
soldBystring | City search: keep only owner postings or only dealer postings. Default keeps both. |
Show 17 more inputs
| Input | What it controls |
|---|---|
hasImageboolean | City search: keep only postings that carry at least one photo. |
postedTodayboolean | City search: keep only postings published today. Useful for a scheduled run that watches a busy section. |
maxAgeinteger | Keep only postings published within this many days (counted from the posted date). Leave empty for no age limit. Applies to search results and to links to a search; a posting link you paste is always read. |
sortBystring | City search: the order the source returns matches in. Newest first is the usual choice for monitoring; relevance is the source default for a keyword search. |
startUrlsarray | URL mode: craigslist search links (https://sfbay.craigslist.org/search/cta?query=truck) or posting links (https://www.craigslist.org/view/d/.../..., or a classic https://sfbay.craigslist.org/eby/bik/d/.../0000000000.html link). Multi-value supported. |
urlsarray | Alias for Craigslist links, accepted under the name other Apify actors use for URL mode. Each entry is a search link or a posting link; entries are read in order. |
maxItemsinteger | Stop after this many records (0 = no limit; the run then returns every posting the searches matched). |
fetchDetailsboolean | Off by default. Turn on to also read every posting in full: the posting text, the attribute list (bedrooms, condition, make and model, fuel, compensation and so on), the display address and the update time. Each read adds one Posting detail event. Posting links pasted in URL mode are always read in full and always charge this event. |
resumeFromRunIdstring | Paste a previous run ID or dataset ID to continue a large pull without returning postings already collected there. |
incrementalModeboolean | Turn this on for daily or recurring monitoring. The first run returns every matching posting as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED postings. A posting counts as UPDATED when any returned field changes (price, title, description, location, photos, attributes and so on); the changed field names are listed in changedFields. The raw detail payload and the HTML copy of the description are never compared (the plain-text description is), and any field you list in Ignore fields never triggers UPDATED, though it stays in the output. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each city, section, filter and link setup; use State key to name or deliberately share a monitoring campaign. |
stateKeystring | Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search and filter settings. |
emitUnchangedboolean | Off by default. Turn on to also return postings that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have. |
emitExpiredboolean | Off by default. Turn on to also return postings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search. |
ignoreFieldsForChangesarray | Optional. Output field names that must never make a posting UPDATED or appear in changedFields, for a field that changes on its own in your setup (for example a photo list). The fields stay in the output. Changing this list never re-bills tracked postings: the stored baseline is compared again with the new list. |
mcpConnectorsarray | Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output. |
notionParentPageUrlstring | URL or id of the Notion page under which posting pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on postings written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
kindkindrecordIdrecordIdpostingIdpostingIdpostingUuidpostingUuidurlurltitletitlepricepricepriceStringpriceStringcurrencycurrencymonthlyPaymentStringmonthlyPaymentStringcategoryIdcategoryIdcategoryAbbrcategoryAbbrShow 53 more fields
categoryNamecategoryNamesectionsectionpostedDatepostedDateupdatedDateupdatedDatecreatedDatecreatedDatecityHostcityHostcityNamecityNameareaIdareaIdareaAbbrareaAbbrsubareaAbbrsubareaAbbrsubareaNamesubareaNameneighborhoodneighborhoodlocationDescriptionlocationDescriptiondisplayAddressdisplayAddresslatitudelatitudelongitudelongitudeimageUrlsimageUrlsimageCountimageCountbedroomsbedroomssqftsqftodometerodometersalarysalarycompanycompanycompanyNamecompanyNamejobTitlejobTitleeventFirstDateeventFirstDateeventLastDateeventLastDateopenHousesopenHouseseventDateseventDatesseoSlugseoSlugdedupeKeydedupeKeydetailLoadeddetailLoadeddescriptiondescriptionattributesattributesattributesByKeyattributesByKeybodyHtmlbodyHtmlrawDetailrawDetailhasContactInfohasContactInfonoticesnoticesrepostOfrepostOfseeMyOtherseeMyOtherchangeTypechangeTypechangedFieldschangedFieldsfirstSeenAtfirstSeenAtlastSeenAtlastSeenAtididdatetimedatetimelocationlocationcategorycategorylabellabelpostpostmapAccuracymapAccuracyphoneNumbersphoneNumbersExample output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"kind": "posting",
"recordId": "7900000000",
"postingId": "7900000000",
"postingUuid": "AbCdEfGhIjKlMnOpQrStUv",
"title": "Example road bicycle, lightly used",
"url": "https://www.craigslist.org/view/d/example-city-bicycle/AbCdEfGhIjKlMnOpQrStUv",
"price": 625,
"priceString": "$625",
"currency": "USD",
"categoryId": 68,
"categoryAbbr": "bik",
"categoryName": "bicycles - by owner",
"section": "for sale",
"postedDate": "2026-09-04T00:00:00+00:00",
"updatedDate": "2026-09-05T00:00:00+00:00",
"createdDate": "2026-09-04T00:00:00+00:00",
"cityHost": "sfbay",
"cityName": "SF bay area",
"areaId": 1,
"subareaAbbr": "eby",
"subareaName": "east bay",
"neighborhood": "example neighbourhood",
"locationDescription": "example town",
"displayAddress": "100 Example Street",
"latitude": 37.7749,
"longitude": -122.4194,
"imageUrls": [
"https://images.craigslist.org/00d0d_example_1200x900.jpg"
],
"imageCount": 1,
"detailLoaded": true,
"description": "Bought new in 2012. Lightly used, excellent condition.",
"bodyHtml": "Bought new in 2012.<br>Lightly used, excellent condition.",
"attributes": [
{
"key": "condition",
"label": "condition",
"value": "good",
"type": "key_value"
}
],
"attributesByKey": {
"condition": "good"
},
"rawDetail": {},
"hasContactInfo": true,
"notices": null,
"repostOf": null,
"seeMyOther": null,
"changeType": "NEW",
"changedFields": [],
"firstSeenAt": "2026-09-04T00:00:00+00:00",
"lastSeenAt": "2026-09-04T00:00:00+00:00"
}Ways to use this data
- Marketplace and resale price research: track asking prices on a make, model, category or neighbourhood over time to spot underpriced listings.
- Housing search automation: watch new apartment or room listings in a metro area on a schedule and get only what is new since the last check.
- Local lead generation: monitor gigs, services or job postings in a city and export the leads straight into Notion or another connector.
- Sourcing across cities: run the same category search over several cities in one job to compare what is available and at what price.
- Market and academic research: build a dataset of classified-ad volume, pricing and category mix for a city or region.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Craigslist Scraper return?
The documented output for Craigslist Scraper includes kind, recordid, postingid, postinguuid, url, title, price and pricestring. Availability of each field depends on the source page and the selected mode.
How much does Craigslist Scraper cost?
It costs $2.00 per 1,000 results on the Apify Free plan and from $1.20 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new or changed postings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental changes for scheduled runs. Later runs return only NEW, UPDATED and REAPPEARED postings; UNCHANGED ones are suppressed and not billed unless you turn on Emit unchanged.
Why does Section never come back empty?
The source refuses a search that names no section, so leaving Section blank does not mean "everything": the actor fills in sss (for sale) for you. Narrow it explicitly with a code such as cta, apa or jjj, or with a section display name.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push postings into Notion or another connector you've authorized.
