# Contractor Lead Scraper — Verified Emails (HVAC, Plumbing) (`muhammadafzal/contractor-lead-scraper`) Actor

Scrape HVAC, plumber, roofer & electrician contacts from Google Maps with verified emails & phones. Real-time data from contractor websites. Export to HubSpot, Salesforce, or CSV. Built for home services marketing & SaaS sales.

- **URL**: https://apify.com/muhammadafzal/contractor-lead-scraper.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 enriched contractor 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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

### Contractor Lead Scraper — Verified Emails (HVAC, Plumbing, Roofing, Electricians)

Generate a targeted HVAC contractor email list, plumber leads database, roofer contact list, or electrician leads directory — scraped live from Google Maps with verified contact details. This actor covers the full home services trades: HVAC companies, plumbers, roofers, electricians, general contractors, landscapers, painters, and pest control businesses, returning verified emails, phone numbers, addresses, ratings, and social links ready to import into your CRM.

Built for construction suppliers, home service SaaS companies, insurance brokers, subcontractor networks, and anyone who needs a contractor email list at scale — without paying for an overpriced, stale data subscription.

#### Key Features

- **Google Maps search** — Find contractor businesses by trade type and location, powered by Playwright
- **Email extraction** — Automatically crawls contractor websites to find contact emails
- **DNS + SMTP verification** — Confirms email deliverability before export to minimize bounces
- **Social media links** — Extracts Facebook, Instagram, LinkedIn, and Twitter/X profiles
- **CRM-ready export** — Output in Full, HubSpot Import, or Salesforce Import format
- **Real-time data** — Fresh results scraped on demand, not a stale broker database
- **Deduplication** — Automatically removes duplicate listings from overlapping search results
- **No coding required** — Configure via form, click Start, download your contractor leads

### Use cases

- **HVAC leads and contractor prospecting**: Build an HVAC contractor email list or plumber leads database for any city or region in minutes — ideal for equipment suppliers, parts distributors, and refrigerant wholesalers targeting buying managers by territory.
- **Electrician and roofer lead generation**: Source electrician leads and roofing contractor contacts for product sales, subcontractor recruitment, or regional outreach. Filter by review count to prioritize high-volume, established businesses.
- **Home service SaaS prospecting**: Find home service leads for field service management, scheduling, invoicing, or estimating software by targeting active contractors in your region.
- **Commercial insurance outreach**: Build targeted contractor email lists for commercial liability, bonding, and workers' comp campaigns.
- **Subcontractor sourcing**: Identify qualified subcontractors by trade, city, and rating. Contact owners directly via verified email.
- **Construction supply and material sales**: Reach plumbing supply buyers, HVAC equipment purchasers, roofing material buyers, and electrical supply contacts by scraping contractors in your distribution territory.

### How it works

1. **Search Google Maps** — The actor navigates to Google Maps, searches for the specified contractor trade in the target location, and scrolls through results to collect all listings.
2. **Extract listing data** — For each listing, it captures business name, category, address, phone, website, rating, review count, hours, coordinates, and the Google Maps URL.
3. **Enrich from website** — The actor visits each contractor's website (homepage + contact/about pages) to extract email addresses and social media links using pattern matching and DOM analysis.
4. **Verify email deliverability** — Every email candidate is checked via DNS/MX lookup and SMTP handshake to confirm deliverability before being marked `email_verified: true`. No actual emails are sent.
5. **Format and export** — Results are deduplicated, normalized, and pushed to the dataset in your chosen format (Full, HubSpot Import, or Salesforce Import).

### Input parameters

| Parameter | Type | Default | Required | Description |
|-----------|------|---------|----------|-------------|
| `businessType` | string | `"HVAC Company"` | Yes | Contractor trade to search for. Options: HVAC Company, Plumber, Roofer, Electrician, General Contractor, Landscaper, Painter, Pest Control, Custom. |
| `location` | string | `"Dallas, TX"` | Yes | City, state, ZIP, or metro area to search within. |
| `searchQuery` | string | `"HVAC companies in Dallas, TX"` | No | Raw Google Maps query — only used when `businessType` is `Custom`. |
| `maxResults` | integer | `50` | No | Maximum leads to collect. Prefill is 3 for a quick test; 50–200 for production. |
| `enrichEmails` | boolean | `true` | No | Visit each contractor website to extract email addresses from contact/about pages. |
| `verifyEmails` | boolean | `true` | No | Verify email deliverability via DNS MX + SMTP handshake. Only applies when `enrichEmails` is enabled. |
| `enrichSocials` | boolean | `true` | No | Scan contractor websites for Facebook, Instagram, LinkedIn, and Twitter/X links. |
| `outputFormat` | string | `"full"` | No | Output structure: `full` (all fields), `hubspot` (HubSpot CSV import columns), `salesforce` (Salesforce import columns). |
| `proxyUrl` | string | `""` | No | Custom HTTP proxy URL (format: `http://user:pass@host:port`). Leave empty to use Apify's residential proxies. |

### Output data

Each record in the dataset contains:

| Field | Type | Description |
|-------|------|-------------|
| `business_name` | string | Contractor business name |
| `business_type` | string | The search business type used |
| `category` | string\|null | Google Maps business category (e.g., "HVAC contractor") |
| `phone` | string\|null | Phone number from Google Maps |
| `email` | string\|null | Primary verified email extracted from contractor website |
| `email_verified` | boolean\|null | Whether email passed DNS MX + SMTP verification |
| `email_verification_status` | string\|null | `smtp_verified`, `dns_only`, `unverified`, or `unknown` |
| `email_verification_note` | string\|null | Human-readable verification result |
| `all_emails` | array\|null | All emails found on the site, each with verification status |
| `website` | string\|null | Contractor website URL |
| `address` | string\|null | Full street address |
| `rating` | number\|null | Google Maps star rating (0–5) |
| `review_count` | integer\|null | Total Google reviews |
| `hours` | string\|null | Operating hours summary |
| `facebook` | string\|null | Facebook page URL |
| `instagram` | string\|null | Instagram profile URL |
| `linkedin` | string\|null | LinkedIn company page URL |
| `twitter` | string\|null | Twitter/X profile URL |
| `google_maps_url` | string\|null | Direct Google Maps listing link |
| `place_id` | string\|null | Google Place ID |
| `latitude` | number\|null | GPS latitude |
| `longitude` | number\|null | GPS longitude |
| `scraped_at` | string | ISO 8601 timestamp of extraction |
| `source_url` | string | Google Maps search URL used |

#### Sample output

```json
{
    "business_name": "Comfort Air Solutions",
    "business_type": "HVAC Company",
    "category": "HVAC contractor",
    "phone": "(214) 555-0192",
    "email": "service@comfortairsolutions.com",
    "email_verified": true,
    "email_verification_status": "smtp_verified",
    "email_verification_note": "Verified via SMTP",
    "all_emails": [
        {
            "address": "service@comfortairsolutions.com",
            "verified": true,
            "status": "smtp_verified",
            "verificationNote": "Verified via SMTP"
        }
    ],
    "website": "https://comfortairsolutions.com",
    "address": "4521 Maple Ave, Dallas, TX 75219",
    "rating": 4.7,
    "review_count": 312,
    "hours": "Mon-Fri 7:00 AM - 6:00 PM",
    "facebook": "https://facebook.com/comfortairsolutions",
    "instagram": null,
    "linkedin": null,
    "twitter": null,
    "google_maps_url": "https://www.google.com/maps/place/Comfort+Air+Solutions/@32.8032,-96.8067,17z",
    "place_id": "ChIJb5xK7wLQIYURxjM",
    "latitude": 32.8032,
    "longitude": -96.8067,
    "scraped_at": "2026-06-24T12:00:00.000Z",
    "source_url": "https://www.google.com/maps/search/HVAC%20Company%20in%20Dallas"
}
````

### Pricing

This actor uses **pay-per-event pricing**: $0.05 per enriched contractor lead.

#### Cost examples

| Leads | Cost |
|-------|------|
| 10 leads | $0.50 |
| 50 leads | $2.50 |
| 100 leads | $5.00 |
| 200 leads | $10.00 |

You only pay for successfully enriched leads. If the actor fails to collect a lead, you are not charged.

### Code examples

#### Run the actor via API

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('USERNAME/contractor-lead-scraper').call({
    businessType: 'HVAC Company',
    location: 'Dallas, TX',
    maxResults: 50,
    enrichEmails: true,
    verifyEmails: true,
    enrichSocials: true,
    outputFormat: 'hubspot',
});

const dataset = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${dataset.items.length} contractor leads`);
```

#### Run via Apify CLI

```bash
apify run --input='{"businessType":"Plumber","location":"Miami, FL","maxResults":25}'
```

#### Schedule a daily run

```bash
apify schedule create --actor USERNAME/contractor-lead-scraper \
  --cron "0 8 * * 1" \
  --input '{"businessType":"HVAC Company","location":"Dallas, TX","maxResults":50}'
```

### FAQ

#### Why do some leads have no email?

Not all contractors list an email on their website. Some use contact forms or only list a phone number. The actor scans the homepage, contact page, and about page — if no email is found, the `email` field will be `null`. You are not charged for leads without enrichment data beyond the Google Maps listing.

#### How accurate is email verification?

The actor performs a two-step check: (1) DNS MX record lookup to confirm the domain accepts email, and (2) an SMTP handshake to verify the specific mailbox exists. This catches most invalid emails, but some mail servers reject SMTP probes for security reasons — those will show `email_verification_status: "unknown"` rather than confirmed valid.

#### What does the `email_verification_status` field mean?

- `smtp_verified` — Email passed both DNS MX lookup and SMTP mailbox check. Safe to send.
- `dns_only` — Domain has an A record accepting mail but SMTP probe was skipped or unavailable.
- `unverified` — Email failed verification (invalid domain or rejected mailbox).
- `unknown` — Verification could not complete (timeout or connection error).

#### Can I search multiple locations?

Run the actor once per location. For territory-wide prospecting, run sequential searches for each city or ZIP code in your target area and merge the datasets. Each run deduplicates internally by business name.

#### What's the difference between output formats?

- **Full** — All fields in the actor's native schema. Best for API integrations and custom processing.
- **HubSpot Import** — Column names mapped to HubSpot's CSV import format. Download the dataset as CSV and upload directly to HubSpot.
- **Salesforce Import** — Column names mapped to Salesforce's data import format, with `LeadSource` pre-filled as "Google Maps Scraper". Download as CSV and use Salesforce Data Import.

#### Does it work outside the US?

Yes. Google Maps returns results globally. The search query is built from the business type and location you provide. For non-US locations or niche trades not in the dropdown, use the `Custom` business type and write your own query.

### Technical details

- **Crawler**: PlaywrightCrawler with stealth mode and randomized viewports for anti-bot evasion
- **Proxy**: Apify residential proxies by default, or custom proxy URL supported
- **Email verification**: DNS MX lookup + SMTP RCPT TO handshake (8-second timeout per email)
- **Deduplication**: Results are deduplicated by business name within each run
- **Resource blocking**: Images, fonts, media, and tracking scripts are blocked for faster crawling
- **Session pool**: Up to 5 browser sessions with rotation to avoid rate limiting

### Limitations

- Google Maps typically returns up to ~120 results per search query. Use multiple locations for larger datasets.
- Email extraction depends on the business having a website with publicly visible contact info. Businesses using only contact forms will not have emails extracted.
- SMTP verification may be blocked by some mail servers, resulting in `unknown` status rather than confirmed valid or invalid.
- Google Maps CSS selectors change occasionally — the actor uses multiple fallback selectors to handle this.

Export scraped data, run the scraper via API, schedule and monitor runs, or integrate with other tools using the Apify platform.

# Actor input Schema

## `businessType` (type: `string`):

Select the contractor trade to search on Google Maps. The actor builds the query automatically — e.g., 'HVAC Company' finds heating, cooling, and air conditioning contractors in your city; 'Plumber' finds licensed plumbing contractors; 'Roofer' finds roofing companies; 'Electrician' finds electrical contractors. Choose 'Custom' to write your own search query for any other trade type.

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

The city, state, or ZIP code to search for contractors in. Use 'City, ST' format for best results (e.g., 'Dallas, TX', 'Phoenix, AZ', 'Chicago, IL'). ZIP codes and neighborhoods also work. For multi-city coverage, run the actor once per location and merge datasets — each run fully covers one market.

## `searchQuery` (type: `string`):

A raw Google Maps search query — only used when Business Type is set to 'Custom'. Use this to target trades not in the dropdown, such as 'concrete contractors in Denver, CO', 'pool builders near Orlando, FL', or 'waterproofing companies in Seattle, WA'. Write the query exactly as you would type it into Google Maps.

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

Maximum number of contractor leads to return. The prefill is 3 for a quick quality test — increase to 50–200 for production prospecting. Google Maps caps at ~120 results per search; run multiple locations to build larger datasets. Start small to verify results match your target trade and geography before scaling.

## `enrichEmails` (type: `boolean`):

When enabled, the actor visits each contractor's website and scans contact pages, footers, and about pages to extract email addresses. Disable if you only need phone numbers and addresses, or to run faster without website crawling. Most HVAC, plumbing, and electrical contractor sites publish a contact email in the footer or on a Contact page.

## `verifyEmails` (type: `boolean`):

When enabled, each extracted email is checked via DNS/MX lookup and SMTP handshake to confirm the mailbox exists and can receive mail — without sending any actual message. Adds ~1 minute per batch but significantly reduces bounce rates on outreach campaigns. Only applies when 'Find Email Addresses' is enabled. Verified emails are flagged with email\_verified: true in the output.

## `enrichSocials` (type: `boolean`):

When enabled, the actor scans each contractor website for social media profile links: Facebook, Instagram, LinkedIn, and Twitter/X. Useful for multi-channel outreach, ad targeting (Facebook Custom Audiences), and account research before contacting. Many HVAC and plumbing companies are active on Facebook even when they lack a strong website.

## `outputFormat` (type: `string`):

Controls the structure of the output dataset. 'Full' returns all fields for custom pipelines. 'HubSpot Import' maps columns to HubSpot Contact and Company import properties for direct CSV upload with zero remapping. 'Salesforce Import' aligns to the Salesforce Lead object with LeadSource pre-filled. All formats are downloadable from Apify as CSV, JSON, or Excel.

## `proxyUrl` (type: `string`):

Optional HTTP proxy URL for using third-party residential proxies instead of Apify's built-in proxies. Format: http://username:password@host:port. Compatible with IPRoyal, Smartproxy, Bright Data, and other rotating proxy services. Leave empty to use Apify's default residential proxies.

## Actor input object example

```json
{
  "businessType": "HVAC Company",
  "location": "Dallas, TX",
  "searchQuery": "HVAC companies in Dallas, TX",
  "maxResults": 3,
  "enrichEmails": true,
  "verifyEmails": true,
  "enrichSocials": true,
  "outputFormat": "full"
}
```

# Actor output Schema

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

Link to the dataset containing all extracted contractor leads.

# 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 = {
    "businessType": "HVAC Company",
    "location": "Dallas, TX",
    "searchQuery": "HVAC companies in Dallas, TX",
    "maxResults": 3,
    "enrichEmails": true,
    "verifyEmails": true,
    "enrichSocials": true,
    "outputFormat": "full"
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/contractor-lead-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 = {
    "businessType": "HVAC Company",
    "location": "Dallas, TX",
    "searchQuery": "HVAC companies in Dallas, TX",
    "maxResults": 3,
    "enrichEmails": True,
    "verifyEmails": True,
    "enrichSocials": True,
    "outputFormat": "full",
}

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/contractor-lead-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "businessType": "HVAC Company",
  "location": "Dallas, TX",
  "searchQuery": "HVAC companies in Dallas, TX",
  "maxResults": 3,
  "enrichEmails": true,
  "verifyEmails": true,
  "enrichSocials": true,
  "outputFormat": "full"
}' |
apify call muhammadafzal/contractor-lead-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=muhammadafzal/contractor-lead-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Contractor Lead Scraper — Verified Emails (HVAC, Plumbing)",
        "description": "Scrape HVAC, plumber, roofer & electrician contacts from Google Maps with verified emails & phones. Real-time data from contractor websites. Export to HubSpot, Salesforce, or CSV. Built for home services marketing & SaaS sales.",
        "version": "1.0",
        "x-build-id": "24zaTLh20ykvfDFm8"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/muhammadafzal~contractor-lead-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-muhammadafzal-contractor-lead-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/muhammadafzal~contractor-lead-scraper/runs": {
            "post": {
                "operationId": "runs-sync-muhammadafzal-contractor-lead-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/muhammadafzal~contractor-lead-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-muhammadafzal-contractor-lead-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "businessType": {
                        "title": "Business Type",
                        "enum": [
                            "HVAC Company",
                            "Plumber",
                            "Roofer",
                            "Electrician",
                            "General Contractor",
                            "Landscaper",
                            "Painter",
                            "Pest Control",
                            "Custom"
                        ],
                        "type": "string",
                        "description": "Select the contractor trade to search on Google Maps. The actor builds the query automatically — e.g., 'HVAC Company' finds heating, cooling, and air conditioning contractors in your city; 'Plumber' finds licensed plumbing contractors; 'Roofer' finds roofing companies; 'Electrician' finds electrical contractors. Choose 'Custom' to write your own search query for any other trade type.",
                        "default": "HVAC Company"
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "The city, state, or ZIP code to search for contractors in. Use 'City, ST' format for best results (e.g., 'Dallas, TX', 'Phoenix, AZ', 'Chicago, IL'). ZIP codes and neighborhoods also work. For multi-city coverage, run the actor once per location and merge datasets — each run fully covers one market."
                    },
                    "searchQuery": {
                        "title": "Custom Search Query",
                        "type": "string",
                        "description": "A raw Google Maps search query — only used when Business Type is set to 'Custom'. Use this to target trades not in the dropdown, such as 'concrete contractors in Denver, CO', 'pool builders near Orlando, FL', or 'waterproofing companies in Seattle, WA'. Write the query exactly as you would type it into Google Maps."
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of contractor leads to return. The prefill is 3 for a quick quality test — increase to 50–200 for production prospecting. Google Maps caps at ~120 results per search; run multiple locations to build larger datasets. Start small to verify results match your target trade and geography before scaling.",
                        "default": 50
                    },
                    "enrichEmails": {
                        "title": "Find Email Addresses",
                        "type": "boolean",
                        "description": "When enabled, the actor visits each contractor's website and scans contact pages, footers, and about pages to extract email addresses. Disable if you only need phone numbers and addresses, or to run faster without website crawling. Most HVAC, plumbing, and electrical contractor sites publish a contact email in the footer or on a Contact page.",
                        "default": true
                    },
                    "verifyEmails": {
                        "title": "Verify Email Deliverability",
                        "type": "boolean",
                        "description": "When enabled, each extracted email is checked via DNS/MX lookup and SMTP handshake to confirm the mailbox exists and can receive mail — without sending any actual message. Adds ~1 minute per batch but significantly reduces bounce rates on outreach campaigns. Only applies when 'Find Email Addresses' is enabled. Verified emails are flagged with email_verified: true in the output.",
                        "default": true
                    },
                    "enrichSocials": {
                        "title": "Find Social Media Links",
                        "type": "boolean",
                        "description": "When enabled, the actor scans each contractor website for social media profile links: Facebook, Instagram, LinkedIn, and Twitter/X. Useful for multi-channel outreach, ad targeting (Facebook Custom Audiences), and account research before contacting. Many HVAC and plumbing companies are active on Facebook even when they lack a strong website.",
                        "default": true
                    },
                    "outputFormat": {
                        "title": "Output Format",
                        "enum": [
                            "full",
                            "hubspot",
                            "salesforce"
                        ],
                        "type": "string",
                        "description": "Controls the structure of the output dataset. 'Full' returns all fields for custom pipelines. 'HubSpot Import' maps columns to HubSpot Contact and Company import properties for direct CSV upload with zero remapping. 'Salesforce Import' aligns to the Salesforce Lead object with LeadSource pre-filled. All formats are downloadable from Apify as CSV, JSON, or Excel.",
                        "default": "full"
                    },
                    "proxyUrl": {
                        "title": "Custom Proxy URL (optional)",
                        "type": "string",
                        "description": "Optional HTTP proxy URL for using third-party residential proxies instead of Apify's built-in proxies. Format: http://username:password@host:port. Compatible with IPRoyal, Smartproxy, Bright Data, and other rotating proxy services. Leave empty to use Apify's default residential proxies."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
