# Craigslist Scraper | Listings, Prices & Details (`datascraperes/craigslist-scraper`) Actor

Collect Craigslist listings across 50 US and Canadian regions. Search cars, housing, jobs, electronics, furniture, services, gigs and events with keyword, price, condition, image and date filters. Export unique listings with descriptions, images, post IDs, locations and category-specific attributes.

- **URL**: https://apify.com/datascraperes/craigslist-scraper.md
- **Developed by:** [DataScraperES](https://apify.com/datascraperes) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 craigslist listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Collect **Craigslist listings with prices, descriptions, images and category-specific attributes**. Choose a city and category, add optional filters, or paste search and posting URLs. Export unique results for market research, inventory monitoring and classifieds analysis.

### What this Actor does

The Actor searches Craigslist and returns one Dataset item per unique posting. The city selector contains 50 presets: 44 US regions and six Canadian regions. Categories cover general sale listings, cars and trucks, electronics, furniture, apartments and houses, rooms, sublets, jobs, gigs, services, community, resumes and events.

You can collect search-listing information alone or request full posting details. Full details include the published description, category-specific attributes, available gallery images, posting dates and location information. Phone numbers and email addresses are extracted only when present in the public description.

### Use cases

- Compare advertised vehicle prices, condition and mileage across cities.
- Monitor housing listings by asking price, bedrooms and published features.
- Collect job and gig descriptions with compensation when disclosed.
- Track second-hand product availability and asking prices.
- Build a deduplicated classifieds dataset with links back to each posting.

### How to use

1. Choose a **City / region** and **Category**, then optionally enter a keyword. Alternatively, paste Craigslist search or posting URLs.
2. Set **Maximum results** and choose whether to include full details.
3. Click **Start** and open the Dataset when the run finishes.
4. Download results in JSON, CSV or Excel. Check the run summary if any sources or details could not be retrieved.

The run log shows processed listings versus the requested limit, percentage, successful and failed sources, collection speed, estimated time remaining and elapsed time. Updates are sent periodically while work is in progress. The final message distinguishes completion, an empty search and collection problems.

### Input

| Field | Default | Behavior |
|---|---|---|
| `startUrls` | Empty | Up to 100 search, category or posting URL strings. URL filters are preserved. When supplied, all guided search settings below are ignored. |
| `region` | `newyork` | One of the 50 preset regions. |
| `category` | `sss` | Top-level category code: `sss` For sale, `cta` Cars & trucks, `ela` Electronics, `fua` Furniture, `apa` Apartments & houses, `roo` Rooms & shares, `sub` Sublets & temporary, `jjj` Jobs, `ggg` Gigs, `bbb` Services, `ccc` Community, `rrr` Resumes, `eee` Events. Use `startUrls` for a specific subcategory. |
| `searchTerm` | Empty | Optional keyword, up to 500 characters. |
| `priceMin`, `priceMax` | Unset | Price range in the listing's local currency, for applicable categories. |
| `condition` | `any` | `new`, `like-new`, `excellent`, `good`, `fair` or `salvage`, where supported. |
| `hasImage`, `postedToday` | `false` | Apply Craigslist's corresponding search filters. |
| `sort` | `date` | Newest, relevance (`rel`), lowest price (`priceasc`) or highest price (`pricedsc`). |
| `includeDetails` | `true` | Fetch full posting details. Individual posting URLs always receive detail extraction. |
| `maxResults` | `200` | Strict global limit across all sources. `0` allows up to 100,000 unique rows. |
| `includeNearby` | `false` | Include nearby-area suggestions when Craigslist supplies them. |

The same posting appears only once across the run. Sources are processed in input order; the result limit can be reached before later sources are searched. Sorting applies within each search, not across all regions combined. The 100,000-row limit is an Actor safety cap, not a promise that Craigslist exposes that many matches.

The Canadian presets are Montreal, Toronto, Vancouver, Calgary, Ottawa and Edmonton. US presets include New York, Los Angeles, Chicago, San Francisco Bay Area, Seattle, Boston, Miami, Dallas, Houston and the other regions in the selector. Pasted URLs may identify additional Craigslist areas, but coverage outside the presets is not comprehensively verified.

Example input:

```json
{
  "region": "seattle",
  "category": "ela",
  "searchTerm": "20uf",
  "maxResults": 1
}
```

### Output

Results are stored in the default Dataset. Each item identifies the original posting and the search or URL that produced it. Prices use the listing's local currency and are not converted to US dollars. Category attributes vary by posting, and absent information remains `null`, an empty array or an empty object.

`detailsStatus` distinguishes complete detail extraction (`ok`), listing-only output (`not_requested`), confirmed deletion (`deleted`) and detail retrieval problems such as `not_found`, `blocked` or `network_error`. If an optional detail request fails, the valid search listing is retained with the failure status. A direct URL that cannot be retrieved produces a summary error rather than an invented listing.

`isDeleted` is `true` only for an explicit deletion message, `false` for a valid fetched posting, and otherwise unknown (`null`). `isNearby` marks suggestions from outside the requested area. `contactObfuscated` is `false` when public contact text was found, `true` when only a reply button was observed, and otherwise `null`. Contact extraction does not verify ownership or deliverability.

Craigslist may show a **Reply** button without publishing the seller's email address or phone number in the public posting. The Actor does not open that private reply flow, solve its verification challenge or reconstruct its relay address. In those cases `emails` and `phoneNumbers` correctly remain empty arrays; `replyToken` identifies the public reply link and is not a contact address.

This is the complete Dataset item from a real successful run:

```json
{
  "url": "https://www.craigslist.org/view/d/clinton-new-20uf-400v-motor-start-run/jcKfSpd4HtqMRBcrfaqHjX",
  "postId": "7926770440",
  "title": "NEW!!! 20uf 400V Motor Start run Capacitor",
  "price": 25.0,
  "currency": "USD",
  "region": "seattle",
  "categorySlug": "ela",
  "categoryLabel": "Electronics",
  "subcategorySlug": "ele",
  "subcategoryLabel": "electronics - by owner",
  "location": "South End of Whidbey",
  "neighborhood": null,
  "latitude": 47.9508,
  "longitude": -122.3916,
  "mapAccuracy": null,
  "postedAt": "2026-04-09T20:13:58-0700",
  "updatedAt": "2026-09-05T08:41:45-0700",
  "description": "*** if you are reading this the item is still available***\nWhat you see is what you get. I am assuming if you are reading this then you are familiar with what you are looking at so no other description should be needed.",
  "attributes": {},
  "imageUrls": [
    "https://images.craigslist.org/00d0d_9llB9E1MrRC_0oZ0t2_600x450.jpg",
    "https://images.craigslist.org/00h0h_jOekMWAiA3s_0ki0t2_600x450.jpg",
    "https://images.craigslist.org/00s0s_gMRdXUH4WJP_0bh0oN_600x450.jpg",
    "https://images.craigslist.org/01111_jy8jhXGnKU9_0k80eR_600x450.jpg"
  ],
  "hasImages": true,
  "phoneNumbers": [],
  "emails": [],
  "contactObfuscated": true,
  "replyToken": "sea/ele/7926770440",
  "sellerListingsUrl": null,
  "isDeleted": false,
  "isNearby": false,
  "detailsStatus": "ok",
  "sourceUrl": "https://www.craigslist.org/search/area/seattle?cat=ela&sort=date&query=20uf",
  "scrapedAt": "2026-09-05T18:15:35.875261+00:00"
}
```

### Pricing

The Actor charges for each unique listing delivered to the Dataset. The active introductory price is $0.001 per listing ($1.00 per 1,000 listings). Apify has scheduled the following tiered prices for the next pricing period:

| Tier | Price per listing | Equivalent per 1,000 listings |
|---|---:|---:|
| Free | $0.001000 | $1.00 |
| Bronze | $0.000950 | $0.95 |
| Silver | $0.000900 | $0.90 |
| Gold | $0.000850 | $0.85 |
| Platinum | $0.000850 | $0.85 |
| Diamond | $0.000850 | $0.85 |

The equivalent column is only a comparison; billing remains per delivered listing. Empty searches, failed requests, discarded duplicates and run-summary records are not charged. A valid search listing can still be returned when its optional detail enrichment fails; check `detailsStatus` when evaluating these results. Check the **Pricing** tab for the effective tier and current billing details before starting a run.

### Related Actors

| Actor | Best for |
|---|---|
| [Built In Jobs Scraper | Salaries & Skills](https://apify.com/datascraperes/builtin-jobs-scraper) | Research technology jobs with employers, skills and published salary information. |
| [Fotocasa Spain Property Listings Scraper](https://apify.com/datascraperes/fotocasa-property-search-scraper) | Collect Spanish property listings with prices, rooms, photos and agency information. |

### Limits and data quality

Default memory is 256 MB, with a supported range of 256–512 MB.

Craigslist listings change while a run is in progress. Counts, ordering and availability can differ between requests. Seller-entered prices, condition and attributes are returned as published; a low price may describe a payment or deposit rather than the full purchase price. Keywords can match description text, so a matching title is not required.

Coordinates describe the location published by Craigslist and should not be treated as a verified street address. Search timestamps can differ from the original posting dates available in the full detail page. Image links are returned as supplied or as search-gallery images; their availability can change after extraction.

When Craigslist publishes a neighborhood label, it is returned in `neighborhood`. `mapAccuracy` is the source map precision value when present, and `sellerListingsUrl` is the public link to additional listings by the seller when Craigslist exposes it. These three fields are nullable and are not inferred when the source omits them.

The Actor collects public content without signing in. Email addresses are returned only when the seller publishes them in visible posting text, a public `mailto:` link or an obfuscated form such as `name [at] example [dot] com`. It does not solve CAPTCHAs or reveal contact information hidden behind Craigslist's reply flow. Temporary access failures receive a bounded automatic retry when permitted by the source response. Failed searches are recorded in the summary; successful sources can still return results. Reduce request concurrency and retry later if access is restricted. Long-running stability and maximum coverage depend on source availability.

### Frequently asked questions

#### Does this work in the United States and Canada?

Yes. The region selector contains 44 US presets and six Canadian presets. The currency field distinguishes published USD and CAD prices when that information is available.

#### Can I mix searches and individual posting URLs?

Yes. Supply them as plain strings in `startUrls`. Existing URL filters take precedence over guided search fields, and deduplication applies across the entire run.

#### Can I collect listings without their descriptions?

Yes. Set `includeDetails` to `false` for search URLs. Search fields such as title, price, location, images and posting ID remain available. Individual posting URLs are always fetched as details.

#### Why are there fewer results than requested?

The requested maximum is a cap. Searches may contain fewer matches, duplicate postings, excluded nearby results or unavailable records. Access restrictions and the run's spending limit can also stop collection early.

#### Why are `emails` or `phoneNumbers` empty?

Those fields contain only contact information that the seller publishes in the visible description, a public `mailto:` link or an obfuscated text form. Craigslist often keeps contact details behind its Reply flow, which may require an interactive verification challenge. This Actor leaves that contact hidden and returns empty arrays instead of guessing or exposing a relay token.

### Responsible use

Use the data for lawful purposes and comply with applicable Craigslist terms and privacy requirements. Publicly visible contact information should not be treated as permission for unsolicited messaging. Verify listing details directly before making purchasing, housing or employment decisions.

### Support

Open an issue in the Actor's **Issues** tab with your run ID, a reproducible input and a description of the expected result. Do not include account credentials or other secrets.

### Public guide and API examples

See the [Craigslist Scraper web guide, API examples and sample dataset](https://github.com/datacrawler-edu/craigslist-scraper-python) for no-code instructions, Python, JavaScript and cURL examples, and sanitized output files.

# Actor input Schema

## `startUrls` (type: `array`):

Optional Craigslist search, category or posting URLs. Use one URL per line, for example https://newyork.craigslist.org/search/sss?query=bike or a direct /view/ posting URL. URL filters are preserved and take precedence over region, category, keyword and other guided filters. Leave empty to build a search from the fields below. Maximum 100 URLs.

## `region` (type: `string`):

Select the Craigslist area where the search runs. Example: newyork searches New York City; toronto searches Toronto, Canada. This setting is ignored when startUrls contains a URL.

## `category` (type: `string`):

Choose the top-level Craigslist category to search. Use the code that matches the category: sss = For sale; cta = Cars & trucks; ela = Electronics; fua = Furniture; apa = Apartments & houses; roo = Rooms & shares; sub = Sublets & temporary; jjj = Jobs; ggg = Gigs; bbb = Services; ccc = Community; rrr = Resumes; eee = Events. Example: select cta to collect vehicle listings or jjj to collect jobs. Use startUrls when you need a specific subcategory URL.

## `searchTerm` (type: `string`):

Optional keyword or phrase sent to Craigslist's search filter. Example: enter electric bike to find listings matching those words. Leave empty to collect the newest listings without a keyword. Maximum 500 characters.

## `priceMin` (type: `integer`):

Optional lower bound for the asking price, expressed in the listing region's currency (USD or CAD). Example: 500 returns listings priced at 500 or more. Leave empty when price filtering does not apply.

## `priceMax` (type: `integer`):

Optional upper bound for the asking price, expressed in the listing region's currency (USD or CAD). Example: 2500 returns listings priced up to 2,500. Leave empty when price filtering does not apply; it must be greater than or equal to Minimum price.

## `condition` (type: `string`):

Filter by the condition selected by the seller in supported for-sale categories. Example: choose excellent to keep only listings marked excellent. any leaves all conditions unchanged.

## `hasImage` (type: `boolean`):

When enabled, keep only search results that include at least one Craigslist image. Example: true is useful for photo inventory research; false keeps listings with or without images.

## `postedToday` (type: `boolean`):

When enabled, apply Craigslist's posted-today filter. Example: true returns listings posted during the current day according to Craigslist; false includes older listings.

## `sort` (type: `string`):

Choose the order within each search. date returns newest first (default), rel uses Craigslist relevance, priceasc sorts from lowest to highest price, and pricedsc sorts from highest to lowest. Sorting already present in a startUrl takes precedence.

## `includeDetails` (type: `boolean`):

When true, fetch each posting page to add the published description, category attributes, dates, map data, gallery images and visible contact text. Example: true gives richer records; false is faster and returns search-listing fields only. Direct posting URLs always receive details.

## `maxResults` (type: `integer`):

Maximum number of unique listings written across all supplied sources. Example: 50 stops after 50 rows; 0 enables the safety cap of up to 100,000 rows. The value is global for the whole run, not per URL.

## `includeNearby` (type: `boolean`):

When true, include nearby-area suggestions returned by Craigslist in addition to the selected region. Example: true can broaden a city search; those rows are marked isNearby=true. false keeps only the requested area.

## Actor input object example

```json
{
  "startUrls": [],
  "region": "newyork",
  "category": "sss",
  "priceMax": 1000000000,
  "condition": "any",
  "hasImage": false,
  "postedToday": false,
  "sort": "date",
  "includeDetails": true,
  "maxResults": 20,
  "includeNearby": false
}
```

# Actor output Schema

## `listings` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [],
    "region": "newyork",
    "category": "sss",
    "searchTerm": "",
    "priceMin": 0,
    "priceMax": 1000000000,
    "condition": "any",
    "hasImage": false,
    "postedToday": false,
    "sort": "date",
    "includeDetails": true,
    "maxResults": 20,
    "includeNearby": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascraperes/craigslist-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [],
    "region": "newyork",
    "category": "sss",
    "searchTerm": "",
    "priceMin": 0,
    "priceMax": 1000000000,
    "condition": "any",
    "hasImage": False,
    "postedToday": False,
    "sort": "date",
    "includeDetails": True,
    "maxResults": 20,
    "includeNearby": False,
}

# Run the Actor and wait for it to finish
run = client.actor("datascraperes/craigslist-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [],
  "region": "newyork",
  "category": "sss",
  "searchTerm": "",
  "priceMin": 0,
  "priceMax": 1000000000,
  "condition": "any",
  "hasImage": false,
  "postedToday": false,
  "sort": "date",
  "includeDetails": true,
  "maxResults": 20,
  "includeNearby": false
}' |
apify call datascraperes/craigslist-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datascraperes/craigslist-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ugLULcs9t1tJ1eaAy/builds/426QskrhcXyjPZXlO/openapi.json
