Lead generation
Craigslist Multi-City Listings Scraper
Scrape Craigslist listings across dozens of US metro areas and 7 categories in one run — title, price, location, images, posted/updated dates, structured attributes, and the public reply link, normalized into one clean dataset instead of one run per city.
Free Apify credit covers a first run. No credit card to try.
What this Actor scrapes
Craigslist's own search pages (/search/area/<areaSlug>) and listing-detail pages (/view/d/<slug>/<postId>) -- fanned out across every metro area and category you pick, in one Actor call instead of one run per city. Point it at a single area, or union in a curated top-US-metro preset, pick one or all seven top-level categories, and get back a single normalized dataset: title, price, location, coordinates, images, posted and updated timestamps, structured attributes, description, and the public reply-flow link. Every request runs through our full anti-blocking stack by default -- rotating browser-fingerprint impersonation, session-rotated proxying, retries with backoff -- the same defenses every Devil Scrapes Actor ships, so your dataset holds up even if Craigslist changes its defenses tomorrow.
What we handle for you
- 🛡️ We rotate browser fingerprints on every request --
curl-cffiimpersonates real Chrome, Firefox, and Safari TLS/HTTP handshakes, so nothing about the traffic looks like a bare Python script, today or if Craigslist tightens up tomorrow. - 🌐 We rotate Apify Proxy sessions -- a fresh session ID and exit IP on any request that comes back looking blocked, no manual restart needed.
- 🔁 We retry with exponential backoff on
408 / 429 / 5xx, honouringRetry-After-- up to 5 attempts before we give up on a page. - 🧱 We pace to the target's rate limits and isolate faults per combo -- one slow metro or blocked category logs a warning and gets skipped; the rest of the run keeps going, and partial progress is always reported via a clear status message, never a silent empty dataset.
- 🧊 Clean, typed dataset rows -- every row is
ResultRow-validated (Pydantic), ISO-8601 timestamps, stable post IDs, ready to export as JSON, CSV, or Excel. - 💰 Pay-per-result pricing -- a small one-off
actor-startcharge, then you pay only for rows that land in your dataset.
Use cases
- Reseller and arbitrage price-scanning across dozens of metros in a single run, instead of one Actor call per city.
- Multi-city lead-generation list building for local-services and real-estate outreach.
- Rental and vehicle market intelligence -- price and inventory tracked across metros side by side.
- Apartment and job aggregation, normalized into one schema instead of stitching together per-city exports.
- Posting-velocity research -- track price drops and reposts via
posted_at,updated_at, andis_edited_or_price_drop.
Input
Paste this into the Apify Console, or send it as the run input over the API. Proxy settings are on by default; you rarely need to touch them.
| Field | Type | Required | What it does |
|---|---|---|---|
areas | array | no | Craigslist area slugs to search (e.g. "newyork", "losangeles") from /about/sites. Combined with All top US metros below when that's enabled. Up to 20 entries. |
allTopUsMetros | boolean | no | Union in a curated list of up to 25 top-US-metro Craigslist area slugs (not the full ~700-area directory) on top of anything listed in Areas. |
categories | array | no | Top-level Craigslist category codes to search: sss (for sale), cta (cars & trucks), reo (real estate), apa (apartments/housing), jjj (jobs), bbb (community), ggg (gigs). Use "all" to expand to all 7. |
query | string | no | Single search term, passed verbatim to Craigslist's search. Leave empty to browse a category with no keyword filter. |
maxResultsPerCombo | integer | no | Cap on listings collected per (area, category) combo. 300 is Craigslist's observed single-page result-set ceiling. |
fetchDetails | boolean | no | When enabled, fetch each listing's detail page for posted/updated dates, full description, structured attributes, and the public reply-flow URL. When disabled, only search-list fields are returned. |
postedWithinDays | integer | no | Drop listings older than this many days. Only enforceable when Fetch listing detail pages is enabled -- posting date is a detail-page-only field. |
maxRunMinutes | integer | no | Run-wide wall-clock budget. New (area, category) combos stop being started once this is exceeded; already-collected rows are still flushed. |
{
"areas": [
"newyork"
],
"allTopUsMetros": false,
"categories": [
"sss"
],
"query": "iphone",
"maxResultsPerCombo": 3,
"fetchDetails": true,
"postedWithinDays": null,
"maxRunMinutes": 5,
"proxyConfiguration": {
"useApifyProxy": true
}
} Output
One row per result, schema-validated before it is written. Export JSON, CSV, Excel or XML from the run, or read it over the API.
area_slugcategory_codetitlepricelocation_textdetail_urlposted_atupdated_atis_edited_or_price_dropattributesreply_url
{
"area_slug": "newyork",
"category_code": "sss",
"query": "iphone",
"post_id": "7812345678",
"title": "iPhone 14 Pro 256GB Unlocked",
"price": 550.0,
"currency": "USD",
"location_text": "Queens",
"latitude": 40.7282,
"longitude": -73.7949,
"images": [
"https://images.craigslist.org/00A0A_abc_600x450.jpg"
],
"detail_url": "https://www.craigslist.org/view/d/queens/7812345678",
"posted_at": "2026-08-05T09:12:00-0400",
"updated_at": "2026-08-09T14:03:00-0400",
"is_edited_or_price_drop": true,
"description": "Barely used, comes with box and charger...",
"attributes": {
"condition": "like new",
"make": "apple"
},
"reply_url": "https://newyork.craigslist.org/reply/que/sss/7812345678/abc123",
"repost_fingerprint": "a1b2c3d4",
"scraped_at": "2026-08-12T12:00:00.000Z"
} Pricing
| Event | Price | When |
|---|---|---|
| Actor start | $0.20 | Once per run, covers warm-up and proxy session setup. |
| Result emitted | $0.0020 | Per result written to the dataset. |
You pay only for results that land. Cap any run with maxTotalChargeUsd. See pricing & billing for worked examples.
Limitations
- Each
(area, category)combo returns up tomaxResultsPerCombo(max 300) -- Craigslist's observed single-page ceiling. There's no pagination past that in v1. - Total combos (
areas x categories, post-resolution) are capped at 150 per run, a FREE-tier compute guardrail -- split very large fan-outs across multiple runs. allTopUsMetrosunions in a curated list of up to 25 metro slugs, not the full ~700-area Craigslist directory.- One
queryterm per run -- no multi-keyword search in a single call. reply_urlis captured exactly as Craigslist renders it on the listing page. We never open it, solve any verification step it triggers, or de-obfuscate a masked email -- that boundary is deliberate, and Craigslist's ownrobots.txtdisallows the reply flow.repost_fingerprintis a best-effort hash (normalized title + area + category), not a guaranteed unique dedup key.postedWithinDaysonly filters whenfetchDetailsis enabled -- posting date lives on the detail page only.
FAQ
Can I get a seller's phone number or email from this?
reply_url exactly as Craigslist places it on the listing page, but we never open it, solve any verification step it triggers, or de-obfuscate a masked email. That's a deliberate scope boundary, not a technical shortfall -- Craigslist's own robots.txt disallows the reply flow, and we respect it.Why one run instead of one run per city?
What happens if one city or category is unreachable mid-run?
(area, category) combo -- a dead metro or a blocked category logs a warning and gets skipped, the rest of the run keeps going, and you get a clear status message on what finished. We never fail the whole run over one bad combo, and we never hand back a silent empty dataset.Do I need Residential proxy?
proxyConfiguration to Residential anytime you want that extra layer for larger or more aggressive runs.How fresh are `posted_at` and `updated_at`?
fetchDetails is on. Turn fetchDetails off to skip the detail-page fetch entirely and get search-list fields only, faster and cheaper.Is this legal to run?
Ready to run it?
Open the listing on Apify, paste the input above, and watch rows land. If it ever breaks, it is our problem before it is yours.
Related Actors