# 🧹 Cleaning Company Leads Scraper - Emails & Phones (`renzomacar/cleaning-services-leads-scraper`) Actor

Build cleaning company lead lists in minutes: maid services, janitorial and commercial cleaners with phone, website, emails and social profiles extracted live from each company's site. For suppliers, software and agencies selling to cleaners. $8 per 1,000 leads.

- **URL**: https://apify.com/renzomacar/cleaning-services-leads-scraper.md
- **Developed by:** [Renzo Madueno](https://apify.com/renzomacar) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 leads

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🧹 Cleaning Company Leads Scraper — Residential & Commercial Emails & Phones

Cleaning is two markets wearing one name. **Residential** — maid services and house cleaners, small crews, owner answers the phone. **Commercial** — janitorial companies bidding office and facility contracts, bigger fleets, procurement emails. This Actor scrapes both, separately or together, for any city: **company name, phone, website, address, emails and social profiles extracted live from each company's own website** — $8 per 1,000 companies.

### Residential vs commercial: search them the way buyers do

Each keyword runs as its own search and tags its rows via `searchQuery`, so one run gives you pre-segmented lists:

| You sell to... | Use keywords |
|---|---|
| House cleaning franchises & booking software | `house cleaning service`, `maid service`, `move out cleaning` |
| Janitorial supply, chemicals, equipment | `janitorial service`, `commercial cleaning service` |
| Specialty verticals | `carpet cleaning service`, `window cleaning service`, `pressure washing service` |

Leave keywords empty and it sweeps all six default segments at once.

### What lands in each row

`name`, `category`, `address` (+parsed `city`/`country`), `phone` and `websitePhones[]`, `website`, `email`/`emails[]`/`emailFound`, `socialProfiles` (Facebook, Instagram, LinkedIn, Twitter), `techStack[]`, `rating`, `reviewsCount`, `placeUrl`, coordinates, `scrapedAt`. One consolidated row per company — export CSV/Excel/JSON or pull via API into your CRM or cold-email tool.

### Why this beats a purchased janitorial list

Cleaning has brutal churn — crews appear and disappear in months, which is exactly what makes bought databases stale on arrival. Here everything is scraped **at run time**: if a janitorial company won a big contract and finally launched a website last month, you get that. And because you build the list yourself per city and segment, no competitor is mailing the identical file.

It's also how you find the *underserved* half: rows with `emailFound: false` and few reviews are young companies nobody else is pitching — and you still have their phone.

### Costs

- $0.008 per company delivered — **$8 per 1,000**
- $0.01 start fee per run
- Typical full-metro sweep (all segments): 250–600 companies, $2–5. Empty run: $0.01.

### Quick start

```json
{
  "location": "Seattle, WA",
  "keywords": ["house cleaning service", "janitorial service"],
  "maxResults": 100,
  "maxPagesPerSite": 2
}
```

Multiple cities in one run: `"searchQueries": ["commercial cleaning service in Tampa, FL", "commercial cleaning service in Orlando, FL"]`.

### FAQ

**Email coverage in this niche?**
Residential cleaners are phone/booking-form first: expect emails on roughly 35–55% of companies with a website. Commercial janitorial skews higher — bid requests arrive by email, so they publish one. Filter on `emailFound` after export.

**How do I keep residential and commercial apart in the output?**
Sort by `searchQuery` — each row remembers which keyword found it. Run them as separate keywords (not one big sweep) if you want clean separation.

**Franchise locations (Merry Maids, Jani-King)?**
Included like any listing; franchisees share corporate domains, so dedupe on `website` if you only want independents.

**Can I schedule weekly refreshes?**
Yes — Apify schedules work natively. Weekly per territory + a diff against your CRM surfaces brand-new companies while they're still shopping for suppliers and software.

**Is using this data legal?**
It's publicly listed business info plus emails companies publish on their own sites to be contacted. Follow CAN-SPAM, CASL or GDPR rules for your outreach channel.

**What about companies without websites?**
Delivered by default with phone/address/rating — prime cold-call material. Set `onlyWithWebsite: true` to drop them; dropped companies are never charged.

### Short-term rental turnover and move-out cleaning

A segment that did not exist ten years ago and appears in no purchased janitorial list. These companies are built around a property manager's calendar, not a household's:

```
airbnb cleaning service in Scottsdale, AZ
vacation rental cleaning company in Sedona, AZ
turnover cleaning service in Phoenix, AZ
move out cleaning service in Tempe, AZ
post construction cleaning company in Mesa, AZ
```

Put these in **Custom search queries** — each line runs as its own live Maps search, and a company listed under several of them is merged into a single row before you are charged.

They are the best-fit buyers in the whole vertical for scheduling and dispatch software, because their scheduling problem is genuinely hard: same-day turnarounds, keys, and a booking calendar they do not control.

### Commercial janitorial and specialty contract cleaning

Commercial cleaning is a contract business with real revenue per account, and it is a different buyer from residential maid services:

```
commercial cleaning company in Columbus, OH
janitorial services company in Dublin, OH
office cleaning service in Westerville, OH
medical office cleaning in Columbus, OH
industrial cleaning company in Grove City, OH
```

Commercial firms maintain proper websites with a quote form, so `contactPageUrl` is populated on most rows and email coverage runs well above the residential average. `techStack` will often show HubSpot or a Google Tag Manager container — a reliable tell that the company already runs paid acquisition and has a marketing budget to talk about.

### Carpet, upholstery and restoration companies

```
carpet cleaning company in Tampa, FL
upholstery cleaning service in Brandon, FL
water damage restoration company in Tampa, FL
mold remediation company in St. Petersburg, FL
tile and grout cleaning service in Clearwater, FL
```

Restoration is the money end: IICRC-certified firms doing insurance work carry equipment budgets and franchise relationships that a residential maid service never will. They are also phone-first — every row carries the Maps number plus up to four more numbers pulled from the company's own site, with the Maps number filtered out so it never occupies one of those four slots.

# Actor input Schema

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

City, region or country to search in, e.g. 'Seattle, WA', 'Austin, TX', 'London, UK'.

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

Which cleaning segments to search for, one per line. Good options: 'house cleaning service', 'commercial cleaning service', 'maid service', 'janitorial service', 'carpet cleaning service', 'window cleaning service', 'pressure washing service', 'move out cleaning'. Leave empty to search all common segments at once.

## `searchQueries` (type: `array`):

Full searches, one per line (e.g. 'commercial cleaning service in Tampa, FL'). When set, these override Location + cleaning segments. Use several queries to cover multiple cities in one run.

## `maxResults` (type: `integer`):

Maximum number of companies to find per search. One search typically yields up to ~120 companies.

## `maxPagesPerSite` (type: `integer`):

How many pages to check on each company website when hunting for emails (homepage, /contact, /about...). More pages = more emails found, slightly slower run.

## `onlyWithWebsite` (type: `boolean`):

Drop companies that have no website (they can never have an email). You are not charged for dropped companies.

## `includeGenericEmails` (type: `boolean`):

Keep every published address, including shared inboxes like info@, hello@ and contact@. Disable to drop only non-deliverable system addresses (noreply@, no-reply@, donotreply@, mailer-daemon@, postmaster@, webmaster@, hostmaster@, abuse@).

## `language` (type: `string`):

Language code for the discovery search (e.g. 'en', 'es', 'fr', 'de').

## Actor input object example

```json
{
  "location": "Seattle, WA",
  "keywords": [
    "house cleaning service"
  ],
  "maxResults": 5,
  "maxPagesPerSite": 1,
  "onlyWithWebsite": false,
  "includeGenericEmails": true,
  "language": "en"
}
```

# Actor output Schema

## `leads` (type: `string`):

Complete B2B leads (company, website, phone, address, emails, social profiles), one item per lead in the 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 = {
    "location": "Seattle, WA",
    "keywords": [
        "house cleaning service"
    ],
    "maxResults": 5,
    "maxPagesPerSite": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("renzomacar/cleaning-services-leads-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 = {
    "location": "Seattle, WA",
    "keywords": ["house cleaning service"],
    "maxResults": 5,
    "maxPagesPerSite": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("renzomacar/cleaning-services-leads-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 '{
  "location": "Seattle, WA",
  "keywords": [
    "house cleaning service"
  ],
  "maxResults": 5,
  "maxPagesPerSite": 1
}' |
apify call renzomacar/cleaning-services-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,renzomacar/cleaning-services-leads-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/cvbZ1nixuEw2YXqnl/builds/di7OlDas8yOoos5ur/openapi.json
