# Mental Health Professionals Email Scraper (`muhammadafzal/mental-health-professionals-email-scraper`) Actor

Find therapists, psychologists, counselors, psychiatrists, and mental health practices by specialty and location. Extract public emails, phones, credentials, specialties, addresses, websites, and source pages for compliant B2B research.

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

## Pricing

from $20.00 / 1,000 professional contact records

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Mental Health Professionals Email Scraper

Find public websites for therapists, psychologists, counselors, psychiatrists, and mental health practices, then extract business emails that those sites visibly publish. The Actor is built for ethical B2B outreach, provider-directory research, partnership discovery, and local market analysis—not patient data or clinical decision-making.

### What it extracts

Each dataset row represents one professional or practice website. By default, every returned row contains at least one public email.

| Field | Meaning |
| --- | --- |
| `professionalName` | Provider name when the website identifies one |
| `credentials` | Public credentials such as PhD, PsyD, LCSW, LMFT, or LPC |
| `practiceName` | Clinic, group practice, or organization name |
| `specialties` | Detected areas such as anxiety, trauma/PTSD, couples therapy, EMDR, or addiction |
| `primaryEmail`, `emails` | Visible, normalized emails; addresses are never guessed |
| `emailSourceUrls` | Exact pages where an email was found |
| `emailConfidence` | `high` for `mailto:`/structured data, `medium` for visible page text |
| `phoneNumbers` | Public phone values from links or structured data |
| `website`, `pagesVisited` | Canonical website and the pages inspected |
| Address fields | Published address, city, region, postal code, and country when available |
| `socialUrls` | Social accounts linked by the practice website |
| Source fields | Search URL and specialty-location query used for discovery |

### How discovery works

Provide specialties and locations, and the Actor searches public search result pages. `auto` tries Google first and falls back to Bing and DuckDuckGo when a page is unavailable or yields no candidates. It excludes common directory and social-network results so that it can focus on official professional and practice websites.

For every candidate, it fetches `robots.txt`, respects crawl exclusions, verifies that public page text matches the requested specialty and location, visits the landing page, and follows a small number of same-domain links whose labels indicate contact, about, team, staff, therapists, or clinicians. Requests are bounded by the input limits, use consistent proxy sessions, retry only transient errors, and never cross into login or patient-portal flows.

Alternatively, supply `startUrls` to inspect known practice websites directly. You may combine direct URLs with search discovery.

### Input examples

Default local-market search:

```json
{
  "specialties": ["therapist"],
  "locations": ["Austin, TX"],
  "maxResults": 10,
  "maxSearchPages": 1,
  "maxWebsitePages": 3,
  "includeWithoutEmail": false,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

Multiple buyer segments:

```json
{
  "specialties": ["child psychologist", "trauma counselor"],
  "locations": ["Chicago, IL", "Milwaukee, WI"],
  "maxResults": 50
}
```

Known websites only:

```json
{
  "startUrls": [
    { "url": "https://example-therapy-practice.com/" },
    { "url": "https://example-counseling-center.org/team" }
  ],
  "specialties": [],
  "locations": [],
  "maxResults": 20
}
```

### Output example

```json
{
  "professionalName": "Jane Smith, PhD",
  "credentials": ["PHD"],
  "practiceName": "Calm Path Therapy",
  "specialties": ["Anxiety", "Trauma and PTSD"],
  "primaryEmail": "hello@calmpath.example",
  "emails": ["hello@calmpath.example"],
  "emailSourceUrls": ["https://calmpath.example/contact"],
  "emailConfidence": "high",
  "phoneNumbers": ["+1 512 555 0100"],
  "website": "https://calmpath.example",
  "pagesVisited": ["https://calmpath.example/", "https://calmpath.example/contact"],
  "address": "1 Main St, Austin, TX 78701, US",
  "city": "Austin",
  "region": "TX",
  "postalCode": "78701",
  "country": "US",
  "socialUrls": [],
  "sourceSearchUrl": "https://www.google.com/search?q=therapist+austin",
  "searchQuery": "therapist — Austin, TX",
  "pageTitle": "Calm Path Therapy | Austin",
  "description": "Therapy for anxiety and trauma in Austin.",
  "scrapedAt": "2026-09-07T12:00:00.000Z"
}
```

### Pricing

This Actor uses transparent pay per event pricing. Platform usage is included rather than passed through separately.

| Event | Price |
| --- | ---: |
| Actor start | $0.005 per run |
| Professional contact record | $0.02 per dataset row |

A run returning 10 records costs $0.205 in events. A truthful empty run costs only the $0.005 start event. Use `maxResults` and Apify's maximum total charge to cap spend. Each default-dataset row is charged automatically exactly once; the Actor does not add a duplicate custom charge.

### Reliability and truthful outcomes

The `OUTPUT` key-value record classifies every run as `DATA`, `EMPTY`, `BLOCKED`, or `REJECTED`. It includes candidate, request, failure, warning, and delivered counts. A site that publishes no email does not generate a fabricated record. If public pages are broadly blocked, the Actor returns a blocker diagnosis and zero result events. Valid results already delivered are preserved when individual sites fail.

Static HTTP keeps runs fast and inexpensive, but some JavaScript-only sites may expose fewer fields. Search engines and websites can rate-limit or challenge automated access. Configure an appropriate Apify Proxy group where permitted, reduce concurrency for fragile sites, or provide direct practice URLs. The Actor does not solve CAPTCHAs, use logged-in sessions, bypass paywalls, or defeat access controls.

### Privacy, compliance, and responsible use

This tool extracts contact information intentionally published on public professional/business websites. It does not collect patient records, appointment details, insurance claims, protected health information, private accounts, or data behind authentication. Mental health specialty data can still be sensitive in context; use it only for lawful business purposes.

You are responsible for the websites' terms, robots rules, applicable privacy and electronic-marketing laws, opt-out handling, and your legal basis for outreach. Do not use the data for harassment, discriminatory profiling, clinical decisions, emergency services, or unsolicited bulk messaging. Verify important provider and licensing information with the relevant official authority before relying on it.

For support, open an issue from the Actor page with a redacted input, run ID, expected outcome, and the affected public URL. Never include patient information, credentials, cookies, or tokens.

# Actor input Schema

## `specialties` (type: `array`):

Use this to choose the professional or service to discover. Enter phrases such as therapist, child psychologist, trauma counselor, or psychiatrist. Defaults to therapist; 1–10 values. This is not a diagnosis or patient search.

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

Use this to choose markets for search discovery. Enter a city, state/region, postal code, or country such as Austin, TX. Defaults to Austin, TX; 1–20 values. This is not a radius or geocoding field.

## `startUrls` (type: `array`):

Use this when you already know public professional or practice websites. Add full HTTP/HTTPS URLs such as https://example-therapy-practice.com/. Defaults to empty. This is not for login pages, patient portals, private profiles, or search result URLs.

## `searchEngine` (type: `string`):

Use this to control public web discovery. Auto tries Google, then Bing and DuckDuckGo when a result page is unavailable or empty. Defaults to auto. This does not use a paid search API or bypass access challenges.

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

Use this to cap delivered professional/practice records and result-event spend. Enter 1–500; defaults to 10. At $0.02 per record plus the $0.005 start event, 10 records cost at most $0.205 in PPE events.

## `maxSearchPages` (type: `integer`):

Use this to control discovery depth for each specialty-location pair. Enter 1–5; defaults to 1. Increase only when the first result page does not provide enough candidate websites. This is not the website page limit.

## `maxWebsitePages` (type: `integer`):

Use this to cap same-domain pages inspected for public contacts. Enter 1–10; defaults to 3, prioritizing the landing page plus contact/about/team links. This does not permit off-domain or private-page crawling.

## `includeWithoutEmail` (type: `boolean`):

Use this only when practice discovery is useful even if no public email is found. Defaults to false, so every delivered record has an email. Enabling it can return contact records with primaryEmail set to null; it never guesses an address.

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

Use this to tune speed and politeness across independent domains. Enter 1–20; defaults to 5. Lower it for fragile sites or constrained proxies. This does not increase per-domain request concurrency.

## `requestTimeoutSecs` (type: `integer`):

Use this to bound each public page request. Enter 10–60 seconds; defaults to 20. Shorter values fail fast on slow sites, while longer values can reduce throughput. This is not the overall Actor timeout.

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

Use this when public search or practice sites restrict datacenter traffic. The Apify Proxy is enabled by default; residential groups may improve access but cost more. This is not a way to bypass authentication, CAPTCHAs, paywalls, or access controls.

## Actor input object example

```json
{
  "specialties": [
    "therapist"
  ],
  "locations": [
    "Austin, TX"
  ],
  "startUrls": [],
  "searchEngine": "auto",
  "maxResults": 10,
  "maxSearchPages": 1,
  "maxWebsitePages": 3,
  "includeWithoutEmail": false,
  "maxConcurrency": 5,
  "requestTimeoutSecs": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Schema-validated records in the default dataset.

## `summary` (type: `string`):

Outcome, counts, access warnings, and billing parity diagnostics.

# 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 = {
    "specialties": [
        "therapist"
    ],
    "locations": [
        "Austin, TX"
    ],
    "startUrls": [],
    "searchEngine": "auto",
    "maxResults": 10,
    "maxSearchPages": 1,
    "maxWebsitePages": 3,
    "includeWithoutEmail": false,
    "maxConcurrency": 5,
    "requestTimeoutSecs": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/mental-health-professionals-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 = {
    "specialties": ["therapist"],
    "locations": ["Austin, TX"],
    "startUrls": [],
    "searchEngine": "auto",
    "maxResults": 10,
    "maxSearchPages": 1,
    "maxWebsitePages": 3,
    "includeWithoutEmail": False,
    "maxConcurrency": 5,
    "requestTimeoutSecs": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/mental-health-professionals-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 '{
  "specialties": [
    "therapist"
  ],
  "locations": [
    "Austin, TX"
  ],
  "startUrls": [],
  "searchEngine": "auto",
  "maxResults": 10,
  "maxSearchPages": 1,
  "maxWebsitePages": 3,
  "includeWithoutEmail": false,
  "maxConcurrency": 5,
  "requestTimeoutSecs": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call muhammadafzal/mental-health-professionals-email-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,muhammadafzal/mental-health-professionals-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/0hLtv3icoiX1u6wVb/builds/r9SJNQYdQnPCALa6B/openapi.json
