# Craigslist Rentals Scraper: Apartments & Rooms (`arjun_code/craigslist-rentals-scraper`) Actor

🏠 Scrape US Craigslist apartments, rooms and sublets for rental research and listing feeds. Filter by city, subarea, rent and amenities. Export rents, bedrooms, bathrooms, descriptions, photo URLs and public contacts to JSON or CSV. Schedule runs and skip previously collected ads.

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

## Pricing

from $1.49 / 1,000 rental listings

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 Rentals Scraper** collects US apartments, rooms and sublets for rent comparisons, listing feeds and housing research. Search across cities, subareas or Craigslist URLs, then export structured data to JSON or CSV.

- **Rental filters:** rent, bedrooms, bathrooms, floor area, pets, amenities and advertised availability.
- **Details included:** descriptions, photo URLs, source attributes and publicly displayed contacts.
- **Recurring collection:** schedule searches and skip previously delivered posting IDs.
- **Automatic connections:** no proxy setup required.

Built for rental data products, housing researchers, property managers and relocation services.

### 🚀 Quick start

Start with a ready-made search:

| Public example | What it collects |
| --- | --- |
| [Compare apartment rents across three US markets](https://apify.com/arjun_code/craigslist-rentals-scraper/examples/compare-craigslist-apartment-rents-across-cities) | Up to 10 monthly ads each from New York, Los Angeles and the SF Bay Area, with details. |
| [Find Los Angeles rooms with private bathrooms](https://apify.com/arjun_code/craigslist-rentals-scraper/examples/find-private-rooms-with-bathrooms-los-angeles) | Up to 20 monthly private-room ads with private bathrooms and details. |

Copy an example to your account, or configure your own search:

1. Select a **Rental category** and one or more **US cities / regions**.
2. Choose the rental period and any filters, then set **Maximum rental ads — total**.
3. Keep **Include rental details and public contacts** enabled for descriptions and amenities.
4. Run the Actor and open **Output**. Download **Full rental records (JSON)** or **Rental records (CSV)**.

💡 Default: up to **50 New York apartment ads, monthly rent, newest first, with details**. No keyword, price or amenity restrictions.

```json
{
  "rentalCategory": "apa",
  "cities": ["newyork"],
  "rentPeriods": ["monthly"],
  "sort": "date",
  "maxItems": 50,
  "includeDetails": true
}
```

Limits cap delivered ads; fewer may be available.

### 🔎 Rental search examples

#### Compare apartments across three cities

Collect up to five one- or two-bedroom ads per city, 15 total. Each search is newest first; combined results are interleaved.

```json
{
  "rentalCategory": "apa",
  "cities": ["newyork", "sfbay", "dallas"],
  "rentPeriods": ["monthly"],
  "minBedrooms": 1,
  "maxBedrooms": 2,
  "sort": "date",
  "maxItems": 15,
  "maxItemsPerSearch": 5,
  "includeDetails": true
}
```

#### Find private rooms with private bathrooms

Search selected subareas for private rooms and bathrooms. Privacy filters describe private/shared use, not room counts. Subareas replace Cities.

```json
{
  "rentalCategory": "roo",
  "subareas": ["newyork/brk", "losangeles/wst"],
  "rentPeriods": ["monthly"],
  "privateRoom": true,
  "privateBath": true,
  "maxItems": 10,
  "maxItemsPerSearch": 5,
  "includeDetails": true
}
```

#### Collect furnished sublets

Collect furnished weekly or monthly sublets. Compare `rent` with `rentPeriod`; amounts are not converted.

```json
{
  "rentalCategory": "sub",
  "subareas": ["newyork/brk", "sfbay/sfc"],
  "rentPeriods": ["weekly", "monthly"],
  "furnished": true,
  "sort": "date",
  "maxItems": 10,
  "maxItemsPerSearch": 5,
  "includeDetails": true
}
```

#### Reuse exact searches and ZIP locations

Reuse Craigslist searches: this example combines Brooklyn with a three-mile radius around ZIP 94103. Optional `userData.label` names each input in `matchedSearches`.

```json
{
  "startUrls": [
    {
      "url": "https://newyork.craigslist.org/search/brk/apa?rent_period=3&sort=date",
      "userData": {
        "label": "Brooklyn monthly rentals"
      }
    },
    {
      "url": "https://sfbay.craigslist.org/search/apa?postal=94103&search_distance=3&sort=dist&rent_period=3",
      "userData": {
        "label": "Within 3 miles of 94103"
      }
    }
  ],
  "maxItems": 10,
  "maxItemsPerSearch": 5,
  "includeDetails": true
}
```

**Priority: Rental URLs → Subareas → Cities.** URLs replace guided categories, locations, filters and sorting, including the monthly default. Without `rent_period`, a URL can return any rental period. Limits, details, nearby suggestions and monitoring still apply.

Supported paths: `/search/apa`, `/search/roo`, `/search/sub`, subareas such as `/search/brk/roo`, `/search/area/`, and individual US ads in these categories. Individual ads always collect details.

#### Collect posting IDs not delivered before

Schedule this input as an Apify Task. Reuse the searches and history name for subsequent runs.

```json
{
  "rentalCategory": "apa",
  "subareas": ["newyork/brk"],
  "rentPeriods": ["monthly"],
  "sort": "date",
  "maxItems": 50,
  "includeDetails": true,
  "newOnly": true,
  "watchName": "brooklyn-monthly-rentals"
}
```

The first run may include older ads. Later runs skip saved IDs, including same-ID price edits; reposts with new IDs count as new. Set `newOnly: false` to collect current versions again. This tracks posting IDs, not unique properties or price changes.

### 📦 Rental output and downloads

| Output | Contents | Best for |
| --- | --- | --- |
| Dataset | Rental records plus readable collection notices | Reviewing ads and explaining empty or partial results |
| RENTALS.json | All 56 rental fields, including nested arrays and original attributes; no notices | APIs, data feeds and full-fidelity records |
| RENTALS.csv | 54 selected rental columns; no notices | Spreadsheets and analysis |
| RUN_SUMMARY | Outcome, counts, exclusions, issues and a summary for each input | Checking coverage and explaining differences in counts |

CSV omits `recordType` and `listingUuid`; `postId` and URL remain. Arrays and objects are JSON strings in CSV cells. JSON preserves all fields and types.

#### Complete rental example

This is an **illustrative record showing all 56 rental fields**, based on the Actor's current output structure. The listing identity, address, contact data, photo URLs and dates are fictional examples, not an available rental or working contact. Real fields may be `null` or empty; the Actor does not invent missing details.

```json
{
  "recordType": "rental",
  "postId": "7990000001",
  "listingUuid": "EXAMPLE_LISTING_UUID",
  "url": "https://newyork.craigslist.org/brk/apa/d/example-brooklyn-rental/7990000001.html",
  "title": "Example: 1-bedroom apartment with laundry",
  "category": "apa",
  "rent": 2900,
  "rentRaw": "$2,900",
  "currency": "USD",
  "rentPeriod": "monthly",
  "bedrooms": 1,
  "bathrooms": 1.5,
  "area": 850,
  "areaUnit": "sqft",
  "areaRaw": "850ft²",
  "propertyType": "apartment",
  "availableFrom": "2026-11-15",
  "laundry": "w/d in unit",
  "parking": "street parking",
  "privateRoom": null,
  "privateBath": null,
  "catsAllowed": true,
  "dogsAllowed": true,
  "furnished": null,
  "noSmoking": true,
  "wheelchairAccessible": null,
  "airConditioning": true,
  "evCharging": null,
  "noApplicationFee": null,
  "noBrokerFee": null,
  "region": "newyork",
  "subarea": "brk",
  "location": "Brooklyn",
  "neighborhood": "Example neighborhood",
  "address": "Example Street near Sample Avenue",
  "latitude": 40.7,
  "longitude": -73.95,
  "description": "Example rental description.\nOne bedroom, 1.5 bathrooms, washer/dryer in unit and street parking.\nAdvertised rent: $2,900 per month. Available November 15, 2026.\nContact: (212) 555-0100 or leasing@example.com.",
  "imageUrls": [
    "https://images.craigslist.org/EXAMPLE_LIVING_ROOM_1200x900.jpg",
    "https://images.craigslist.org/EXAMPLE_BEDROOM_1200x900.jpg"
  ],
  "attributes": {
    "bedrooms": "1",
    "bathrooms": "1.5",
    "area": "850ft²",
    "movein_date": "2026-11-15",
    "rent_period": "monthly",
    "housing_type": "apartment",
    "laundry": "w/d in unit",
    "parking": "street parking",
    "pets_cat": "✓",
    "pets_dog": "✓",
    "no_smoking": "✓",
    "airconditioning": "✓"
  },
  "postedAt": "2026-11-03T08:00:00+00:00",
  "updatedAt": "2026-11-03T09:00:00+00:00",
  "scrapedAt": "2026-11-03T09:05:00+00:00",
  "repostOf": null,
  "upcomingDate": null,
  "openHouseDates": [],
  "advertisedDates": [],
  "dateRange": [],
  "detailStatus": "collected",
  "firstSeenAt": null,
  "isNew": null,
  "matchedSearches": [
    {
      "inputPosition": 1,
      "inputLabel": "newyork",
      "inputUrl": "https://www.craigslist.org/search/area/newyork?cat=apa&rent_period=3&sort=date",
      "searchRegion": "newyork"
    }
  ],
  "phoneNumbers": [
    "+12125550100"
  ],
  "emails": [
    "leasing@example.com"
  ],
  "contactSources": [
    {
      "type": "phone",
      "value": "+12125550100",
      "raw": "(212) 555-0100"
    },
    {
      "type": "email",
      "value": "leasing@example.com",
      "raw": "leasing@example.com",
      "isRelay": false
    }
  ],
  "contactStatus": "found"
}
```

With `newOnly` off, `firstSeenAt` and `isNew` are `null`. With monitoring on, newly delivered IDs receive a timestamp and `isNew: true`.

#### Missing values and contact status

- `null` means unknown or uncollected, not zero or false. Empty arrays mean no values collected.
- `contactStatus: "found"`: at least one public phone/email extracted; ownership and reachability unverified.
- `contactStatus: "not_found"`: no phone/email found in the collected public description or contact links.
- `contactStatus: "not_requested"`: details were not collected; contacts may still exist.

Descriptions are plain text; photos are source URLs, not downloaded files. Contacts may belong to owners, agents or businesses; roles are unverified. Hidden **Reply** contacts are not collected.

#### Full field reference

All 56 rental fields are listed below. Advertised calendar dates remain dates; timestamps use UTC.

#### Identity, rent and property

| Field | Type | Meaning |
| --- | --- | --- |
| `recordType` | string | rental for an ad; notice for an explanation. Notices do not count toward maxItems. |
| `postId` | string / null | Craigslist posting ID, as text. Identifies an ad, not a unique property; use it to join records across runs. |
| `listingUuid` | string / null | Additional Craigslist identifier when available. |
| `url` | string / null | Source ad link; may expire or redirect. |
| `title` | string / null | Title as advertised by the poster. |
| `category` | string / null | apa: apartments; roo: rooms/shares; sub: sublets. Separate from propertyType. |
| `rent` | number / null | Advertised USD amount for rentPeriod, without conversion. Null does not mean free. |
| `rentRaw` | string / null | Original price text, including source currency formatting. |
| `currency` | string / null | USD for supported US markets. |
| `rentPeriod` | string / null | Source period, usually monthly, weekly or daily. Requires details; never inferred from filters. |
| `bedrooms` | number / null | Advertised bedrooms; 0 means studio. |
| `bathrooms` | number / null | Advertised bathrooms, including halves such as 1.5. Requires details. |
| `area` | number / null | Advertised floor area. Read with areaUnit; no conversion. |
| `areaUnit` | string / null | Source unit: sqft or sqm; null when unavailable. |
| `areaRaw` | string / null | Original floor-area text, such as 850ft². Requires details. |
| `propertyType` | string / null | Source housing label, such as apartment or house. Does not establish whether the whole property is offered. Requires details. |
| `availableFrom` | string / null | Advertised move-in date, usually YYYY-MM-DD. May be outdated; requires details. |
| `laundry` | string / null | Source laundry label, such as w/d in unit. May differ from input option names; requires details. |
| `parking` | string / null | Source parking label, such as street parking. May differ from input option names; requires details. |

#### Privacy and amenities

Requires details. Explicitly marked amenities are `true`; otherwise `null`. Privacy may also be explicitly `false`. Search filters never fill missing attributes.

| Field | Type | Meaning |
| --- | --- | --- |
| `privateRoom` | boolean / null | Private: true; explicitly shared: false; unknown: null. |
| `privateBath` | boolean / null | Private: true; explicitly shared: false; unknown: null. |
| `catsAllowed` | boolean / null | Cats allowed. |
| `dogsAllowed` | boolean / null | Dogs allowed. |
| `furnished` | boolean / null | Furnished. |
| `noSmoking` | boolean / null | No smoking. |
| `wheelchairAccessible` | boolean / null | Marked wheelchair accessible. |
| `airConditioning` | boolean / null | Air conditioning. |
| `evCharging` | boolean / null | EV charging. |
| `noApplicationFee` | boolean / null | Marked no application fee. |
| `noBrokerFee` | boolean / null | Marked no broker fee. |

#### Location, description and photos

| Field | Type | Meaning |
| --- | --- | --- |
| `region` | string / null | Ad’s Craigslist market slug, such as newyork; may differ from the input in radius/nearby searches. |
| `subarea` | string / null | Subarea code, such as brk for Brooklyn. |
| `location` | string / null | Source location description or poster-entered label. |
| `neighborhood` | string / null | Source neighborhood label; not inferred from coordinates. |
| `address` | string / null | Advertised address or intersection. Requires details. |
| `latitude` | number / null | Advertised map latitude; may be approximate. |
| `longitude` | number / null | Advertised map longitude; may be approximate. |
| `description` | string / null | Public description as plain text with line breaks. Requires details. |
| `imageUrls` | array | Unique source photo URLs. Search-only records may include photos; files are not downloaded and links may expire. |

#### Source attributes, dates and history

| Field | Type | Meaning |
| --- | --- | --- |
| `attributes` | object | Original Craigslist keys and values. Varies by ad; requires details. |
| `postedAt` | string / null | Source posting timestamp, ISO 8601 UTC. |
| `updatedAt` | string / null | Source update timestamp, ISO 8601 UTC. Requires details; not a change history. |
| `scrapedAt` | string / null | Collection timestamp, ISO 8601 UTC. |
| `repostOf` | string / null | Earlier posting ID if Craigslist identifies a repost. Requires details. |
| `upcomingDate` | string / null | Next advertised search date for upcoming sorting; not necessarily the move-in date. |
| `openHouseDates` | array | Advertised open-house dates (YYYY-MM-DD) exposed by search; direct listing inputs may not populate them. |
| `advertisedDates` | array | Other advertised search dates (YYYY-MM-DD); not verified availability. |
| `dateRange` | array | Source search date-range endpoints; does not establish a lease term. |
| `detailStatus` | string / null | collected or not_requested. Failed ads become notices, not successful rental rows. |
| `firstSeenAt` | string / null | Delivery time of an unseen ad with newOnly enabled; otherwise null. |
| `isNew` | boolean / null | True for an unseen ad delivered with newOnly enabled; otherwise null. Does not mean posted today. |

#### Input matches and public contacts

| Field | Type | Meaning |
| --- | --- | --- |
| `matchedSearches` | array | Contributing inputs for this posting ID; nested fields are described below. |
| `phoneNumbers` | array | Unique public phone numbers in international format; US numbers generally start +1. |
| `emails` | array | Unique public email addresses. Hidden Reply dialogs are not queried. |
| `contactSources` | array | Contact type, normalized value and raw visible text; email entries also include isRelay. |
| `contactStatus` | string / null | found, not_found or not_requested; see the definitions above. |

#### Nested objects and notice fields

- `matchedSearches[]`: `inputPosition` (one-based integer), `inputLabel` (text, possibly empty), `inputUrl` (requested URL), and `searchRegion` (market slug or null).
- `contactSources[]`: `type` (phone/email), `value` (normalized contact), and `raw` (visible text). Emails add `isRelay`, true for `.craigslist.org` domains. A contact may have multiple entries.
- `attributes`: original keys and values, such as `rent_period`, `housing_type` and `movein_date`. Top-level fields provide normalized values.

Notices use `recordType: "notice"`, a machine-readable `code`, and a readable `message`. Source-specific notices add the input fields listed above; listing failures may add `postId`, and batch failures add an integer `batchOffset`.

#### Empty results and collection notices

Notices explain affected inputs, do not count toward `maxItems`, and are excluded from RENTALS.json and RENTALS.csv.

```json
{
  "recordType": "notice",
  "code": "no_matches",
  "message": "No matching rental ads were found. Try a wider area or fewer filters.",
  "inputPosition": 1,
  "inputLabel": "Brooklyn monthly rentals",
  "inputUrl": "https://newyork.craigslist.org/search/brk/apa?rent_period=3&sort=date",
  "searchRegion": "newyork"
}
```

| Notice | Meaning / next step |
| --- | --- |
| `no_matches` | No eligible ads remain in the accessible search results; widen the location or reduce filters. |
| `no_new_listings` | No previously undelivered ads remain for the saved monitoring history. |
| `spending_limit` | The run budget limits how many ads can be delivered. Increase the maximum run charge to collect more. |
| `no_exact_matches` | No examined ads passed the exact decimal bathroom bounds. |
| `invalid_input` | Correct the named input field, spelling or value before rerunning. |
| `invalid_source` | Correct the affected city, subarea, category or URL. Other valid inputs can still run. |
| `source_failed` / `source_unavailable` | A search or source could not be collected. Read the message and try again later. |
| `listing_failed` | An individual ad could not be collected. It is not delivered as a successful rental or marked as seen. |
| `batch_failed` | Part of a search could not be collected; the notice identifies the affected input and batch. |
| `search_window_limit` | Craigslist reports more ads than the accessible search window; narrow the search for wider coverage. |
| `details_required_for_filter` | Decimal bathroom bounds require details even when the detail option is off. |
| `city_directory_fallback` | Collection used the available city directory after the live directory could not be loaded. |

Even a successful Apify run may return no ads or report invalid inputs. Check `RUN_SUMMARY.status` and `rentalsSaved` for collection results.

| Summary field | Meaning |
| --- | --- |
| `status` / `message` | Outcome: succeeded, partial, no_data, no_data_with_issues or invalid_input, with an explanation |
| `rentalsSaved` / `noticesSaved` | Delivered ad and notice counts |
| `sources` | Per-input matches, accessible search window, saved ads, exclusions and detail failures; overlapping inputs can refer to the same delivered ad |
| `issues` | Collection problems |
| `network` | Connection route and automatic changes |
| `billing` | Pricing model and the number of listing and start events charged |
| `monitor` | History usage, new IDs saved and total known IDs |
| `limits` | Requested and budget-adjusted total limits, plus per-input caps |

### ⚙️ Input parameters

All 43 inputs are listed below. Names are case-sensitive; optional bounds can be omitted or blank.

Multi-select choices use **OR** within a field and **AND** between fields. Unchecked boxes add no requirement. Filters follow the poster’s markings.

| Parameter | Type | Default / choices | Meaning |
| --- | --- | --- | --- |
| `rentalCategory` | string | "apa"; apa, roo, sub | Guided search category: apartments / housing for rent (apa), rooms & shares (roo), or sublets & temporary (sub). URLs keep their own category. |
| `cities` | array | \["newyork"] | US Craigslist markets. Used when both Rental URLs and Subareas are empty. |
| `subareas` | array | Not set; select in Input | Specific areas such as newyork/brk or losangeles/wst. Replaces Cities; Rental URLs take priority. The Input dropdown lists all supported choices. |
| `searchTerm` | string | Not set | Keywords in titles and descriptions, matching the main Craigslist search box. Blank means no keyword restriction. |
| `searchTitlesOnly` | boolean | false | Apply searchTerm to titles only. |
| `sort` | string | "date"; date, dateoldest, priceasc, pricedsc, dist, rel, upcoming | Order within each search; combined searches are interleaved, not globally sorted. See sorting options below. |
| `rentPeriods` | array | \["monthly"]; monthly, weekly, daily | Monthly by default. Select daily/weekly for short stays, or \[] for any period. Amounts retain their advertised period; no conversion. |
| `maxItems` | integer | 50 | Total unique posting IDs to deliver across all inputs. Notices are excluded. Actual results may be fewer. |
| `includeDetails` | boolean | true | Collect descriptions, amenities and public contacts. Off returns search data; individual listing URLs and decimal bathroom filters still collect details. |
| `startUrls` | array | Not set | US rental search or listing URLs. Replaces guided location, category, filters and sort, including default monthly rent. Limits, details, nearby settings and monitoring still apply. Optional userData.label names each input. |
| `minRent` | integer | Not set | Minimum advertised USD amount for the selected rental periods. |
| `maxRent` | integer | Not set | Maximum advertised USD amount. Weekly/daily amounts are not monthly equivalents. |
| `minBedrooms` | integer | Not set | Minimum whole bedrooms; 0 includes studios. |
| `maxBedrooms` | integer | Not set | Maximum whole bedrooms; set to 0 for studios only. |
| `minBathrooms` | number | Not set | Minimum bathrooms, including half baths such as 1.5. Decimal bounds require details. |
| `maxBathrooms` | number | Not set | Maximum bathrooms. Set both bounds to 1.5 for exactly 1.5 baths. |
| `minArea` | integer | Not set | Minimum floor area in square feet. |
| `maxArea` | integer | Not set | Maximum floor area in square feet. |
| `propertyTypes` | array | Not set; apartment, condo, cottage_cabin, duplex, flat, house, in_law, loft, townhouse, manufactured, assisted_living, land | One or more property types; empty means any. |
| `laundryTypes` | array | Not set; in_unit, in_building, on_site, hookups, none | One or more laundry options; empty means any. |
| `parkingTypes` | array | Not set; carport, attached_garage, detached_garage, off_street, street, valet, none | One or more parking options; empty means any. |
| `privateRoom` | boolean | false | Require private rather than shared room use. Rooms and sublets only; not a bedroom count. |
| `privateBath` | boolean | false | Require private rather than shared bathroom use. Rooms and sublets only; not a bathroom count. |
| `catsAllowed` | boolean | false | Require ads marked cats allowed. |
| `dogsAllowed` | boolean | false | Require ads marked dogs allowed. |
| `furnished` | boolean | false | Require ads marked furnished. |
| `noSmoking` | boolean | false | Require ads marked no smoking. |
| `wheelchairAccessible` | boolean | false | Require ads marked wheelchair accessible. |
| `airConditioning` | boolean | false | Require ads marked air conditioning. |
| `evCharging` | boolean | false | Require ads marked EV charging. |
| `noApplicationFee` | boolean | false | Require ads marked no application fee. Apartments only. |
| `noBrokerFee` | boolean | false | Require ads marked no broker fee. Apartments only. |
| `availability` | string | "any"; any, within_30_days, beyond_30_days | Craigslist’s within/beyond-30-day move-in filter. Advertised dates may be absent or outdated. |
| `postalCode` | string | Not set | Center guided searches on one US ZIP. Use separate URLs for independent ZIP centers. Default radius: 60 miles. |
| `radiusMiles` | number | Not set | Radius around the ZIP or city center, with any sort. Blank adds no radius except ZIP/nearest searches, which use 60 miles. |
| `openHouseDate` | string | Not set | Advertised viewing date (YYYY-MM-DD), separate from move-in availability. Apartments and sublets only. |
| `hasImage` | boolean | false | Require at least one photo. |
| `postedToday` | boolean | false | Apply Craigslist’s posted-today filter. |
| `showDuplicates` | boolean | false | Off keeps the newest ad in each Craigslist duplicate group. On includes distinct posting IDs; neither mode identifies unique physical properties. |
| `includeNearby` | boolean | false | Include Craigslist’s nearby-area suggestions. ZIP/radius searches already cover their requested circle and may cross regions. |
| `maxItemsPerSearch` | integer | Not set | Optional cap for each city, subarea or URL. Blank adds no per-search cap; maxItems still applies. |
| `newOnly` | boolean | false | Skip successfully delivered posting IDs from the same search history. Same-ID edits are skipped; a new repost ID is new. |
| `watchName` | string | Not set | Optional separate history name. Reuse with the same searches. Without a name, each saved Task has its own history. Run only one collection at a time per history. |

#### Category-specific filters

| Filter | Apartments (`apa`) | Rooms (`roo`) | Sublets (`sub`) |
| --- | --- | --- | --- |
| Private room / private bathroom | — | Supported | Supported |
| No application fee / no broker fee | Supported | — | — |
| Open-house date | Supported | — | Supported |

Unsupported combinations return an explanation identifying the setting to change, including for URL inputs.

Decimal bathroom bounds may require extra detail requests. Area filters use square feet; output preserves source units in `areaUnit`.

#### Sorting and radius

| Sort value | Order |
| --- | --- |
| `date` | Newest first |
| `dateoldest` | Oldest first |
| `priceasc` | Advertised rent, low to high |
| `pricedsc` | Advertised rent, high to low |
| `dist` | Nearest first |
| `rel` | Relevance to search keywords |
| `upcoming` | Upcoming advertised dates, including open houses; not necessarily move-in-date order |

Use Relevance with keywords. ZIP/radius works with every guided sort. ZIP or nearest-first searches default to 60 miles; without a ZIP, they use the city center. Use separate URLs for different ZIP centers.

### 🔄 Schedules and API

Save an Apify Task and add a Schedule. Reuse searches and `watchName` to continue history; changing limits or details does not reset it. Unnamed Tasks have separate histories. Avoid overlapping runs per history.

Applications can use these Apify API endpoints:

| Step | API request | What to use |
| --- | --- | --- |
| Start | `POST https://api.apify.com/v2/acts/arjun_code~craigslist-rentals-scraper/runs` | JSON request body from any input example above |
| Check progress | `GET https://api.apify.com/v2/actor-runs/{runId}` | Run ID returned by the start request |
| Get dataset | `GET https://api.apify.com/v2/datasets/{defaultDatasetId}/items` | Includes rentals and notices |
| Get rentals only | `GET https://api.apify.com/v2/key-value-stores/{defaultKeyValueStoreId}/records/RENTALS.json` | Full rental records without notices |
| Get summary | `GET https://api.apify.com/v2/key-value-stores/{defaultKeyValueStoreId}/records/RUN_SUMMARY` | Check outcome and per-input counts |

Send `Authorization: Bearer YOUR_APIFY_TOKEN`; starting a run also requires `Content-Type: application/json`. Use returned IDs and wait for completion before downloading files. [API guide](https://docs.apify.com/api/v2)

### 🤖 AI Agents & LLM Apps

Give housing assistants and research agents structured rental ads to compare and summarize with source links.

#### Connect an AI agent through MCP

Add this remote MCP server to your client and authorize it with your Apify account:

```json
{
  "mcpServers": {
    "craigslist-rentals": {
      "url": "https://mcp.apify.com/?tools=actors,arjun_code/craigslist-rentals-scraper"
    }
  }
}
```

Connector forms can use the URL directly. Authorize with OAuth or `Authorization: Bearer <APIFY_TOKEN>` in client credentials. See the [MCP configurator](https://mcp.apify.com/) for client-specific setup.

Try this prompt:

> Use arjun_code/craigslist-rentals-scraper to find 10 monthly Los Angeles rooms with private bathrooms. Include details, cap spending at $0.05, and summarize rent, rental period, source links and collection notices.

For an explicit spending cap, call the MCP tool `call-actor` with these arguments:

```json
{
  "actor": "arjun_code/craigslist-rentals-scraper",
  "input": {
    "rentalCategory": "roo",
    "cities": ["losangeles"],
    "rentPeriods": ["monthly"],
    "privateRoom": true,
    "privateBath": true,
    "sort": "date",
    "maxItems": 10,
    "includeDetails": true
  },
  "callOptions": {
    "maxTotalChargeUsd": 0.05,
    "memory": 512,
    "timeout": 180
  },
  "waitSecs": 30
}
```

`input.maxItems` caps ads; `callOptions.maxTotalChargeUsd` caps charges. Use `call-actor` for spending caps; the direct tool `arjun_code--craigslist-rentals-scraper` has no budget input.

Poll unfinished runs with `get-actor-run` using the returned run ID. Once complete, read `RENTALS.json` and `RUN_SUMMARY` with `get-key-value-store-record` and the returned store ID. For paginated datasets, use `get-dataset-items` with `limit`, `offset` and `fields`; rows include notices. [MCP guide](https://docs.apify.com/mcp)

#### Call from your LLM application

Expose Actor inputs as tool arguments; execute calls in your backend and return records to the model. For OpenAPI tool imports, use the [Actor definition](https://api.apify.com/v2/acts/arjun_code~craigslist-rentals-scraper/builds/default/openapi.json).

Python example using `apify-client` 3.4 (`pip install "apify-client>=3.4,<4"`). Set `APIFY_TOKEN` in your backend environment and pass the `input` object above as `search`:

```python
import os
from decimal import Decimal
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

def get_rental_ads(search: dict) -> dict:
    run = client.actor("arjun_code/craigslist-rentals-scraper").call(
        run_input=search,
        max_total_charge_usd=Decimal("0.05"),
    )
    if run is None or run.status != "SUCCEEDED":
        raise RuntimeError("Rental collection did not complete successfully.")
    store = client.key_value_store(run.default_key_value_store_id)
    return {
        "rentals": store.get_record("RENTALS.json")["value"],
        "summary": store.get_record("RUN_SUMMARY")["value"],
    }
```

This call waits for completion; background jobs can use the API flow above. [Python client reference](https://docs.apify.com/api/client/python/reference/class/ActorClient)

Retain `url` and `scrapedAt`, compare `rent` with `rentPeriod`, and treat missing values as unknown. Explain partial/empty results from `RUN_SUMMARY`; advertised details remain the poster's claims.

### 💰 Pricing

Pay per delivered rental ad, plus an Actor start charge. Prices are in USD; records are billed individually.

| Store discount tier | Per 1,000 rental ads |
| --- | ---: |
| Free | $1.99 |
| Bronze | $1.79 |
| Silver | $1.59 |
| Gold, Platinum and Diamond | $1.49 |

Start charge: **$0.001 at default 512 MB**, even with no ads. Apify charges one start event per allocated GB, minimum one.

Details, photo URLs, public contacts and proxy usage are included; search-only records cost the same. Notices, failed ads and skipped IDs incur no listing charge. With `newOnly` off, repeat deliveries are billed again.

Example: **50 Free-tier ads cost $0.1005**, including start. Set Apify's maximum run charge to cap spending; `maxItems` caps ads only. Run-time usage is included; post-run storage access may incur standard fees. Current Pricing and Console settings apply.

### 🚗 Need Craigslist vehicle data?

Compare vehicle prices and dealer inventory with our [Craigslist Cars & Trucks Scraper](https://apify.com/arjun_code/craigslist-cars-scraper). Filter by make/model, price, year, mileage and seller type; export details and available public contacts.

### ❓ FAQ and support

#### Why are there fewer results than on Craigslist?

Match the exact URL, category, period, filters and sort. Defaults select monthly rent, exclude nearby suggestions and group duplicates. Limits, history, unavailable ads and search-window restrictions can reduce counts; `RUN_SUMMARY` explains each input.

A `search_window_limit` notice means fewer ads are accessible than Craigslist reports. Narrow the area or rent range. Ads and ordering may change during collection.

#### How do I report a problem?

Use the **Issues** tab with the run ID, inputs without credentials, affected URL and expected result. For count differences, include the exact search URL and collection time.

# Actor input Schema

## `rentalCategory` (type: `string`):

Choose one rental category for guided searches. Default: apartments / housing for rent. Rooms and sublets have their own filters. Search and listing URLs keep their own category.

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

Select one or more US Craigslist markets. Default: New York. Used only when both Subareas and Rental URLs are empty.

## `subareas` (type: `array`):

Choose specific areas, such as New York / Brooklyn or Los Angeles / Westside-Southbay. Selected subareas replace the Cities list. Leave empty to search whole cities. 💡 Rental URLs take priority over both.

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

Search titles and descriptions, just like the main Craigslist search box. Try furnished studio or near subway. Leave blank to collect all ads that match your other filters.

## `searchTitlesOnly` (type: `boolean`):

Apply keywords to titles only. Has an effect only when Search keywords is filled.

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

Order results within each city, subarea or URL. Multiple searches are interleaved, not globally sorted. Use Relevance with search keywords. Upcoming follows advertised dates/open houses, not move-in availability. Nearest uses the ZIP or city center and, if omitted, a 60-mile radius.

## `rentPeriods` (type: `array`):

Default: monthly. Add daily or weekly for short-term offers, or clear all selections for any period. 💡 Rent keeps its advertised period; daily and weekly prices are not converted to monthly amounts.

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

Your main quantity setting: the maximum number of unique rental ads to save across all selected cities, subareas or URLs. Fewer ads may match your search. Exact bathroom filtering happens before this limit; notice rows do not count.

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

Default: on. Include descriptions, photo URLs, bathrooms, rental periods, amenities and contacts visible in the public ad. Turn off for search fields only. 💡 Individual listing URLs and decimal bathroom filters always collect details.

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

Paste apa (apartments), roo (rooms) or sub (sublets) search URLs, /search/area/ URLs, or individual rental ads. 💡 URLs replace guided locations, category and filters, including the default monthly rent filter. Quantity limits, detail collection and repeat-run settings still apply. Use userData.label to name an input.

## `minRent` (type: `integer`):

Minimum USD amount for the selected rental periods. Leave blank for no lower bound.

## `maxRent` (type: `integer`):

Maximum USD amount for the selected rental periods. Daily and weekly prices are not monthly equivalents.

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

Whole bedrooms. Use 0 for studios; leave blank for no lower bound.

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

Use 0 to limit results to studios. Leave blank for no upper bound.

## `minBathrooms` (type: `number`):

Supports half baths such as 1.5. Decimal values require details and can increase request count.

## `maxBathrooms` (type: `number`):

Supports half baths. Set both bathroom bounds to 1.5 for exactly 1.5 baths.

## `minArea` (type: `integer`):

Advertised floor area in square feet. Leave blank for no lower bound.

## `maxArea` (type: `integer`):

Advertised floor area in square feet. Leave blank for no upper bound.

## `propertyTypes` (type: `array`):

Choose one or more options. Options within this field are OR; different filter fields are combined with AND. Empty means any.

## `laundryTypes` (type: `array`):

Choose one or more options. Options within this field are OR; different filter fields are combined with AND. Empty means any.

## `parkingTypes` (type: `array`):

Choose one or more options. Options within this field are OR; different filter fields are combined with AND. Empty means any.

## `privateRoom` (type: `boolean`):

Require a private room in Rooms & shares or Sublets & temporary. Off means no restriction, not shared rooms only. This filter is not offered for Apartments / housing for rent.

## `privateBath` (type: `boolean`):

Require a private bathroom in Rooms & shares or Sublets & temporary. Off means no restriction. This describes private versus shared use, not the number of bathrooms.

## `catsAllowed` (type: `boolean`):

Require ads marked “cats allowed” by the poster. Off means no restriction; it does not mean the amenity is absent.

## `dogsAllowed` (type: `boolean`):

Require ads marked “dogs allowed” by the poster. Off means no restriction; it does not mean the amenity is absent.

## `furnished` (type: `boolean`):

Require ads marked “furnished” by the poster. Off means no restriction; it does not mean the amenity is absent.

## `noSmoking` (type: `boolean`):

Require ads marked “no smoking” by the poster. Off means no restriction; it does not mean the amenity is absent.

## `wheelchairAccessible` (type: `boolean`):

Require ads marked “wheelchair accessible” by the poster. Off means no restriction; it does not mean the amenity is absent.

## `airConditioning` (type: `boolean`):

Require ads marked “air conditioning” by the poster. Off means no restriction; it does not mean the amenity is absent.

## `evCharging` (type: `boolean`):

Require ads marked “ev charging” by the poster. Off means no restriction; it does not mean the amenity is absent.

## `noApplicationFee` (type: `boolean`):

Require ads marked “no application fee” by the poster. Off means no restriction; it does not mean the amenity is absent. Available for apartments (apa) only; clear this option when collecting rooms or sublets.

## `noBrokerFee` (type: `boolean`):

Require ads marked “no broker fee” by the poster. Off means no restriction; it does not mean the amenity is absent. Available for apartments (apa) only; clear this option when collecting rooms or sublets.

## `availability` (type: `string`):

Use Craigslist’s within/beyond 30-day availability filter. The posted move-in date may be missing or outdated. This does not verify that a unit is still available.

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

Center all guided searches on this ZIP. For independent locations use separate rental URLs. Without a radius, ZIP searches use 60 miles.

## `radiusMiles` (type: `number`):

Use a radius around the ZIP code or selected city center, with any sort order. Empty means no explicit radius except ZIP/nearest-first searches, which use 60 miles.

## `openHouseDate` (type: `string`):

Select one advertised open-house date (YYYY-MM-DD). Available for apartments and sublets; not rooms. This is different from the move-in availability filter. Leave blank for any open-house date.

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

Require at least one source photo.

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

Use Craigslist’s posted-today filter for each search.

## `showDuplicates` (type: `boolean`):

Default: off, keep the newest ad in each duplicate group identified by Craigslist. On includes each distinct posting ID. Reposts or separate ads for one property can still be separate records.

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

Include nearby-area suggestions returned by Craigslist. ZIP/radius searches already use their requested circle and can cross region boundaries.

## `maxItemsPerSearch` (type: `integer`):

Leave blank for no additional cap. For example, set 10 to collect up to 10 ads from each city, subarea or URL. The Maximum rental ads — total setting still limits the combined output.

## `newOnly` (type: `boolean`):

Collect posting IDs not delivered by earlier runs of the same search. Only successfully saved ads enter the history. 💡 Price or description edits on the same ID are skipped; a repost with a new ID counts as new.

## `watchName` (type: `string`):

Optional name for a separate monitoring history. Reuse it with the same searches to continue collecting unseen posting IDs. Without a name, each saved Task has its own history. Run only one collection at a time for the same history.

## Actor input object example

```json
{
  "rentalCategory": "apa",
  "cities": [
    "newyork"
  ],
  "searchTitlesOnly": false,
  "sort": "date",
  "rentPeriods": [
    "monthly"
  ],
  "maxItems": 50,
  "includeDetails": true,
  "startUrls": [],
  "privateRoom": false,
  "privateBath": false,
  "catsAllowed": false,
  "dogsAllowed": false,
  "furnished": false,
  "noSmoking": false,
  "wheelchairAccessible": false,
  "airConditioning": false,
  "evCharging": false,
  "noApplicationFee": false,
  "noBrokerFee": false,
  "availability": "any",
  "hasImage": false,
  "postedToday": false,
  "showDuplicates": false,
  "includeNearby": false,
  "newOnly": false
}
```

# Actor output Schema

## `results` (type: `string`):

Rental records plus notices explaining empty, partial or limited results.

## `rentalsJson` (type: `string`):

All rental fields, including nested arrays and original attributes; no notice rows. Detail fields can be null when absent or not requested.

## `rentalsCsv` (type: `string`):

54 selected rental columns for spreadsheets; no notice rows. Arrays and objects are JSON strings. Use JSON for recordType and listingUuid.

## `runSummary` (type: `string`):

Applied parameters, counts, search-window limitations and monitoring history.

# 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"
    ],
    "startUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("arjun_code/craigslist-rentals-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"],
    "startUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("arjun_code/craigslist-rentals-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"
  ],
  "startUrls": []
}' |
apify call arjun_code/craigslist-rentals-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,arjun_code/craigslist-rentals-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/6BP4adbtkkCiFt8ny/builds/j6GJ6aBPMdMz1gr8V/openapi.json
