# Craigslist Email Scraper (`leads-scraper/craigslist-email-scraper`) Actor

Craigslist Email Scraper SD - Craigslist Email Scraper is a lead generation tool that extracts leads with public contact emails, account names and profile URLs from Craigslist results by keyword, location and email domain - Craigslist email extractor.

- **URL**: https://apify.com/leads-scraper/craigslist-email-scraper.md
- **Developed by:** [Leads Scraper](https://apify.com/leads-scraper) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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 Email Scraper

The Craigslist Email Scraper collects publicly indexed contact emails connected to `craigslist.org`, the classified network that still carries an enormous volume of local services, gigs and for-sale listings.
It builds Google queries with the `site:craigslist.org` operator, fetches them through the Apify GOOGLE\_SERP proxy, and extracts emails from the result blocks.
No login, no browser, no Craigslist API — only what Google has already published in its index.

**Start with the honest part.** Craigslist posts are anonymised and expire quickly, and its subdomains are cities rather than accounts, so rows identify a city board rather than a person.
Craigslist deliberately relays contact through masked addresses, and old posts fall out of the index. Both facts cap what any SERP-based tool can recover here.

The measured evidence reflects that. In a live test run, roughly 10 parsed results produced 3 unique emails, 2 rows with a usable label and 2 resolvable profile URLs — and those URLs were city boards such as `https://sfbay.craigslist.org/`, not seller profiles.

This is also the odd one out in its Actor family.
The other 34 are travel and hospitality tools; the Craigslist Email Scraper is broad local classified prospecting — tradespeople, service businesses, gig posters and for-sale traders — rather than a restaurant tool.

#### What one run of the Craigslist Email Scraper produces

Each dataset row is one unique email plus whatever context Google printed around it.
You get the raw title, a label where one exists, a cleaned snippet, the exact query used and a truncation flag.
The Craigslist Email Scraper pushes rows to the Apify dataset as they are found, so you can export CSV, JSON or Excel mid-run.

#### Exporting and integrating the Craigslist Email Scraper dataset

Because rows are written incrementally, an aborted or migrated run still leaves whatever it found behind.
Export from the Apify console, pull the dataset over the API, or schedule the Craigslist Email Scraper weekly and push results straight into your CRM.

### How the Craigslist Email Scraper works: SERP parsing, not an API

The Craigslist Email Scraper runs the same six steps on every query it builds.

1. It reads your input: keywords, location, email domains and limits.
2. It builds Google queries with the `site:` operator, for example `site:craigslist.org services "@gmail.com" "call or text" "Austin"`.
3. It fetches result pages through the Apify GOOGLE\_SERP proxy using async `aiohttp` requests.
4. It parses each result block structurally — locating the `<h3>` and the smallest surrounding block — rather than by CSS class name.
5. It extracts emails with a domain-filtered regex and normalises obfuscated forms.
6. It deduplicates globally and pushes each lead to the dataset immediately.

There is no browser, no JavaScript rendering, no authentication and no cookies.
The Craigslist Email Scraper never signs into Craigslist and never requests pages from Craigslist's own servers.
Everything it returns was already public in Google's search index at the time of the run.

### What the Craigslist Email Scraper is actually good for

Craigslist is not a directory of businesses; it is a stream of posts.
That changes what a lead from it means, and it is worth being explicit about the categories that work.

| Category | Who you find | Typical buyer |
|---|---|---|
| Services | Contractors, movers, cleaners, tutors, photographers | Agencies, insurers, tool and supply vendors |
| Gigs | Freelancers, event crews, temporary labour | Recruiters, staffing platforms |
| For sale by dealer | Small resellers, equipment traders, dealers | Wholesalers, marketplaces, B2B distributors |
| Community and events | Organisers, venues, class providers | Event suppliers, local sponsors |
| Housing (commercial) | Landlords, property managers, sublet brokers | Proptech, maintenance and insurance vendors |

The obfuscation-handling in the email extractor matters unusually much on this platform.
Classified posters routinely write `name (at) gmail (dot) com` or `name @ gmail.com` to dodge naive scrapers, and those forms are normalised before matching.

#### City-level prospecting with `location`

`location` is the single most valuable input in the Craigslist Email Scraper, because Craigslist is organised city by city and so is almost every use case for its data.
It appends a quoted phrase to every query, so you can build one dataset per market instead of one national dump.

Useful values are the metros with the largest boards: `San Francisco`, `New York`, `Los Angeles`, `Chicago`, `Seattle`, `Austin`, `Denver`, `Boston`, `Atlanta`, `Portland`.
Neighbourhood and county phrases work too when a metro board is too broad for a field team.

Because `profileUrl` resolves to a city subdomain rather than a person, `location` is often the only geographic signal you can trust.
Set it deliberately on every run, and tag the resulting dataset with it.

#### Keyword and modifier suggestions

The shipped defaults are `for sale` and `services`, with `email`, `contact`, `call or text`, `inquiries` and `owner` as modifiers.
Those modifiers are already tuned to classified-ad phrasing — `call or text` in particular matches how posters write contact lines.

| Keyword | Why it works on Craigslist |
|---|---|
| `handyman` | High-volume services category with direct contact details |
| `landscaping` | Seasonal trades that post repeatedly |
| `moving` | Small operators who publish an email for quotes |
| `catering` | Independent food businesses advertising locally |
| `photographer` | Freelancers who list a working inbox |
| `commercial equipment` | Dealers and liquidators in for-sale categories |
| `wholesale` | Traders and resellers moving stock |
| `event staffing` | Gig posters hiring crews |

Pair a trade noun with an intent modifier — `handyman "call or text"`, `wholesale inquiries` — rather than searching a bare noun.

### Craigslist Email Scraper features

Everything listed below is implemented in the Craigslist Email Scraper today.

| Feature | What it means in practice |
|---|---|
| Query expansion | Base, quoted, `intitle:` and one variant per modifier; base queries run first |
| Global deduplication | An email found by several queries is stored exactly once |
| Email normalisation | Understands `name [at] domain [dot] com`, `name (at) domain`, `name @ domain`, `domain .com`, zero-width characters and the full-width `＠` — heavily used in classified posts |
| Junk filter | Rejects placeholders such as `email@`, `yourname@`, `test@`, `xxx@` and single-character locals |
| Boundary-correct matching | `@gmail.com` will not match inside `@gmail.company` or `@gmail.com.br` |
| Soft-wrap repair | Drops a hit that is only the tail of another email in the same block |
| Structural parsing | Independent of Google's obfuscated CSS class names |
| Whole-page fallback | A markup change degrades to "emails without account details" rather than "no emails" |
| Block detection | CAPTCHA, "unusual traffic" and consent pages are detected and retried, not counted as empty |
| Retries | Up to 3 attempts per page with exponential backoff and a fresh proxy session per request |
| Failed-query requeue | Blocked or failed queries are re-queued once at the end of the run |
| Concurrency | An `asyncio` worker pool with a shared stop signal on `maxEmails` |
| Resumable state | Key-value store state keyed by an input hash; saves on `PERSIST_STATE`, `MIGRATING` and `ABORTING` |
| Run summary | Logs pages fetched, blocked pages, retries and emails per page |

### Craigslist Email Scraper input fields

These are the exact input fields the Craigslist Email Scraper accepts, with the defaults it ships with.

| Field | Type | Default | Meaning |
|---|---|---|---|
| `keywords` | array (required) | `["for sale","services"]` | Search terms describing the posts you want |
| `location` | string | `""` | Optional location phrase added to every query |
| `customDomains` | array | `["@gmail.com","@yahoo.com"]` | Only emails on these domains are kept; `@` optional |
| `maxEmails` | integer 1-10000 | `20` | Stop after this many unique emails |
| `countryCode` | string | `""` | Two-letter country for the search proxy — `US` covers most boards |
| `expandQueries` | boolean | `true` | Search each keyword x domain in several phrasings |
| `queryModifiers` | array | `["email","contact","call or text","inquiries","owner"]` | Extra words combined with each keyword when expansion is on |
| `maxPagesPerQuery` | integer 1-50 | `30` | Page cap per query |
| `maxConcurrency` | integer 1-20 | `5` | Parallel queries |

#### Example Craigslist Email Scraper input

```json
{
  "keywords": ["handyman", "moving", "commercial equipment"],
  "location": "Austin",
  "customDomains": ["@gmail.com", "@yahoo.com", "@hotmail.com", "@aol.com"],
  "maxEmails": 150,
  "countryCode": "US",
  "expandQueries": true,
  "queryModifiers": ["email", "contact", "call or text", "inquiries", "owner"],
  "maxPagesPerQuery": 30,
  "maxConcurrency": 5
}
```

Widening `customDomains` is unusually productive here, because classified posters use whatever personal mailbox they already have.
`@aol.com`, `@hotmail.com`, `@icloud.com` and `@outlook.com` are all worth testing alongside the defaults.

### Craigslist Email Scraper output fields

Every dataset item the Craigslist Email Scraper writes carries all fourteen of these fields.

| Field | Meaning |
|---|---|
| `network` | Platform name |
| `keyword` | The keyword that produced the lead |
| `query` | The exact Google query used |
| `title` | Raw result title |
| `accountName` | Account label Google prints |
| `fullName` | Display name parsed from a profile-style title; empty for post captions |
| `username` | URL-safe handle when the platform exposes one; otherwise `null` |
| `profileUrl` | Canonical account URL when a handle is known; otherwise empty |
| `url` | Direct platform link when exposed, else the profile URL |
| `description` | Bio or snippet text, cleaned of labels and engagement counters |
| `email` | Lower-cased email address |
| `emailDomain` | The matched domain |
| `possiblyTruncated` | `true` when Google's snippet ellipsis touched the email |
| `foundAt` | ISO 8601 UTC timestamp |

#### Example Craigslist Email Scraper output

```json
[
  {
    "network": "Craigslist",
    "keyword": "handyman",
    "query": "site:craigslist.org handyman \"@gmail.com\" \"call or text\" \"Austin\"",
    "title": "Handyman & Remodel - licensed, 15 yrs - austin",
    "accountName": "craigslist",
    "fullName": "Handyman & Remodel - licensed, 15 yrs",
    "username": "austin",
    "profileUrl": "https://austin.craigslist.org/",
    "url": "https://austin.craigslist.org/",
    "description": "Carpentry, drywall, tile. Free estimates - email or call or text: atx.handyman.jobs@gmail.com",
    "email": "atx.handyman.jobs@gmail.com",
    "emailDomain": "@gmail.com",
    "possiblyTruncated": false,
    "foundAt": "2026-08-31T16:11:20Z"
  },
  {
    "network": "Craigslist",
    "keyword": "commercial equipment",
    "query": "site:craigslist.org commercial equipment \"@aol.com\" inquiries \"Austin\"",
    "title": "Restaurant equipment liquidation - fryers, coolers",
    "accountName": "",
    "fullName": "",
    "username": null,
    "profileUrl": "",
    "url": "",
    "description": "Clearing a full kitchen. Serious inquiries only: txequipment.sales@aol.com",
    "email": "txequipment.sales@aol.com",
    "emailDomain": "@aol.com",
    "possiblyTruncated": true,
    "foundAt": "2026-08-31T16:13:47Z"
  }
]
```

Read the first row's `profileUrl` carefully. `https://austin.craigslist.org/` is the Austin city board, not a seller account.
Craigslist's subdomains are cities rather than accounts, so `username` — when populated at all — is a city code such as `austin`, `sfbay` or `newyork`.

The second row is the more common shape: an expired or unresolvable post with `username: null` and an empty `profileUrl`.
Everything you can act on is in `email`, `title` and `description`.

#### What a measured Craigslist Email Scraper run looked like

Per roughly 10 parsed results in a live test: 2 rows with a usable label, 2 resolvable profile URLs and 3 unique emails.
Low across the board, and the profile URLs point at city boards rather than people.

Plan around the address and the snippet.
The `description` field is the most informative column in a Craigslist dataset, because it carries the trade, the offer and often the poster's own contact phrasing.

### Local lead generation use cases for the Craigslist Email Scraper

Here is where the Craigslist Email Scraper fits into real local B2B prospecting and market research.

| Use case | How to configure it |
|---|---|
| Local trades and services prospecting | `keywords: ["handyman","landscaping","moving"]`, one metro per run |
| Recruiting and staffing sourcing | `keywords: ["event staffing","gigs"]` with an `inquiries` modifier |
| Wholesale and liquidation sourcing | `keywords: ["commercial equipment","wholesale"]` |
| Small-business software sales | Services categories, where owner-operators post their own inbox |
| Insurance and finance for tradespeople | `keywords: ["contractor","handyman"]` per city |
| Local agency client acquisition | One metro per run; pitch web, ads or booking-system work |
| Marketplace supply acquisition | Recruit dealers and resellers off `for sale by dealer` categories |
| Event and venue supplier prospecting | `keywords: ["catering","photographer"]` per market |
| Local market research | Compare row counts per trade keyword across cities |
| CRM enrichment | Match on `email`; do not rely on `profileUrl` for identity |

### Practical Craigslist Email Scraper recipes

**Single-metro trades run.** Three trade keywords, four mail domains, one city in `location`, `maxEmails: 150`.
This is the configuration most likely to return usable local leads.

**Obfuscation sweep.** Keep `expandQueries` on and rely on the normaliser.
Classified posters write `at` and `dot` in words far more often than other platforms, and those variants are handled before matching.

**Domain widening.** Add `@aol.com`, `@hotmail.com`, `@icloud.com` and `@outlook.com`.
On a platform full of personal mailboxes, domain breadth beats keyword depth.

**Run it often, not deep.** Posts expire, so a weekly job over the same city surfaces new material that a single deep run never will.
Google caps a single query at roughly 300 results anyway, so frequency beats `maxPagesPerQuery`.

**Different family, different job.** If you actually want restaurants, use the [OpenTable Email Scraper](https://apify.com/neuro-scraper/opentable-email-scraper) or [Zomato Email Scraper](https://apify.com/leads-scraper/zomato-email-scraper) instead — the Craigslist Email Scraper is a general local-classifieds tool, not a hospitality one.

### Responsible use, GDPR and CAN-SPAM

Craigslist addresses are unusually likely to belong to private individuals rather than registered businesses, so treat this dataset more carefully than a business directory.
An email that identifies a natural person is personal data even when it was published publicly, and public availability is not consent to send.

Commercial email into the United States falls under CAN-SPAM; EU or UK recipients bring the GDPR into scope.
Craigslist's own terms also restrict automated collection and unsolicited contact — read them and make your own assessment before running outreach.

Practical steps that keep a Craigslist Email Scraper workflow defensible:

- Prefer posts that clearly advertise a business over posts from private individuals.
- Keep provenance for every lead — the `query`, `url` and `foundAt` fields exist for exactly this.
- Give a clear sender identity, a stated purpose and a working opt-out in every message.
- Include a valid physical postal address in commercial email, as CAN-SPAM requires.
- Honour opt-outs immediately and check suppression lists before each follow-up.
- Delete data you are not actively using; posts expire, and stale personal data is a liability.

This is operational guidance, not legal advice.

### Related Actors

The Craigslist Email Scraper sits in a Travel, Hospitality and Food family of 35 Actors that all share this engine, even though its own subject matter is broader.
If your target is genuinely restaurants or travel businesses, the **OpenRice Email Scraper**, [Resy Email Scraper](https://apify.com/leads-scraper/resy-email-scraper) and [Booking.com Email Scraper](https://apify.com/leads-scraper/booking-com-email-scraper) will serve you far better.

| Actor | What it collects |
|---|---|
| [Craigslist Email and Phone Number Scraper](https://apify.com/leads-scraper/craigslist-email-and-phone-number-scraper) | Emails and phone numbers from Craigslist |
| [Craigslist Phone Number Scraper](https://apify.com/leads-scraper/craigslist-phone-number-scraper) | Public phone numbers from Craigslist |
| [Airbnb Email Scraper](https://apify.com/leads-scraper/airbnb-email-scraper) | Public contact emails from Airbnb |
| [Booking.com Email Scraper](https://apify.com/leads-scraper/booking-com-email-scraper) | Public contact emails from Booking.com |
| [Caviar Email Scraper](https://apify.com/neuro-scraper/caviar-email-scraper) | Public contact emails from Caviar |
| [ChowNow Email Scraper](https://apify.com/neuro-scraper/chownow-email-scraper) | Public contact emails from ChowNow |
| [Contiki Email Scraper](https://apify.com/neuro-scraper/contiki-email-scraper) | Public contact emails from Contiki |
| [Delivery.com Email Scraper](https://apify.com/neuro-scraper/delivery-com-email-scraper) | Public contact emails from Delivery.com |
| [DoorDash Email Scraper](https://apify.com/leads-scraper/doordash-email-scraper) | Public contact emails from DoorDash |
| [EatStreet Email Scraper](https://apify.com/neuro-scraper/eatstreet-email-scraper) | Public contact emails from EatStreet |
| [G Adventures Email Scraper](https://apify.com/neuro-scraper/g-adventures-email-scraper) | Public contact emails from G Adventures |
| [GetYourGuide Email Scraper](https://apify.com/leads-scraper/getyourguide-email-scraper) | Public contact emails from GetYourGuide |
| [Grubhub Email Scraper](https://apify.com/leads-scraper/grubhub-email-scraper) | Public contact emails from Grubhub |
| [Hostelbookers Email Scraper](https://apify.com/leads-scraper/hostelbookers-email-scraper) | Public contact emails from Hostelworld |
| [HotelsCombined Email Scraper](https://apify.com/neuro-scraper/hotelscombined-email-scraper) | Public contact emails from HotelsCombined |
| [Intrepid Travel Email Scraper](https://apify.com/neuro-scraper/intrepid-travel-email-scraper) | Public contact emails from Intrepid Travel |
| [Just Eat Email Scraper](https://apify.com/leads-scraper/just-eat-email-scraper) | Public contact emails from Just Eat |
| [Klook Email Scraper](https://apify.com/neuro-scraper/klook-email-scraper) | Public contact emails from Klook |
| [OpenTable Email Scraper](https://apify.com/neuro-scraper/opentable-email-scraper) | Public contact emails from OpenTable |
| [Resy Email Scraper](https://apify.com/leads-scraper/resy-email-scraper) | Public contact emails from Resy |
| [TheFork Email Scraper](https://apify.com/leads-scraper/thefork-email-scraper) | Public contact emails from TheFork |
| [Toast Restaurant Email Scraper](https://apify.com/leads-scraper/toast-restaurant-email-scraper) | Public contact emails from Toast |
| [TourRadar Email Scraper](https://apify.com/leads-scraper/tourradar-email-scraper) | Public contact emails from TourRadar |
| [Traveloka Email Scraper](https://apify.com/leads-scraper/traveloka-email-scraper) | Public contact emails from Traveloka |
| [Tripadvisor Attractions Email Scraper](https://apify.com/leads-scraper/tripadvisor-attractions-email-scraper) | Public contact emails from Tripadvisor |
| [Tripadvisor Hotels Email Scraper](https://apify.com/leads-scraper/tripadvisor-hotels-email-scraper) | Public contact emails from Tripadvisor |
| [Tripadvisor Restaurants Email Scraper](https://apify.com/leads-scraper/tripadvisor-restaurants-email-scraper) | Public contact emails from Tripadvisor |
| [Uber Eats Email Scraper](https://apify.com/leads-scraper/uber-eats-email-scraper) | Public contact emails from Uber Eats |
| [Viator Email Scraper](https://apify.com/leads-scraper/viator-email-scraper) | Public contact emails from Viator |
| [Wanderlog Email Scraper](https://apify.com/leads-scraper/wanderlog-email-scraper) | Public contact emails from Wanderlog |
| [Wego Email Scraper](https://apify.com/leads-scraper/wego-email-scraper) | Public contact emails from Wego |
| [Zomato Email Scraper](https://apify.com/leads-scraper/zomato-email-scraper) | Public contact emails from Zomato |
| [Airbnb Email and Phone Number Scraper](https://apify.com/leads-scraper/airbnb-email-and-phone-number-scraper) | Emails and phone numbers from Airbnb |
| [Booking.com Email and Phone Number Scraper](https://apify.com/leads-scraper/booking-com-email-and-phone-number-scraper) | Emails and phone numbers from Booking.com |
| [Caviar Email and Phone Number Scraper](https://apify.com/neuro-scraper/caviar-email-and-phone-number-scraper) | Emails and phone numbers from Caviar |
| [ChowNow Email and Phone Number Scraper](https://apify.com/neuro-scraper/chownow-email-and-phone-number-scraper) | Emails and phone numbers from ChowNow |
| [Contiki Email and Phone Number Scraper](https://apify.com/neuro-scraper/contiki-email-and-phone-number-scraper) | Emails and phone numbers from Contiki |
| [Delivery.com Email and Phone Number Scraper](https://apify.com/neuro-scraper/delivery-com-email-and-phone-number-scraper) | Emails and phone numbers from Delivery.com |
| [DoorDash Email and Phone Number Scraper](https://apify.com/leads-scraper/doordash-email-and-phone-number-scraper) | Emails and phone numbers from DoorDash |
| [EatStreet Email and Phone Number Scraper](https://apify.com/neuro-scraper/eatstreet-email-and-phone-number-scraper) | Emails and phone numbers from EatStreet |
| [G Adventures Email and Phone Number Scraper](https://apify.com/neuro-scraper/g-adventures-email-and-phone-number-scraper) | Emails and phone numbers from G Adventures |
| [Grubhub Email and Phone Number Scraper](https://apify.com/neuro-scraper/grubhub-email-and-phone-number-scraper) | Emails and phone numbers from Grubhub |

### Craigslist Email Scraper limitations

Read these before planning anything around Craigslist Email Scraper output.

- **Craigslist posts are anonymised and expire quickly, and its subdomains are cities rather than accounts, so rows identify a city board rather than a person.** This is the defining limitation of the Craigslist Email Scraper.
- **Low yield.** In a live test, roughly 10 parsed results produced 3 unique emails, 2 usable labels and 2 profile URLs.
- **Publicly indexed emails only.** The Craigslist Email Scraper finds addresses already visible in Google's index. Masked relay addresses and expired posts are unreachable.
- **Google's ~300-result cap.** A single query returns roughly 300 results at most, which is why `expandQueries` defaults to `true`.
- **`possiblyTruncated`.** When `true`, Google's snippet ellipsis touched the email and it may be cut off. Verify before sending.
- **`username` and `profileUrl` identify a city, not an account.** Where populated, `username` is a city code and `profileUrl` is `https://{city}.craigslist.org/`. Where nothing resolves, `username` is `null`. That is a Google and platform limitation, not a bug.
- **Personal rather than business addresses.** Many posters are private individuals, which raises the compliance bar on any outreach.
- **Apify GOOGLE\_SERP proxy required.** The Craigslist Email Scraper cannot run without Apify proxy credentials.
- **Free-plan cap.** Free Apify plans stop at 100 emails per run. Paid plans are uncapped.
- **No guaranteed volume.** Results vary with keywords, domains, location and Google's index on the day.
- **Not affiliated with Craigslist.** This is an independent tool, not supported, endorsed by or connected to craigslist, Inc.

### Craigslist Email Scraper FAQ

Common questions about the Craigslist Email Scraper, its inputs and its output.

#### How many results should I expect from the Craigslist Email Scraper?

Few. In a live test, roughly 10 parsed results produced 3 unique emails, 2 usable labels and 2 profile URLs, and those URLs were city boards. Craigslist posts are anonymised and expire quickly, so treat this as a supplementary source rather than a primary lead engine.

#### Why does `profileUrl` point at a city instead of a seller?

Because Craigslist's subdomains are cities rather than accounts, so rows identify a city board rather than a person. The Actor builds `https://{city}.craigslist.org/` when a city code resolves, and leaves the field empty otherwise.

#### Is this a restaurant scraper like the rest of the family?

No. It shares the engine and the category, but Craigslist is broad local classified prospecting — services, gigs and for-sale traders. For restaurants, use a hospitality-specific Actor instead.

#### Does the Craigslist Email Scraper log into Craigslist?

No. It never logs in, never calls a Craigslist API and never opens craigslist.org in a browser. It reads Google results through the Apify GOOGLE\_SERP proxy.

#### Which keywords work best?

Trade and category nouns: `handyman`, `landscaping`, `moving`, `catering`, `photographer`, `commercial equipment`, `wholesale`, `event staffing`. Keep the `call or text` modifier — it matches how classified posters write contact lines.

#### How do I use `location` for city-level prospecting?

Put a metro in it — `Austin`, `Seattle`, `San Francisco` — and run one job per market. It is the only geographic signal you can rely on, since `profileUrl` resolves only to a city board.

#### Which email domains should I add?

Widen aggressively: `@aol.com`, `@hotmail.com`, `@outlook.com` and `@icloud.com` alongside the defaults. Classified posters use whatever personal mailbox they already have.

#### Does it handle obfuscated addresses like `name (at) gmail (dot) com`?

Yes. The normaliser handles bracketed `at`/`dot`, spaced `@`, zero-width characters and the full-width `＠` before matching — all common in classified posts.

#### Does the Craigslist Email Scraper verify deliverability?

No. It extracts and normalises what Google indexed. Check rows flagged `possiblyTruncated` before using them, and expect some addresses on expired posts to be dead.

#### Can I resume an interrupted run?

Yes. State lives in the key-value store keyed by a hash of your input, with saves on Apify's `PERSIST_STATE`, `MIGRATING` and `ABORTING` events.

#### What happens when Google blocks a request?

Block, CAPTCHA and consent pages are detected rather than treated as empty. Pages get up to three attempts with exponential backoff, and failed queries are re-queued once at the end of the run.

#### Is scraping Craigslist contact emails legal?

The Craigslist Email Scraper only reads publicly indexed Google results. Craigslist's own terms restrict automated collection and unsolicited contact, and many posters are private individuals, so CAN-SPAM and GDPR obligations bite harder here. Read the responsible use section and take your own legal advice.

### Leave a review

If the Craigslist Email Scraper saved you time, please leave a star rating and a short review
on the Actor page.

Reviews are how other buyers judge whether a tool works, and they tell us which features to
build next.

If something did not work, email <neurodata.apify@gmail.com>
instead - bugs get fixed faster than they get complained about.

### Support

Questions, a bug, or you need a custom build of the Craigslist Email Scraper? Contact **<neurodata.apify@gmail.com>**.

# Actor input Schema

## `keywords` (type: `array`):

Search terms describing the Craigslist accounts you want (niche, job title, industry).

## `location` (type: `string`):

Optional location phrase added to every query (e.g. "New York").

## `customDomains` (type: `array`):

Only emails ending with one of these domains are collected. With or without the leading @. Each domain is searched separately, so more domains means more results but a longer run - remove some for a faster, narrower search, or add your own (e.g. @company.com).

## `maxEmails` (type: `integer`):

Stop once this many unique emails have been collected.

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

Two-letter country code for the search proxy (e.g. US, GB, DE). Empty for any.

## `expandQueries` (type: `boolean`):

Search each keyword x domain pair with several phrasings. Recommended - Google caps a single query at ~300 results.

## `queryModifiers` (type: `array`):

Extra words combined with each keyword when Expand queries is on. Tuned for Craigslist.

## `maxPagesPerQuery` (type: `integer`):

Google rarely returns more than ~30 pages for one query.

## `maxConcurrency` (type: `integer`):

How many queries run in parallel.

## Actor input object example

```json
{
  "keywords": [
    "for sale",
    "services"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com",
    "@yahoo.com"
  ],
  "maxEmails": 20,
  "countryCode": "",
  "expandQueries": true,
  "queryModifiers": [
    "email",
    "contact",
    "call or text",
    "inquiries",
    "owner"
  ],
  "maxPagesPerQuery": 30,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

Records produced by Craigslist Email Scraper, stored in the run's default dataset.

# 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 = {
    "keywords": [
        "for sale",
        "services"
    ],
    "location": "",
    "customDomains": [
        "@gmail.com",
        "@yahoo.com"
    ],
    "countryCode": "",
    "queryModifiers": [
        "email",
        "contact",
        "call or text",
        "inquiries",
        "owner"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("leads-scraper/craigslist-email-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 = {
    "keywords": [
        "for sale",
        "services",
    ],
    "location": "",
    "customDomains": [
        "@gmail.com",
        "@yahoo.com",
    ],
    "countryCode": "",
    "queryModifiers": [
        "email",
        "contact",
        "call or text",
        "inquiries",
        "owner",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("leads-scraper/craigslist-email-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 '{
  "keywords": [
    "for sale",
    "services"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com",
    "@yahoo.com"
  ],
  "countryCode": "",
  "queryModifiers": [
    "email",
    "contact",
    "call or text",
    "inquiries",
    "owner"
  ]
}' |
apify call leads-scraper/craigslist-email-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,leads-scraper/craigslist-email-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/LG4WKSC2ZEkTxSmoM/builds/s5iSCUJL3zMwkb7vq/openapi.json
