# Craigslist Classifieds Scraper with Category Attributes (`vexaloom-labs/craigslist-classifieds-scraper-with-category`) Actor

Scrape Craigslist search results and individual posts across any city subdomain, with category-specific attributes for jobs, housing, autos, and for-sale posts. No login or proxy required.

- **URL**: https://apify.com/vexaloom-labs/craigslist-classifieds-scraper-with-category.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** Automation, Lead generation, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 Classifieds Scraper with Category Attributes

Scrape **Craigslist** across 700+ local sites without a login, cookie, or proxy setup. Search by keyword or browse a category, follow individual post links, and get the full listing: price, description, every photo, map coordinates, posted and repost data, plus the category-specific attributes Craigslist shows for jobs, housing, autos, and for-sale items.

### What this actor does

- **Four modes:** keyword search, category browse, specific URLs, and a region/subarea reference list
- **700+ regions:** every Craigslist hostname, with 62 common regions ready in a dropdown and a custom-region field for the rest
- **Filters that run on Craigslist:** price, posted today, photos, titles-only, owner/dealer, sort, condition, bedrooms/baths/square feet, vehicle make/year/mileage, postal radius, and duplicate grouping
- **Full detail records:** body text, gallery images, attributes, coordinates, display address, repost link, notices, and typed category fields
- **Empty fields are omitted** from every record; no `null` values or placeholder rows

### Output per listing

- `type` — always `craigslist_listing`
- `id`, `postingUuid`, `url`, `title`
- `price`, `priceValue`, `priceCurrency`, `priceQualifier`
- `postedAt`, `updatedAt`, `recordCreatedAt`, `scrapedAt`
- `region`, `location`, `neighborhood`, `subArea`, `area`, `areaAbbr`, `locationType`, `mapAddress`
- `latitude`, `longitude`
- `category`, `subcategory`, `section`, `categoryAbbr`, `subcategoryAbbr`, `postingType`
- `description`, `images[]`, `imageCount`, `attributes`, `notices[]`
- `phoneNumbers[]`, `emails[]`, `vin`, `replyUrl`
- `repostOf`, `hasContactInfo`, `seeMyOther`
- Jobs: `compensation`, `employmentType`, `jobTitle`, `companyName`, `experienceLevel`, `salary`
- Housing: `bedroomCount`, `bathroomCount`, `sqft`, `availableDate`, `housingType`, `laundry`, `parking`, `rentPeriod`, `listedBy`, `applicationFee`, `brokerFee`, `openHouseDates`, `catsOk`, `dogsOk`, `furnished`, `smoking`, `privateRoom`, `privateBath`, `wheelchairAccessible`, `airConditioning`, `evCharging`
- Autos: `yearManufactured`, `makeManufacturer`, `modelName`, `odometer`, `transmission`, `fuelType`, `titleStatus`, `cylinders`, `paintColor`, `drive`, `vehicleType`
- For sale: `condition`, `size`, `make`, `model`

With `includeDetails` off, rows contain only the search-card fields: identity, price, category, posted time, location, coordinates, and image URLs.

### Output per area (mode = `areas`)

- `type` — `craigslist_area`
- `areaId`, `abbreviation`, `hostname`, `description`, `shortDescription`
- `region`, `country`, `latitude`, `longitude`, `timezone`
- `subareas[]` — each with `abbreviation`, `description`, and `subAreaId`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `category` / `byUrl` / `areas` |
| `region` | string | `sfbay` | Common Craigslist region (mode=search/category) |
| `customRegion` | string | – | Any hostname or abbreviation; overrides `region` |
| `subarea` | string | – | Optional subarea such as `sfc`, `eby`, `brk` |
| `category` | string | `sss` | Craigslist category; `sss` is all for-sale listings |
| `searchQueries` | array | – | One or more keywords (mode=search); leave empty to browse a category |
| `startUrls` | array | – | Search pages or post URLs (mode=byUrl) |
| `minPrice` | integer | – | Minimum price |
| `maxPrice` | integer | – | Maximum price |
| `postedToday` | boolean | `false` | Only posts from the last 24 hours (Craigslist's posted-today filter) |
| `hasImage` | boolean | `false` | Only posts with a photo |
| `titlesOnly` | boolean | `false` | Match keywords against titles only |
| `sellerType` | string | `all` | `all` / `owner` / `dealer` |
| `sortBy` | string | `newest` | `newest` / `oldest` / `relevance` / `priceAsc` / `priceDesc` / `distance` |
| `condition` | string | `any` | `any` / `new` / `like-new` / `excellent` / `good` / `fair` / `salvage` |
| `minBedrooms` | integer | – | Housing only |
| `maxBedrooms` | integer | – | Housing only |
| `minBathrooms` | integer | – | Housing only |
| `maxBathrooms` | integer | – | Housing only |
| `minSqft` | integer | – | Housing only |
| `maxSqft` | integer | – | Housing only |
| `autoMakeModel` | string | – | Auto categories only, e.g. `honda civic` |
| `minAutoYear` | integer | – | Auto categories only |
| `maxAutoYear` | integer | – | Auto categories only |
| `maxAutoMiles` | integer | – | Auto categories only |
| `postalCode` | string | – | Optional ZIP/postal code anchor |
| `searchRadiusMiles` | integer | – | Radius around `postalCode` |
| `hideDuplicates` | boolean | `false` | Group duplicate/reposted listings |
| `deliveryAvailable` | boolean | `false` | For-sale/auto only |
| `cryptoOk` | boolean | `false` | For-sale/auto only |
| `countryCode` | string | – | Two-letter country filter for `areas` mode |
| `maxItems` | integer | `100` | Hard cap across all queries and URLs (1–10000) |
| `includeDetails` | boolean | `true` | Fetch full descriptions, attributes, images, and coordinates |

### Examples

#### Search a city for a keyword

```json
{
  "mode": "search",
  "region": "sfbay",
  "category": "sss",
  "searchQueries": ["bike"],
  "maxItems": 50,
  "includeDetails": true
}
```

#### Browse apartments with housing filters

```json
{
  "mode": "category",
  "region": "chicago",
  "category": "apa",
  "minBedrooms": 2,
  "maxBedrooms": 2,
  "maxPrice": 3000,
  "sortBy": "priceAsc",
  "maxItems": 100
}
```

#### Scrape specific posts

```json
{
  "mode": "byUrl",
  "startUrls": [
    { "url": "https://www.craigslist.org/view/d/richmond-195-iron-horse-maverick-21/scJ6mscDAryikpFRAS61aq" },
    { "url": "https://sfbay.craigslist.org/bik/7962037752.html" }
  ],
  "maxItems": 10
}
```

#### List regions in one country

```json
{
  "mode": "areas",
  "countryCode": "CA",
  "maxItems": 100
}
```

### Use cases

- **Marketplace price tracking** — monitor asking prices for a product across cities and categories
- **Vehicle shopping** — pull year, make, model, mileage, transmission, and title status for matching cars
- **Rental research** — collect rent, bedrooms, bathrooms, square footage, laundry, parking, and pet policy
- **Job aggregation** — gather compensation, employment type, experience level, and company names
- **Lead sourcing** — filter by price, photos, seller type, and posted date to find fresh posts
- **Local market mapping** — join listing coordinates and neighborhoods to city/subarea reference data

### FAQ

**Do I need a Craigslist account, cookie, or proxy?**
No. The actor reads public Craigslist listings and connects automatically. There is no login or proxy field to fill in.

**How many results can one run return?**
Craigslist caps a single search at 10,000 results. To collect more, split by category, subarea, price range, or posted-today and combine the runs. The actor tells you in the run status when the cap is reached.

**Why are some fields missing from a row?**
Craigslist posts differ by category and by what the seller filled in. A job may have no price; a generic for-sale post may have no structured attributes; a seller may not publish a phone number. Empty fields are omitted rather than filled with `null` or an empty value.

**Can I get the poster's email address?**
Only when the seller typed an email into the post body. Craigslist's reply relay hides the real address behind its own form and sometimes a captcha; this actor does not bypass that.

**Does the actor support RSS or JSON feeds?**
No. Craigslist discontinued its RSS output, and its old `output=json` parameter no longer returns JSON. This actor uses Craigslist's current listing data and returns the same fields in its dataset.

**Can I paste an old Craigslist post link?**
Current `/view/d/...` links work directly. Older `region/category/post-id.html` links also work. Very old links that contain a `/d/` slug but a broad category are resolved by searching for the post; if Craigslist has removed it, the URL is skipped with a message.

**Does an old search URL's `s=` offset still work?**
No. Craigslist no longer offers an offset cursor for search results, so the actor ignores `s=` and starts from the first result. Use `maxItems`, a narrower price range, or a subarea to control how deep a run goes.

**Why did a run return no listings?**
The query may have no matches, the category may not exist in that region, the post may have been removed, or a filter may be too narrow. A zero-result run completes with a status message and no placeholder record.

**Is this affiliated with Craigslist?**
No. This is an independent actor that reads publicly available Craigslist pages and is not operated or endorsed by Craigslist.

# Actor input Schema

## `mode` (type: `string`):

What to collect: keyword search, a category browse, specific Craigslist URLs, or the region/subarea reference list.

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

Craigslist city/region to search (mode=search/category). Pick a common region, or use Custom region for any of the 707 Craigslist sites.

## `customRegion` (type: `string`):

Any Craigslist hostname or abbreviation (e.g. humboldt, tokyo, sfbay). Overrides Region. (mode=search/category)

## `subarea` (type: `string`):

Optional Craigslist subarea abbreviation inside the region (e.g. sfc, eby, brk). Leave blank for the whole region. (mode=search/category)

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

Craigslist category to search or browse. The default is all for-sale listings.

## `searchQueries` (type: `array`):

One or more keywords. Each query is searched separately; results are de-duplicated. Leave empty for a category browse. (mode=search)

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

Craigslist search pages, new-style /view/d/... post URLs, or old /region/category/post-id.html URLs. (mode=byUrl)

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

Only listings at or above this price. Posts without a price are excluded when a price filter is set.

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

Only listings at or below this price. Posts without a price are excluded when a price filter is set.

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

Only listings posted in the last 24 hours (Craigslist's posted-today filter).

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

Only listings with at least one photo.

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

Match the keywords against titles only instead of titles and descriptions.

## `sellerType` (type: `string`):

Filter by owner, dealer, or either.

## `sortBy` (type: `string`):

Order of results within each query.

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

For for-sale and auto categories: only items in this condition.

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

Housing only.

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

Housing only.

## `minBathrooms` (type: `integer`):

Housing only.

## `maxBathrooms` (type: `integer`):

Housing only.

## `minSqft` (type: `integer`):

Housing only.

## `maxSqft` (type: `integer`):

Housing only.

## `autoMakeModel` (type: `string`):

Auto categories only, e.g. honda civic.

## `minAutoYear` (type: `integer`):

Auto categories only.

## `maxAutoYear` (type: `integer`):

Auto categories only.

## `maxAutoMiles` (type: `integer`):

Auto categories only.

## `postalCode` (type: `string`):

Optional ZIP/postal code to anchor the search geographically. Use with Search radius.

## `searchRadiusMiles` (type: `integer`):

Distance around the postal code. Requires Postal code.

## `hideDuplicates` (type: `boolean`):

Ask Craigslist to group duplicate/reposted listings together.

## `deliveryAvailable` (type: `boolean`):

For-sale and auto categories: only listings offering delivery.

## `cryptoOk` (type: `boolean`):

For-sale and auto categories: only listings that accept crypto.

## `countryCode` (type: `string`):

Two-letter country code to filter the areas list (mode=areas), e.g. US, CA, GB. Leave blank for all 707 sites.

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

Hard cap across all queries and URLs. Craigslist returns at most 10,000 results per search.

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

Fetch each listing's full description, attributes, images, coordinates, and repost status. Turn off for faster search-card-only results.

## Actor input object example

```json
{
  "mode": "search",
  "region": "sfbay",
  "category": "sss",
  "searchQueries": [
    "bike"
  ],
  "startUrls": [],
  "postedToday": false,
  "hasImage": false,
  "titlesOnly": false,
  "sellerType": "all",
  "sortBy": "newest",
  "condition": "any",
  "hideDuplicates": false,
  "deliveryAvailable": false,
  "cryptoOk": false,
  "maxItems": 3,
  "includeDetails": true
}
```

# Actor output Schema

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

Dataset containing scraped Craigslist listings, plus region records in areas mode.

# 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 = {
    "mode": "search",
    "region": "sfbay",
    "category": "sss",
    "searchQueries": [
        "bike"
    ],
    "postedToday": false,
    "hasImage": false,
    "titlesOnly": false,
    "sellerType": "all",
    "sortBy": "newest",
    "condition": "any",
    "hideDuplicates": false,
    "deliveryAvailable": false,
    "cryptoOk": false,
    "maxItems": 3,
    "includeDetails": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/craigslist-classifieds-scraper-with-category").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 = {
    "mode": "search",
    "region": "sfbay",
    "category": "sss",
    "searchQueries": ["bike"],
    "postedToday": False,
    "hasImage": False,
    "titlesOnly": False,
    "sellerType": "all",
    "sortBy": "newest",
    "condition": "any",
    "hideDuplicates": False,
    "deliveryAvailable": False,
    "cryptoOk": False,
    "maxItems": 3,
    "includeDetails": True,
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/craigslist-classifieds-scraper-with-category").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 '{
  "mode": "search",
  "region": "sfbay",
  "category": "sss",
  "searchQueries": [
    "bike"
  ],
  "postedToday": false,
  "hasImage": false,
  "titlesOnly": false,
  "sellerType": "all",
  "sortBy": "newest",
  "condition": "any",
  "hideDuplicates": false,
  "deliveryAvailable": false,
  "cryptoOk": false,
  "maxItems": 3,
  "includeDetails": true
}' |
apify call vexaloom-labs/craigslist-classifieds-scraper-with-category --silent --output-dataset

```

## MCP server setup

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

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/PfjY6S7qeKQpmGEqc/builds/HWKb9T9uefJQgHpvH/openapi.json
