# Dental & Healthcare Provider Google Maps Lead Generator (`clura/dental-google-maps-lead-generator`) Actor

Scrapes dentist, orthodontist, and healthcare provider leads from Google Maps by location, with email/services/social enrichment from each practice's website. Drives the real Clura Chrome extension headlessly.

- **URL**: https://apify.com/clura/dental-google-maps-lead-generator.md
- **Developed by:** [Clura](https://apify.com/clura) (community)
- **Categories:** Lead generation, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 lead without enrichments

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

## Dental & Healthcare Provider Google Maps Lead Generator

Scrapes dentist, orthodontist, and healthcare provider leads directly from Google Maps by location — business name, rating, category, address, phone, website, and a direct Google Maps listing link — then visits each practice's own website to detect email addresses, the specific dental services they offer, and their social media profiles.

Built on a real Chrome browser driven by the actual Clura Chrome extension (not a lightweight HTTP scraper), so it holds up against the same anti-bot measures a real user's browser would face, and self-heals its selectors with AI if Google changes Maps' markup.

### How it works

1. **Search Google Maps** — for each location you provide, the actor searches Google Maps for each of your chosen practice types (Dentist, Orthodontist, Cosmetic Dentist, Emergency Dentist, Pediatric Dentist, Oral Surgeon, Periodontist, or your own custom search terms), rotating across all of them to surface more distinct practices per area than a single generic query would.
2. **Extract listing data** — business name, rating, category, address, phone, website, and Google Maps URL are read directly from the search results.
   - Dental/medical listings are a special case: Google Maps renders these cards without the "Website"/"Call" quick-action buttons that most other business categories get (confirmed by testing — every home-services or professional-services category we checked has them, dental/medical consistently doesn't). When that happens, the actor automatically visits the practice's full Google Maps listing page instead, where website and phone are reliably present, and fills them in from there.
3. **Deduplicate** — practices found under more than one search term (e.g. "Dentist" and "Cosmetic Dentist" both surfacing the same office) are merged into one record, keyed on phone number first, then website domain.
4. **Enrich from each practice's website** — the actor visits each practice's homepage once and extracts:
   - The first email address found on the page
   - Which of 12 dental service categories the page mentions (General Dentistry, Cosmetic Dentistry, Orthodontics/Invisalign, Emergency Dental Care, Pediatric Dentistry, Oral Surgery, Dental Implants, Teeth Whitening, Root Canal, Periodontics, Dentures/Prosthodontics, Same-Day Appointments)
   - Facebook, Instagram, LinkedIn, and Twitter/X profile links

### Input

| Field | Type | Description |
|---|---|---|
| `locations` | array (required) | Zip codes or city/state to search, e.g. `["75201", "Austin, TX"]`. Every search term runs once per location. |
| `searchTerms` | array | Practice types to search for. Defaults to the 8 standard ones listed above if left empty — add your own for a custom search. |
| `maxLeadsPerSearch` | integer | Max leads per location × search-term combination. Default 30. |
| `maxPagesPerSearch` | integer | Max scroll/pagination steps per search before stopping. Default 5. |
| `enrichWebsite` | boolean | Visit each lead's website to extract email/services/social links. Default true. |
| `openaiApiKey` | string | Only used if Google Maps' markup has changed enough that the built-in selectors stop working, to re-detect them via AI. Optional. |
| `proxyConfiguration` | object | Apify Proxy settings. |

### Output

Each record: `name`, `rating`, `category`, `address`, `phone`, `website`, `mapsUrl`, `searchTerm`, `location`, `email`, `services` (array), `emergency24_7` (boolean), `socialLinks` (object).

### What this actor does NOT do (please read before running)

- **No email verification.** Extracted emails are exactly what's published on the practice's website — there's no DNS/SMTP deliverability check. Some competing actors advertise this; we don't do it yet, and would rather say so plainly than ship something unreliable.
- **Homepage only.** Website enrichment reads the practice's homepage — it doesn't crawl into separate Contact/About/Services pages.
- **No review count.** Google Maps' search-results list doesn't render review count for every listing (confirmed by direct inspection — some cards show hours or other info in that slot instead), so it isn't a reliable field to offer here.
- Results per search are capped by what Google Maps itself returns for a single query (typically well under 200).

### Who this is for

- **Dental/medical equipment and supply distributors** sourcing practices to sell into.
- **PE and roll-up acquirers** building a target list of independent practices.
- **Marketing agencies** serving dental clients who need fresh prospect lists.
- **Recruiters** sourcing for dental practices in a specific market.
- **Market research** — practice density and service mix by city.

# Actor input Schema

## `locations` (type: `array`):

Zip codes or city/state to search, e.g. \["75201", "Austin, TX"]. Every search term below is run once per location.

## `searchTerms` (type: `array`):

Dental and healthcare practice types to search for, rotated across each location to surface more leads (Google Maps' ranking varies by query wording). Defaults to the 8 standard practice types if left empty: Dentist, Dental Clinic, Orthodontist, Cosmetic Dentist, Emergency Dentist, Pediatric Dentist, Oral Surgeon, Periodontist. Add your own for a custom search.

## `maxLeadsPerSearch` (type: `integer`):

Maximum leads to collect per location x search term combination.

## `maxPagesPerSearch` (type: `integer`):

Maximum pagination steps (scrolls) per search before stopping.

## `enrichWebsite` (type: `boolean`):

Visit each lead's website homepage to extract email, detected dental service categories, and social media links.

## `crawlContactPages` (type: `boolean`):

If the homepage has no email, follow one Contact/About-style link on the site to look there too. Costs one extra page visit per lead that needs it. Default false.

## `openaiApiKey` (type: `string`):

Used only if Google Maps' markup has changed enough that the built-in recipe stops working, to re-map fields via AI. Falls back to the OPENAI\_API\_KEY env var if omitted.

## `proxyConfiguration` (type: `object`):

Apify Proxy settings to route the browser's traffic through.

## `recipeOverride` (type: `object`):

Advanced use only. Overrides the actor's built-in Google Maps selectors.

## Actor input object example

```json
{
  "locations": [
    "Austin, TX"
  ],
  "searchTerms": [
    "Dentist"
  ],
  "maxLeadsPerSearch": 5,
  "maxPagesPerSearch": 2,
  "enrichWebsite": true,
  "crawlContactPages": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Every lead found, one row per business — the actor's main result.

## `runSummary` (type: `string`):

Status, total leads found, searches run, searches that needed the contact-page fallback, and how many leads had an email — one JSON record for the whole run.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("clura/dental-google-maps-lead-generator").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("clura/dental-google-maps-lead-generator").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 '{}' |
apify call clura/dental-google-maps-lead-generator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clura/dental-google-maps-lead-generator"
        }
    }
}

```

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/zuSqnD2aYGhF7FwFw/builds/qslmUNfWePTgVMW0O/openapi.json
