# Craigslist Listings Scraper - Housing, For Sale, Jobs, Cars (`confidential_gnat/craigslist-listings-scraper`) Actor

Scrapes Craigslist (craigslist.org) classified listings in any city and category: title, price, location, coordinates, address, bedrooms, square feet, attributes, description, images and posted date. Search by area, keyword and filters, a search URL or a posting URL.

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

## Pricing

from $0.30 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Craigslist Listings Scraper - Housing, For Sale, Jobs, Cars

**Scrape Craigslist listings from craigslist.org** in any city and any category: apartments and housing, items for sale, cars and trucks, jobs, gigs and services. Each **Craigslist listing** comes out with title, price, location, coordinates, street address, bedrooms, square feet, attributes, full description, photos and posted date, ready to export as JSON, CSV or Excel or to call as a **Craigslist API**. Type an area such as newyork and a keyword, or paste a Craigslist search URL, and press Start.

**Target website:** [craigslist.org](https://www.craigslist.org)

### ⚖️ Is it legal to scrape Craigslist?

This actor only collects listings that are publicly visible on craigslist.org, with no login and no private content. Scraping publicly available data is generally considered lawful (see *hiQ Labs v. LinkedIn*), but you are responsible for following Craigslist's Terms of Service and laws such as GDPR or CCPA if you process personal data.

### ✨ Features of this Craigslist listings scraper

- **Craigslist listing extraction** — title, price, currency, area, subarea, category, neighborhood, latitude and longitude, address, bedrooms, bathrooms, square feet, attributes (condition, make, odometer, laundry, parking...), description, photos, posted and updated dates.
- **Any city, any category** — search one or many Craigslist areas (newyork, sfbay, chicago, london, toronto...) in any category code (sss, apa, hhh, cta, jjj...) or paste search URLs in the new or the old URL format.
- **Pagination support** — goes through result pages until Max items is reached, up to the 10,000 results Craigslist shows per search.
- **Keyword, price and housing filtering** — keywords, titles only, min and max price, min and max bedrooms, cats OK, dogs OK, has image, posted today, ZIP code with search distance and sort order.
- **Only new listings on scheduled runs** — a cache project name skips listings you already scraped, and they are not charged.
- **Proxy support** — runs without a proxy by default; switch on Apify Proxy for large runs.
- **No browser required** — plain HTTP requests keep runs fast and cheap.

### 🚀 How to scrape Craigslist listings in 5 steps

1. [Sign up](https://apify.com/sign-up) for a free Apify account — includes **$5 monthly credit**.
2. Open the actor page and click **Try for free**.
3. Fill in the **Input** fields (an area or a Craigslist search or posting URL is required).
4. Click **Start** and wait for the run to complete.
5. Download results from the **Output** tab in JSON, CSV, or Excel format.

You can also run this actor via the [Apify API](https://docs.apify.com/api/v2) or integrate it directly into your workflows using [Zapier](https://zapier.com/apps/apify), [Make](https://www.make.com/), or [n8n](https://n8n.io/).

### 💰 Craigslist scraper pricing

This actor uses **pay-per-result** billing: you pay for each listing saved to the dataset.

- New Apify accounts include **$5 of free monthly credit**.
- It uses plain HTTP requests instead of a headless browser, so it costs significantly less to run than browser-based scrapers.
- Proxies are off by default, which keeps runs cheapest.
- Listings skipped by the cache are not charged (see below).

### ♻️ Scrape only new Craigslist listings with the cache (no repeat charges)

Set a **Cache project name** (for example `sfbay-apartments`) and the scraper remembers every listing it saves under that name. On every later run with the same name:

- **Already-scraped listings are skipped** — they are not saved again, so you never get duplicates across runs.
- **Skipped listings cost nothing** — you only pay for listings saved to the dataset, and cached ones are never saved.
- **Max items counts only new listings** — the scraper keeps paging past cached listings until it finds Max items new ones (or the search runs out).
- **New listings are marked** — each saved record gets `changeType: "new"`.

**Example:** a daily schedule on an SF Bay Area apartments search with Max items `50`. Day 1 saves 50 listings. On day 2 the same 50 are skipped for free, and you get and pay for only the next 50 new ones.

The cache is a named key-value store in your own Apify account (`craigslist-<your project name>`). Use a different name for each separate search you want to track, and use a new name (or delete that store) to start from scratch. Leave the field empty to scrape everything on every run.

### 🔧 Craigslist scraper input configuration

| Field | Type | Required | Default | Description |
| ----- | ---- | -------- | ------- | ----------- |
| Search or posting URLs (`startUrls`) | array | — | `[]` | Craigslist search URLs or single posting URLs. Filters inside a search URL are kept. |
| Areas (`areas`) | array | — | `["newyork"]` (prefill) | Craigslist area hostnames to search, e.g. newyork, sfbay, chicago, london. Each area is searched separately. |
| Category (`category`) | string | — | `sss` | Category code used with Areas: sss (for sale), apa (apartments), hhh (housing), cta (cars and trucks), bia (bicycles), jjj (jobs), ggg (gigs), bbb (services). Hub names such as studio-apartment work too. |
| Search keywords (`searchQuery`) | string | — | `bike` (prefill) | Keywords to search for in the chosen areas. |
| Max items per search (`maxItems`) | integer | — | `5` | Maximum unique listings saved for each area or search URL. |
| Cache project name (`cacheProjectName`) | string | — | — | Same name on every run skips listings already scraped; they are not charged and do not count towards Max items. |
| Scrape full posting (`scrapeDetails`) | boolean | — | `true` | Open every posting for the description, address, attributes, bathrooms, all photos and dates. |
| Search titles only (`titlesOnly`) | boolean | — | `false` | **Search filters** section. Match the keywords in listing titles only. |
| Min price (`minPrice`) | integer | — | — | Lowest price, in the area's currency. |
| Max price (`maxPrice`) | integer | — | — | Highest price, in the area's currency. |
| Min bedrooms (`minBedrooms`) | integer | — | — | Housing categories only. |
| Max bedrooms (`maxBedrooms`) | integer | — | — | Housing categories only. |
| Cats OK (`catsOk`) | boolean | — | `false` | Housing only: listings that allow cats. |
| Dogs OK (`dogsOk`) | boolean | — | `false` | Housing only: listings that allow dogs. |
| Has image (`hasImage`) | boolean | — | `false` | Only listings with at least one photo. |
| Posted today (`postedToday`) | boolean | — | `false` | Only listings posted today. |
| ZIP / postal code (`postal`) | string | — | — | Search around this ZIP or postal code. |
| Search distance (`searchDistance`) | integer | — | — | Radius around the ZIP code (miles in the US). |
| Sort by (`sort`) | string | — | — | date, dateoldest, priceasc, pricedsc or rel. Empty uses the site default. |
| Proxy configuration (`proxyConfiguration`) | object | — | `{"useApifyProxy": false}` | **Proxy** section. Craigslist works without a proxy for normal runs. |
| Max concurrency (`maxConcurrency`) | integer | — | `5` | API only: maximum parallel requests. |

The **Search filters** apply to searches built from Areas, Category and Search keywords. Search URLs keep the filters already in the URL.

**Supported URL types:**

- New search URLs: `https://www.craigslist.org/search/area/sfbay?cat=apa`, `https://www.craigslist.org/search/subarea/sfc?cat=apa`, `https://www.craigslist.org/search/area/sfbay?hub=studio-apartment`
- Old search URLs: `https://sfbay.craigslist.org/search/apa?query=loft`, `https://sfbay.craigslist.org/search/sfc/apa`
- Posting URLs: `https://www.craigslist.org/view/d/<title>/<id>` and the old `https://sfbay.craigslist.org/eby/apa/d/<title>/7977442854.html`

### 📦 Craigslist scraper output data

Each listing is one JSON record with the fields `id`, `uuid`, `url`, `title`, `price`, `priceText`, `currency`, `area`, `subarea`, `category`, `categoryName`, `location`, `neighborhood`, `latitude`, `longitude`, `streetAddress`, `city`, `region`, `postalCode`, `country`, `bedrooms`, `bathrooms`, `sqft`, `attributes`, `description`, `images`, `postedAt`, `updatedAt`, `petsAllowed`, `smokingAllowed`, `scrapedAt` and, with a cache project name, `changeType`. The dataset has 1 view: **Overview**, a compact table with the ID, title, price, area, location, category, bedrooms, square feet, posted date, change type and URL.

**Output at a glance:**

| Title | Price | Location | Category | Posted |
| ----- | ----- | -------- | -------- | ------ |
| [Bike 1978 Schwinn Fairlady](https://www.craigslist.org/view/d/new-york-bike-1978-schwinn-fairlady/62r36ZTsGtipf5FhsYMacA) | — | Upper West Side | bicycles - by owner | 2026-08-11 |
| [Bike Schwinn 1970s Mellow Yellow Lowrider](https://www.craigslist.org/view/d/new-york-bike-schwinn-1970s-mellow/fTvRzcxxcBubmbkd4To3Ey) | — | Upper West Side | bicycles - by owner | 2026-10-11 |
| [Bike BMX Mongoose Lowrider](https://www.craigslist.org/view/d/new-york-bike-bmx-mongoose-lowrider/cSe4sDpUtyP5gPLY1RmH7s) | $150 | Upper West Side | bicycles - by owner | 2026-08-02 |
| [2 Motors for Bikes,Go-Peds,Scooters.](https://www.craigslist.org/view/d/new-york-motors-for-bikesgo-pedsscooters/o1rYphBeZtLCR7JU5A7HqP) | $150 | Upper West Side | bicycles - by owner | 2026-10-14 |
| [Bikes Schwinn Muscle](https://www.craigslist.org/view/d/new-york-bikes-schwinn-muscle/9td6BYSFyQUBjWJ3ewbbXc) | — | Upper West Side | bicycles - by owner | 2026-05-23 |

**Sample output (raw JSON):**

```json
{
    "id": "7983498744",
    "uuid": "o1rYphBeZtLCR7JU5A7HqP",
    "url": "https://www.craigslist.org/view/d/new-york-motors-for-bikesgo-pedsscooters/o1rYphBeZtLCR7JU5A7HqP",
    "title": "2 Motors for Bikes,Go-Peds,Scooters.",
    "price": 150,
    "priceText": "$150",
    "currency": "USD",
    "area": "newyork",
    "subarea": "mnh",
    "category": "bia",
    "categoryName": "bicycles - by owner",
    "location": "Upper West Side",
    "neighborhood": "Upper West Side",
    "latitude": 40.7975,
    "longitude": -73.9683,
    "streetAddress": "102st",
    "city": "New York",
    "region": "NY",
    "postalCode": "10025",
    "country": "US",
    "bedrooms": null,
    "bathrooms": null,
    "sqft": null,
    "attributes": [
        "condition: good"
    ],
    "description": "Two motors,both working as of last summer. Drained fuel for storage. Both have brackets to mount on a bike. Everything in pics will be in a storage bin ready to go.",
    "images": [
        "https://images.craigslist.org/00808_hF5vuOaM7Jn_0CI0sy_600x450.jpg",
        "https://images.craigslist.org/00505_9ppXcnnZ4Kq_0nz0t2_600x450.jpg"
    ],
    "postedAt": "2026-10-14T18:04:17.000Z",
    "updatedAt": "2026-10-14T18:08:17.000Z",
    "petsAllowed": null,
    "smokingAllowed": null,
    "scrapedAt": "2026-10-14T18:17:54.689Z"
}
```

### 🐍 How to scrape Craigslist with Python, JavaScript or the API

Run the actor programmatically with the official Apify clients. Replace `<YOUR_API_TOKEN>` with the token from your [Apify Console](https://console.apify.com/account/integrations).

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run = client.actor("confidential_gnat/craigslist-listings-scraper").call(run_input={
    "areas": ["newyork"],
    "category": "sss",
    "searchQuery": "bike",
    "maxItems": 20,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript** (`npm install apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

const run = await client.actor('confidential_gnat/craigslist-listings-scraper').call({
    areas: ['newyork'],
    category: 'sss',
    searchQuery: 'bike',
    maxItems: 20,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**cURL** — start a run and wait for the dataset:

```bash
curl -X POST "https://api.apify.com/v2/acts/confidential_gnat~craigslist-listings-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"areas": ["newyork"], "category": "sss", "searchQuery": "bike", "maxItems": 20}'
```

### 💡 What you can use Craigslist listings data for

- Rental market research: rents, bedrooms, square feet and pet policies by city and neighborhood.
- Used car and resale price tracking by make, model, condition and odometer.
- Deal alerts: scheduled runs that return only new listings for a keyword and price range.
- Lead generation for movers, dealers, landlords and service businesses.
- Mapping supply with the latitude and longitude of each listing.

Real estate investors, property managers, car dealers, resellers, market researchers and data teams use Craigslist classifieds data to watch prices and inventory across US, Canadian and international cities.

### ⚠️ Limitations & known issues

- **No contact details** — phone numbers and reply emails sit behind Craigslist's reply button and are not collected.
- **10,000 results per search** — Craigslist shows at most 10,000 results for one search; split large searches by subarea or price range.
- **Rate limiting** — Craigslist can slow down or block very fast crawlers; keep concurrency moderate and enable a proxy for large runs.
- **Search-only runs** — with Scrape full posting off, the description, street address, attributes, bathrooms and posted date stay empty.

### ❓ Frequently asked questions

#### What data does the Craigslist scraper return?

Every listing gets its ID, URL, title, price, currency, area, subarea, category, location, neighborhood, coordinates, bedrooms, square feet and photos. With Scrape full posting on (the default) you also get the description, street address, city, ZIP code, bathrooms, all attributes, pet and smoking policy and the posted and updated dates.

#### How many listings can I scrape from one Craigslist search?

Max items limits the listings saved for each area or each search URL, so three areas with Max items 100 give up to 300 listings. Craigslist itself shows at most 10,000 results per search.

#### Do I need a proxy to scrape craigslist.org?

No. The default input has the proxy switched off and normal runs work fine. For large runs or if requests start failing, enable Apify Proxy with the datacenter group.

#### How do I scrape Craigslist with Python?

Use the Python example above: call the actor with your input through the Apify client and iterate over the items of the run's dataset.

#### Can I run this Craigslist scraper on a schedule?

Yes, with Apify Schedules. Set a cache project name and keep it the same on every run: listings already scraped under that name are skipped, not charged and not counted towards Max items, and new ones get `changeType: "new"`.

#### What output formats are supported?

JSON, CSV, Excel, XML and RSS, either from the **Output** tab or through the Apify API.

#### Can I get the seller's phone number or email from Craigslist?

No. Craigslist hides contact details behind its reply button, so the scraper returns the public listing data only.

### 🔗 Other actors you may find useful

| Scraper | Description |
| ------- | ----------- |
| [🛍️ Carousell Products Scraper](https://apify.com/confidential_gnat/carousell-products-scraper) | Marketplace listings from Carousell.sg by category, search or listing URL: title, price, seller rating, condition, photos and likes. |
| [🚗 Copart Search Scraper](https://apify.com/confidential_gnat/copart-search-scraper) | Salvage and used vehicle auction lots from Copart: damage, odometer, current bid, sale date, yard, photos and VIN decoding. |
| [🏁 Cheapest Cars & Bids Scraper](https://apify.com/confidential_gnat/cheapest-carsandbids-scraper) | The cheapest vehicle listings from Cars & Bids, to find the best-value auction deals. |
| [🏠 OnTheMarket Property Scraper](https://apify.com/confidential_gnat/onthemarket-property-scraper) | UK property listings for sale and rent: price, address, GPS, bedrooms, agent contacts, floorplans and EPC. |
| [💼 Dice Jobs Scraper](https://apify.com/confidential_gnat/dice-jobs-scraper) | Tech job listings from Dice: title, company, location, salary, skills, remote status and full description. |

### 💬 Support & contact

If you encounter any issues or have questions, please [open an issue](https://apify.com/confidential_gnat/craigslist-listings-scraper/issues/open) or reach out via the [Apify Community Forum](https://community.apify.com/).

You can also find more of our actors on the [Actor Flow](https://apify.com/confidential_gnat) page.

# Actor input Schema

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

Craigslist search URLs (for example https://www.craigslist.org/search/area/sfbay?cat=apa or the older https://sfbay.craigslist.org/search/apa?query=loft) or single posting URLs (https://www.craigslist.org/view/d/... or https://sfbay.craigslist.org/eby/apa/d/.../7977442854.html). Filters in a search URL are kept.

## `areas` (type: `array`):

Craigslist area hostnames to search, for example newyork, sfbay, chicago, losangeles, london, toronto. The hostname is the first part of the area's old address (newyork.craigslist.org). Each area is searched separately with the category and filters below.

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

Craigslist category code used with Areas, for example sss (all for sale), apa (apartments for rent), hhh (all housing), cta (cars and trucks), bia (bicycles), jjj (all jobs), ggg (gigs), bbb (services), ccc (community). A hub name such as studio-apartment also works.

## `searchQuery` (type: `string`):

Keywords to search for in the chosen areas, for example bike or honda civic.

## `maxItems` (type: `integer`):

Maximum unique listings saved for each area or search URL. Craigslist shows at most 10,000 results per search.

## `cacheProjectName` (type: `string`):

Use the same name on each scheduled run to get only new listings. Listings already scraped under this name are skipped and not charged, and they do not count towards Max items. Each record gets changeType: new.

## `scrapeDetails` (type: `boolean`):

Open every posting to get the description, street address, attributes, bathrooms, all photos, posted and updated dates. Turn off for faster, cheaper runs with the search data only. Posting URLs always include the details.

## `titlesOnly` (type: `boolean`):

Match the keywords in listing titles only.

## `minPrice` (type: `integer`):

Lowest price, in the area's currency.

## `maxPrice` (type: `integer`):

Highest price, in the area's currency.

## `minBedrooms` (type: `integer`):

Housing categories only.

## `maxBedrooms` (type: `integer`):

Housing categories only.

## `catsOk` (type: `boolean`):

Housing categories only: listings that allow cats.

## `dogsOk` (type: `boolean`):

Housing categories only: listings that allow dogs.

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

Only listings with at least one photo.

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

Only listings posted today.

## `postal` (type: `string`):

Search around this ZIP or postal code (use with Search distance).

## `searchDistance` (type: `integer`):

Radius around the ZIP / postal code, in the area's distance unit (miles in the US).

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

Order of the results. Leave empty for the site default (newest first, or relevance for keyword searches).

## `proxyConfiguration` (type: `object`):

Craigslist works without a proxy for normal runs. Enable Apify Proxy (datacenter) for large runs or if you get blocked.

## Actor input object example

```json
{
  "startUrls": [],
  "areas": [
    "newyork"
  ],
  "category": "sss",
  "searchQuery": "bike",
  "maxItems": 5,
  "scrapeDetails": true,
  "titlesOnly": false,
  "catsOk": false,
  "dogsOk": false,
  "hasImage": false,
  "postedToday": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (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 = {
    "areas": [
        "newyork"
    ],
    "searchQuery": "bike",
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("confidential_gnat/craigslist-listings-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 = {
    "areas": ["newyork"],
    "searchQuery": "bike",
    "maxItems": 5,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("confidential_gnat/craigslist-listings-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 '{
  "areas": [
    "newyork"
  ],
  "searchQuery": "bike",
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call confidential_gnat/craigslist-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,confidential_gnat/craigslist-listings-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/DluElVvb8oYHKEieS/builds/7eIVHM9sP1essf4YH/openapi.json
