# Craigslist Search Scraper (`cirkit/craigslist-search-scraper`) Actor

Fast craigslist search scraper. Search any of 666 craigslist cities by category, keyword, price range, or map radius. Extracts title, price, posting timestamp, latitude and longitude, location, neighborhood, image urls, and post url. Reads craigslist's own JSON search API, no headless browser.

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

## Pricing

from $1.00 / 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.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

Craigslist Search Scraper extracts classified listings from any craigslist city in structured JSON. Search by city, category, keyword, price range, or map radius, and get back the title, price, posting timestamp, latitude and longitude, location, neighborhood, image urls, and a working link to every post.

This craigslist scraper reads craigslist's own JSON search API directly. There is no headless browser, so runs are fast and cheap, and the data arrives already structured rather than parsed out of HTML.

### What Craigslist Search Scraper extracts

Every record includes:

- `postingId` - craigslist's canonical posting identifier
- `url` - direct link to the post
- `title` - the seller's post title
- `price` and `priceLabel` - numeric price plus the formatted display price
- `postedAt` - UTC timestamp when the post went live, ISO 8601
- `latitude` and `longitude` - real coordinates for mapping
- `locationName` and `neighborhood` - the place craigslist assigns to the post
- `citySubdomain` and `subareaAbbr` - craigslist city and subarea
- `categoryId` and `searchCategory` - the post's category
- `images` and `imageCount` - direct image urls
- `odometer` - vehicle mileage on car and truck categories
- `bedrooms` and `areaSqft` - on housing categories such as `apa` and `hhh`
- `currency` - the currency the price is quoted in, so international cities are not misread as USD

### Why this craigslist scraper

Coordinates and posting timestamps are the two fields most craigslist scraping tools drop. This actor returns both on every record, because it reads them from the same API response that supplies the title and price. If you are plotting listings on a map, deduplicating a feed over time, or tracking how long inventory sits, those fields are the ones you need.

### Input

Set `cities` to one or more craigslist city subdomains. The subdomain is the first part of the site url, so newyork.craigslist.org is `newyork`. All 666 craigslist cities are supported, including international ones such as london, toronto, berlin, and sydney.

Set `category` to a craigslist category abbreviation. The top level categories are `sss` for sale, `jjj` jobs, `hhh` housing, `bbb` services, `ggg` gigs, and `ccc` community. Subcategories work too, such as `cta` for cars and trucks, `apa` for apartments, or `ele` for electronics.

Optional filters include a search keyword, minimum and maximum price, posted today, has image, and a latitude, longitude, and radius for searching around a point.

```json
{
  "cities": ["newyork", "phoenix"],
  "category": "sss",
  "query": "mountain bike",
  "maxPrice": 500,
  "maxItems": 1000
}
```

### Output

One row per craigslist post. Results are written to the default dataset and can be exported as JSON, CSV, or Excel, or pulled through the Apify API from Python, JavaScript, or any HTTP client.

```json
{
  "postingId": "dddMNaNcqeTRK4g1CBCwPd",
  "url": "https://www.craigslist.org/view/d/wilton-recycle-52-cm-derosa-super/dddMNaNcqeTRK4g1CBCwPd",
  "title": "ReCyCle 52 cm, DeRosa Super Prestige",
  "price": 1000,
  "priceLabel": "$1,000",
  "postedAt": "2026-08-08T19:26:23Z",
  "latitude": 41.1958,
  "longitude": -73.4304,
  "locationName": "Wilton",
  "citySubdomain": "newyork",
  "categoryId": 68,
  "images": ["https://images.craigslist.org/00Y0Y_4bBm2CcrZZj_0t20CI_600x450.jpg"],
  "imageCount": 1
}
```

### How many results you can get

Craigslist exposes roughly 2000 results per city and category through search, even when the category reports far more posts in total. To collect more, add more cities, split the search by subcategory, or split it by price band. Records are deduplicated across the whole run, so overlapping searches will not produce duplicate rows.

### Pricing

Pay per result. You are charged per post written to the dataset.

If a search matches nothing at all, the actor writes a single row explaining that instead of finishing with an empty dataset, so a search that finds no posts costs one result.

### Notes on data quality

Price is absent on genuinely free posts and on most job and community posts, so it comes back null there rather than as a zero. Neighborhood is only present when craigslist has assigned one, which is common in dense cities and rare elsewhere. Odometer appears only on vehicle categories, and bedrooms and area only on housing categories.

Coordinates come from the poster, and on cross posted listings they can disagree with the craigslist location label, so both fields are reported exactly as craigslist supplies them and are not reconciled.

Some international cities, including berlin and sydney, do not include coordinates in craigslist's search response at all. For those cities `latitude` and `longitude` come back null while the location name and city are still populated. London does return coordinates.

Prices are passed through exactly as craigslist reports them. A small number of joke listings carry absurd values, up to the 64 bit integer maximum, so filter on a sane upper bound before averaging.

# Actor input Schema

## `cities` (type: `array`):

Craigslist city subdomains to search, one per line. Use the subdomain from the site url: newyork.craigslist.org is 'newyork'. 666 cities worldwide are supported, including london, toronto, berlin and sydney.

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

Craigslist category abbreviation. Top-level: sss (for sale), jjj (jobs), hhh (housing), bbb (services), ggg (gigs), ccc (community). Subcategories also work, for example cta (cars and trucks), apa (apartments for rent), ele (electronics), sof (software jobs).

## `query` (type: `string`):

Optional free-text keyword, for example 'mountain bike'. Leave empty to return everything in the category.

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

Hard cap on records written to the dataset across all cities. Craigslist exposes roughly 2000 results per city and category, so raise this by adding more cities rather than by expecting deeper paging.

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

Only return posts at or above this price.

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

Only return posts at or below this price.

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

Restrict to posts made today.

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

Restrict to posts that include at least one photo.

## `latitude` (type: `string`):

Optional centre point latitude. Set together with longitude and search radius to search around a specific location instead of the whole city.

## `longitude` (type: `string`):

Optional centre point longitude.

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

Radius around the latitude and longitude, in miles for US cities.

## `imageSize` (type: `string`):

Resolution of the returned image urls.

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

Proxy settings. Craigslist's search API does not block datacenter traffic, so the default Apify proxy is sufficient and residential proxies are not needed.

## Actor input object example

```json
{
  "cities": [
    "newyork"
  ],
  "category": "sss",
  "maxItems": 100,
  "postedToday": false,
  "hasImage": false,
  "imageSize": "medium",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset of craigslist post records.

## `datasetCsv` (type: `string`):

Same dataset rendered as CSV.

# 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 = {
    "cities": [
        "newyork"
    ],
    "category": "sss",
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cirkit/craigslist-search-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 = {
    "cities": ["newyork"],
    "category": "sss",
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("cirkit/craigslist-search-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 '{
  "cities": [
    "newyork"
  ],
  "category": "sss",
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call cirkit/craigslist-search-scraper --silent --output-dataset

```

## MCP server setup

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