# 🪷 Dentist Leads Scraper - Dental Office Emails & Phones (`renzomacar/dentist-leads-scraper`) Actor

Dental office leads for any city: practice name, address, phone, website, emails and social profiles extracted live from each practice's own website. $8 per 1,000 dentist leads, no subscription.

- **URL**: https://apify.com/renzomacar/dentist-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 $7.44 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## 🦷 Dentist Leads Scraper — Dental Office Emails & Phones

You sell to dental practices — SEO, patient-acquisition ads, dental supplies, practice-management software, billing services. What you actually need is a fresh, city-by-city list of dental offices with a real email address, not a stale CSV resold since 2022. This scraper builds that list live, on demand, for **$8 per 1,000 dentist leads** with no subscription.

Pick the dental categories you care about (general dentist, orthodontist, pediatric dentist, cosmetic dentist, dental implant clinic...), type a city, and get one clean row per practice: practice name, address, phone, website, **emails scraped directly from the practice's own website**, social profiles, rating and review count.

### What a dentist lead looks like

```json
{
  "name": "Bayfront Dental Studio",
  "category": "Dentist",
  "address": "120 SE 2nd Ave, Miami, FL 33131",
  "phone": "+1 305-555-0134",
  "website": "https://bayfrontdental.com",
  "email": "smile@bayfrontdental.com",
  "emails": ["smile@bayfrontdental.com", "frontdesk@bayfrontdental.com"],
  "socialProfiles": { "instagram": "...", "facebook": "..." },
  "rating": 4.8,
  "reviewsCount": 312
}
```

Every practice is discovered live from the Google Maps business index, then the scraper visits the practice's website (homepage + contact/about pages) to hunt for email addresses, extra phone numbers, and social links. Nothing comes from a pre-built database, so closed practices and dead domains don't pollute your list.

### Who uses this

- **Dental marketing agencies** — build prospect lists per metro before a cold-email or cold-call sprint; the `reviewsCount` field instantly separates established practices from brand-new ones.
- **Dental supply & lab sales reps** — territory lists with direct phones for every practice in your patch.
- **Dental software / DSO acquisition teams** — filter by rating and review volume to find practices worth acquiring or upgrading.
- **Local SEO consultants** — practices with a low rating or no website (set `onlyWithWebsite` to false) are your warmest pitch.

### Dental categories you can target

The `searchTerms` picker covers the seven practice types worth prospecting separately. Each one is its own Google Maps search, so selecting more categories means more practices — and a different buyer profile per list:

| Category | What the list is good for |
|---|---|
| `dentist` | The broad general-practice list — the default, highest volume per city |
| `dental clinic` | Multi-chair clinics and small groups; overlaps `dentist` but surfaces different listings |
| `orthodontist` | Higher ticket, heavy ad spenders — the best list for patient-acquisition agencies |
| `pediatric dentist` | Family-marketing angle; usually strong social profiles |
| `cosmetic dentist` | Veneers/whitening; the highest-margin practices in most metros |
| `dental implants clinic` | Implant centers — the target for lab, imaging and implant-supply reps |
| `emergency dentist` | Extended-hours practices; small list, but they buy call-tracking and answering services |

Leave the picker on `dentist` for the widest sweep, or select several to build a deduplicated multi-category list in one run.

### Selling software or services into dental practices

A dental practice is a small business with an owner-dentist who is also the buyer, an office manager who is the gatekeeper, and almost no procurement process — which is why the columns you sort on decide whether the list converts:

- **`reviewsCount` is the size proxy.** Under ~30 reviews is usually a young or single-chair practice with no budget and no staff to run new software. Between roughly 100 and 500 is the sweet spot for practice-management, billing, patient-communication and marketing tools: enough volume to have the problem, small enough that the dentist still decides alone. Several thousand reviews across several listings in a metro generally means a DSO or group — a longer, centralised sale, and the local office cannot buy from you.
- **`techStack` tells you whether they invest.** A practice site on WordPress with Google Analytics and a tag manager is one that has already paid an agency; one with no detectable stack at all is running a template from whoever built it in 2016. Both are pitchable, but they are different pitches and different price points.
- **`emailFound: false` is not a dead lead in this vertical.** Dental front desks answer the phone all day — that is the job. The no-email rows are a call list, not waste, and they are charged at the same low rate.
- **`category` separates the buyer.** `orthodontist` and `cosmetic dentist` practices spend on patient acquisition and are the right list for ads, SEO and financing products. `dental implants clinic` buys imaging, lab work and implant supply. `emergency dentist` buys answering services and call tracking. Selling one product to all seven categories in one blast is the fastest way to burn a domain.

A practical first run: one metro, `["dentist", "dental clinic"]`, `maxResults: 120`, then filter to practices with a website and 80–500 reviews. That is typically 60–150 practices per metro and costs about a dollar — small enough to test messaging on before scaling to a state.

### How to run it

1. Choose one or more **dental categories** (default: `dentist`).
2. Enter a **location** — `"Miami, FL"`, `"Denver, CO"`, `"London, UK"`.
3. Optionally raise **Max results per search** (a single city search typically surfaces up to ~120 practices).
4. Run. Export the dataset as CSV, Excel or JSON, or pull it through the API into your CRM.

Power users can skip the category picker and pass raw queries like `orthodontist in Scottsdale, AZ` — one per line — to sweep many cities in a single run.

### FAQ

**How many dentists can I scrape per city?**
A single search ("dentist in Chicago, IL") typically yields 60–120 practices, which is what Google Maps exposes per query. To go deeper in a big metro, add neighborhood-level queries ("dentist in Lincoln Park, Chicago") or run several categories (orthodontist, pediatric dentist...) — each is its own search.

**Do all leads come with an email?**
No — an email is only delivered when the practice publishes one on its website, which in practice is roughly 40–70% of dental offices depending on the market. Every lead always includes phone, address and website, and the `emailFound` flag lets you filter instantly. You pay per lead delivered, not per email.

**Can I get only practices that have a website?**
Yes — enable `onlyWithWebsite`. Practices without a site are dropped **before** they're charged.

**Does it work outside the US?**
Yes. Any city Google Maps covers: Canada, UK, Australia, EU, Latin America. Set the `language` field for non-English markets (e.g. `es` for "clínica dental in Madrid").

**How is this different from buying a dental email list?**
Purchased lists decay ~2–3% per month and everyone else bought the same file. This scrapes today's data at run time — practices that opened last quarter are in; ones that closed are out.

**Can I schedule it weekly?**
Yes — use Apify Schedules to re-run your cities weekly or monthly and keep your pipeline topped up automatically.

**What does a 500-lead run cost?**
$0.02 for the run start + 500 × $0.008 = **$4.02**. No monthly fee, no seats, no expiring credits.

### Pricing

| Event | Price |
|---|---|
| Actor start (2 GB run) | $0.02 |
| Per dentist lead delivered | $0.008 |

**$8 per 1,000 leads.** You are charged only for rows actually pushed to your dataset.

### Data & compliance

This actor collects **publicly available business information only**: what dental practices themselves publish on Google Maps and on their own public websites (business name, address, business phone, business email, social links). It does not collect patient data, log into any service, or bypass any access control. You are responsible for using the output in line with the laws that apply to you (e.g. CAN-SPAM for US cold email — include an opt-out; GDPR/PECR rules if you target the EU/UK).

# Actor input Schema

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

Which kinds of dental practices to find. Each selected category runs as its own search in your location; results are deduplicated.

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

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

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

Full searches, one per line (e.g. 'orthodontist in Scottsdale, AZ'). When set, these override the category picker + location. Use several queries to cover multiple cities or neighborhoods 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 addresses like info@, hello@, contact@. Disable to keep only personal/role emails (fewer results).

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

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

## Actor input object example

```json
{
  "searchTerms": [
    "dentist"
  ],
  "location": "Miami, FL",
  "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 = {
    "searchTerms": [
        "dentist"
    ],
    "location": "Miami, FL",
    "maxResults": 5,
    "maxPagesPerSite": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("renzomacar/dentist-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 = {
    "searchTerms": ["dentist"],
    "location": "Miami, FL",
    "maxResults": 5,
    "maxPagesPerSite": 1,
}

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

```

## MCP server setup

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