Craigslist Scraper avatar

Craigslist Scraper

Pricing

$1.00 / 1,000 results

Go to Apify Store
Craigslist Scraper

Craigslist Scraper

Search public Craigslist listings by city, category, keyword, or URL and export prices, descriptions, attributes, images, and approximate locations.

Pricing

$1.00 / 1,000 results

Rating

0.0

(0)

Developer

MLG Data

MLG Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Scrape public Craigslist classifieds by city, category, keyword, or a search URL and export Craigslist data as CSV or JSON. This Craigslist API alternative collects one row per posting, including prices, the full description, category attributes, images, and approximate location when detail enrichment is enabled.

The actor accepts both guided searches and URLs copied from the site. A search URL keeps its existing filters, which is useful for a carefully tuned search that includes a radius, a neighborhood, seller type, bedrooms, or other category-specific settings. Search results and posting details come from the public data used by Craigslist's own pages. No account is required.

What data can you extract from Craigslist?

Each output row is a listing. Fields are flat and stable; category-specific facts appear in the attributes object. The example values below describe the fields, while the complete real result in the output section shows how they fit together.

FieldDescriptionExample
urlDirect public posting linkhttps://www.craigslist.org/view/d/...
postIdNumeric posting identifier, stored as text7932622659
titleListing headlineElectric bike front suspension 20”x 4.00
priceUsdLegacy numeric price field; always read currency80
priceNumeric price in the listing's local currency80
currencyCurrency code for the cityUSD
regionCity hostnamenewyork
categorySlugCategory used for the searchsss
categoryLabelBroad category on the postingfor sale
subcategorySlugPosting's specific category codebop
subcategoryLabelSpecific category namebicycle parts - by owner
postedAtOriginal posting time, expressed in UTC2026-09-26T12:37:44Z
updatedAtUpdate time supplied by the posting data2026-09-26T12:32:44Z
locationSeller's displayed area descriptionbrooklyn
latitudeApproximate map latitude40.7012
longitudeApproximate map longitude-73.9436
attributesExtra fields provided for a category{"condition":"new"}
descriptionFull public posting bodyNew fork with lock system never installed
imageUrlsListing gallery image linksAn array of image URLs
hasImagesWhether at least one image is availabletrue
phoneNumbersNumbers explicitly written in the public body[]
emailsAddresses explicitly written in the public body[]
contactObfuscatedWhether the public body lacks direct contact detailstrue
replyTokenArea, category, and ID for the public reply routenyc/bop/7932622659
isDeletedDetail request reported a removed postingfalse
scrapedAtTime this row was collected, in UTC2026-09-26T14:15:32Z

priceUsd is retained for compatibility with existing pipelines, but its name is misleading outside US cities. Use price together with currency for calculations. attributes can contain keys such as condition, sale_manufacturer, bedrooms, or sqft; the available keys depend on the category and on what the poster supplied. Missing optional details are represented by null, an empty object, or an empty array rather than a fabricated value.

How to scrape Craigslist

  1. Choose a city and category. Enter an optional keyword such as bike, honda civic, or studio apartment. You can instead paste one or more public search or posting URLs into startUrls.
  2. Set filters that make the results useful: a local-currency price range, condition, image requirement, posted-today flag, or sort order. These guided filters apply when startUrls is empty.
  3. Choose a result limit and decide whether to include full details. With details enabled, each selected search result receives a posting request for its full body, specific category, attributes, and complete image list.
  4. Run the actor and inspect the dataset. Download the rows as JSON or CSV, or use the dataset endpoint in an existing workflow.

For example, a New York for-sale search for bike with a 40-row limit returned 40 rows in a verified run. Every row had a posting ID, URL, title, price, posting time, description, and region. The result order and individual postings will change as people add, edit, and remove listings.

Input

Guided parameters are used when startUrls is empty. A pasted URL wins over the city, category, keyword, and guided filters so that the search retains the exact settings already encoded in the URL. Multiple URLs are processed in their supplied order, with duplicate post IDs removed across the run.

ParameterTypeDefaultDescription
startUrlsURL listEmptySearch, category, or individual public posting URLs.
regionTextnewyorkCity subdomain for guided searches; any valid city hostname can be entered.
categorySelectsssBroad or specific category code for guided searches.
searchTermTextEmptyOptional terms matched by the site's search.
priceMinIntegerEmptyMinimum price in the city's local currency.
priceMaxIntegerEmptyMaximum price in the city's local currency.
conditionSelectanySeller-selected condition for applicable for-sale posts.
hasImageBooleanfalseRequire a listing image.
postedTodayBooleanfalseRequest listings marked as posted today.
sortSelectdateNewest, relevance, ascending price, or descending price.
includeDetailsBooleantrueEnrich each result with the full public posting data.
maxResultsInteger200Hard row cap across sources; 0 selects the internal 100,000-row cap.
proxyConfigurationObjectEnabledConnection settings for public page and data requests.

A small guided search:

{
"region": "newyork",
"category": "sss",
"searchTerm": "bike",
"sort": "date",
"includeDetails": true,
"maxResults": 40
}

For a search already configured in a browser, pass its URL instead:

{
"startUrls": [
"https://newyork.craigslist.org/search/sss?query=bike&min_price=50&hasPic=1"
],
"includeDetails": true,
"maxResults": 100
}

A URL can also point to an individual posting. This is useful for checking a known listing alongside a discovery search. The actor resolves the posting from its public page data and collects the same output structure. A posting that has been removed or become unavailable may not yield a row.

Output example

This is a real row from the 40-result New York bike search. The gallery is shortened to one URL for display; the dataset row contains all four image links.

{
"url": "https://www.craigslist.org/view/d/brooklyn-electric-bike-front-suspension/bVVrjbGiFSfJeR7wmVNNDq",
"postId": "7932622659",
"title": "Electric bike front suspension 20”x 4.00",
"priceUsd": 80,
"price": 80,
"currency": "USD",
"region": "newyork",
"categorySlug": "sss",
"categoryLabel": "for sale",
"subcategorySlug": "bop",
"subcategoryLabel": "bicycle parts - by owner",
"postedAt": "2026-09-26T12:37:44Z",
"updatedAt": "2026-09-26T12:32:44Z",
"location": "brooklyn",
"latitude": 40.7012,
"longitude": -73.9436,
"attributes": {},
"description": "New fork with lock system never installed\n\nHead tube diameter 28.6mm 8-3/4 long\n\nBreak Caliper spacing 74mm\n\nWheel spacing 135mm",
"imageUrls": [
"https://images.craigslist.org/00E0E_fLeUAIOretO_0t20CI_600x450.jpg"
],
"hasImages": true,
"phoneNumbers": [],
"emails": [],
"contactObfuscated": true,
"replyToken": "nyc/bop/7932622659",
"isDeleted": false,
"scrapedAt": "2026-09-26T14:15:32.572584Z"
}

The description is plain text. Line breaks are retained so that dimensions, lists, and paragraphs remain readable. Image URLs refer to the public gallery; image files themselves are not copied into the dataset. Public contact details are extracted only if a poster wrote them in the listing body. The reply relay is not opened or used.

Use cases

  • Local inventory tracking. A reseller can schedule a focused search by city, category, and price range, then compare post IDs over time. The dataset makes it straightforward to separate newly observed listings from repeat observations. A missing listing in a later search does not, by itself, prove deletion; it may have fallen outside the current result window.
  • Housing market observation. A researcher can collect apartments or rooms for selected cities and compare asking prices, neighborhood labels, and available category attributes. Geographic coordinates are approximate, so analysis should be aggregated to areas rather than used as exact addresses.
  • Vehicle comparison. A buyer can search cars and trucks by keyword and price, then use the complete description and category attributes to build a shortlist for manual review. Filters in a pasted URL can retain city-specific radius, seller type, and other options.
  • Job and gig discovery. A community organization can monitor a public jobs or gigs category for topics relevant to its members. Job listings often lack a numeric price, so the price field should be treated as optional rather than as a salary.
  • Catalog cleanup. A publisher with a collection of saved posting URLs can collect current public details into one structured dataset. IDs and URLs support deduplication and later checks, while scrapedAt records when the snapshot was taken.

These are snapshots of public listings, not a live inventory or a guarantee that an offer remains available. Review the original posting before making a decision or contacting a poster.

How much does it cost to scrape Craigslist?

The configured result price is $1.00 per 1,000 delivered rows. One output row is one result, whether details are enabled or disabled. Platform usage is included in the result price. A 40-row dataset corresponds to about $0.04 at this rate; billing rules and any account credits can affect the amount shown on a particular run.

Delivered rowsResult-price calculationEstimated charge
100100 × $0.001$0.10
1,0001,000 × $0.001$1.00
5,0005,000 × $0.001$5.00

Set maxResults before a broad search so that the expected number of rows is clear. The actor stops pushing rows at the cap or when the run's spending limit is reached. Detail enrichment adds requests and time, but does not add a second result row for the same posting.

Tips for best results

  • Start narrow. A city, specific category, and meaningful keyword usually produce a more relevant set than a city-wide all-for-sale query. Check the result count after a small run before increasing maxResults.
  • Use site URLs for advanced filters. If the guided fields do not cover a filter you use on the site, set the filter in a browser and paste the resulting search URL. The encoded query parameters are kept for that source.
  • Choose the detail setting deliberately. Turn includeDetails on when you need full descriptions, attributes, and specific categories. Turn it off for a faster sweep of titles, prices, timestamps, approximate locations, and available images.
  • Watch currency and optional prices. Canadian city results use CAD; US cities use USD. Jobs, community posts, and other categories can have no price. Do not sum priceUsd across regions without checking currency.
  • Deduplicate with postId. One posting may appear in more than one search or be encountered again in a later run. The actor removes duplicate IDs within a run; use the ID in your downstream system when combining runs.
  • Split broad searches. Large result sets can exceed the site's visible search window. Use category, city, subarea, keyword, price range, or date filters to create smaller searches, then combine and deduplicate their rows.

Limits

Craigslist changes its public search and posting data over time. A result count is a current snapshot, not a promise that every matching listing will remain available through the run. Individual postings can disappear between the search request and the detail request. In that case, isDeleted can be true and detail fields can be empty. A posting URL supplied directly may return no row if it is already unavailable.

Broad queries may be limited by the site's search window. The actor asks for the initial compact results and, when needed, retrieves the full visible result list in batches. It does not automatically split one query into every possible neighborhood, price, or date slice. For comprehensive collection, provide narrower URLs and use postId to merge the results. maxResults: 0 raises the actor's internal cap; it cannot override the site's own visibility limits.

Some fields depend on the category or poster. A seller may omit attributes, images, a direct phone number, or a direct email. Coordinates are approximate public map points and may be intentionally displaced. The exact street address is not inferred. contactObfuscated only describes whether a direct number or address appears in the public body; it does not guarantee that the poster can or cannot be contacted through the site. Timestamp values are taken from the site's data, even when an update time appears earlier than a displayed posting time.

Example requests for an automated workflow

  • “Collect up to 100 public for-sale listings matching bike in New York, newest first, and return each posting's description, price, images, and posting ID.”
  • “Use this filtered search URL for apartments, keep the URL's existing constraints, and return 50 rows with approximate neighborhood and any bedroom or floor-area attributes.”

These requests map directly to the input fields above. For repeat collection, retain the exact input and compare new dataset rows by postId and scrapedAt.

FAQ

Rules depend on the jurisdiction and intended use. Collect only public information, review the site's terms, and follow applicable privacy and data-protection law. Do not use phone numbers or email addresses for unsolicited messages, harassment, or other misuse. This actor does not access accounts or private replies.

Do I need to configure a proxy?

The default connection settings use the available proxy. The fetch layer starts with the cheaper connection route, rotates a session if blocked, and can escalate when required. Most users can leave proxyConfiguration at its default. A site block or network interruption can still reduce coverage for a particular run.

How long will a run take?

Time depends on result count and whether full details are requested. The verified 40-row run with details completed in about 30 seconds. Larger runs make more posting requests and will take longer. Response time can change with site load and connection conditions.

Can I schedule a search and monitor new listings?

Yes. Run the same saved input on a schedule, then compare postId values with previous datasets. scrapedAt marks the time each row was recorded. Keep the query narrow enough that fresh listings remain within the visible search window between scheduled runs.

Can I export to a spreadsheet?

Yes. Download the dataset as CSV for a spreadsheet or as JSON for a programmatic workflow. Nested attributes and imageUrls may appear as serialized values in a flat CSV export, while JSON preserves their object and array structure.

Why are some fields empty?

A poster may not provide a price, images, location, or category-specific attributes. Details can also be unavailable if a posting is removed after search. With includeDetails disabled, description, specific category labels, and reply information are intentionally left empty. Empty arrays mean no public phone numbers or addresses were found in the body.

Does priceUsd always mean US dollars?

No. It is a compatibility field. The numeric value uses the city's local currency, so read currency and prefer price for new integrations. For example, a Toronto posting can have currency: "CAD" while priceUsd still contains its local numeric price.

Integrations

The default dataset can be retrieved through the platform API, downloaded as CSV or JSON, sent through a webhook after a run, or processed by an existing automation service. A common monitoring workflow schedules a narrow query, reads each new dataset, compares postId with stored IDs, and sends an alert only for listings that match a rule. Preserve the original url in any alert so a reviewer can inspect the current posting before acting.

Support

Open an issue on the Issues tab; we reply within 24h and add fields on request. Include the input that produced the problem, a sample public posting URL if relevant, and the run identifier so the behavior can be reproduced.