# Doctify Scraper (`mrdoe/doctify-scraper`) Actor

Scrape clinic and practitioner listings from Doctify - ratings, reviews, specialties, and locations. No login required, built for healthcare market research and competitor analysis. Give it a search or specialty URL and get one row per provider.

- **URL**: https://apify.com/mrdoe/doctify-scraper.md
- **Developed by:** [MrDoe](https://apify.com/mrdoe) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

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/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

![Doctify Scraper hero](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/doctify-scraper--hero.png)

### What does Doctify Scraper do?

Doctify Scraper collects healthcare provider profiles from Doctify and returns them as clean, structured data. Run a search on Doctify, open a directory page, paste the URL, press **Start**, and download a dataset with the provider's name, title, qualifications, specialty, location, average rating, review count, peer recommendations, conditions treated, consultation fees, accepted insurers, languages, professional registrations, phone, email, and the practices they work from with full addresses. Use it for healthcare market research, provider directories, referral lists, and competitor analysis.

### Why use Doctify Scraper?

- **Directory to dataset** – point it at a specialty-and-location search and it collects every provider profile.
- **Deep profile data** – 25+ fields per provider, including data other tools miss: phone, email, addresses, consultation fees, and the full conditions list with review counts.
- **Ratings and recommendations** – average rating, total reviews, the review breakdown, and peer recommendation counts.
- **Structured practices** – each provider's clinics with street address, city, and postcode.
- **Clean, normalised output** – numbers as numbers, `null` for missing values, deduplicated by provider.
- **Automation ready** – schedule runs and connect results to Google Sheets, Make, Zapier, or your own API.

### What makes this different?

This Actor reads Doctify's own structured profile data, so hard-to-collect fields — direct phone and email, consultation fees, accepted insurers, professional registration numbers, and every practice address — come through consistently rather than being scraped out of page text. It pairs each directory result with its full profile in a single pass.

### What data can you extract?

![Doctify Scraper dataset output](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/doctify-scraper--output.png)

![Doctify Scraper data fields](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/doctify-scraper--fields.png)

| Field                     | Description                                                 |
| ------------------------- | ----------------------------------------------------------- |
| `url` / `slug` / `id`     | Profile URL, Doctify slug, and internal ID                  |
| `type`                    | `specialist` or `practice`                                  |
| `name`                    | Provider or practice name                                   |
| `title`                   | Honorific, e.g. "Mr", "Dr", "Professor"                     |
| `qualifications`          | Post-nominal qualifications, e.g. "MBBS, BSc, MD"           |
| `gender`                  | Provider gender, when published                             |
| `specialty`               | Primary specialty                                           |
| `location`                | Primary city or area                                        |
| `about`                   | Profile biography (plain text)                              |
| `averageRating`           | Average patient rating                                      |
| `reviewsTotal`            | Number of patient reviews                                   |
| `peerRecommendations`     | Number of peer recommendations from other clinicians        |
| `reviewBreakdown`         | Sub-scores: overall experience, bedside manner, explanation |
| `conditions`              | Conditions and procedures, each with its review count       |
| `phones` / `emails`       | Listed contact details                                      |
| `website` / `bookingLink` | Provider website and external booking link, when listed     |
| `consultationFees`        | `{ new, followUp, currency }` where published               |
| `insurers`                | Accepted private medical insurers                           |
| `languages`               | Languages spoken                                            |
| `registrations`           | Professional bodies with registration number, e.g. GMC      |
| `education`               | Degrees with institution and year                           |
| `practices`               | Clinics worked from: name, address, city, postcode          |
| `imageUrl`                | Profile photo or logo URL                                   |
| `scrapedAt`               | ISO timestamp of collection                                 |

Everything beyond `url`, `slug`, and `type` needs **Open each profile for full details** switched on.

### How to use Doctify Scraper

![How Doctify Scraper works](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/doctify-scraper--how-it-works.png)

1. Open the Actor.
2. On [doctify.com](https://www.doctify.com), search for a specialty and location and open the results page (its URL looks like `/uk/find/<specialty>/<location>/specialists`). Copy the URL from your browser.
3. Paste it into **Start URLs**. Add more URLs to combine several specialties or areas.
4. Set **Max profiles per start URL** and choose whether to open each profile.
5. Press **Start**.
6. Download the dataset as JSON, CSV, Excel, or XML, or use the API.

### Input Parameters

| Parameter            | Type    | Required | Default                  | Description                                                                                       |
| -------------------- | ------- | -------- | ------------------------ | ------------------------------------------------------------------------------------------------- |
| `startUrls`          | Array   | Yes      | Dermatologists in London | Doctify directory pages, or individual profile URLs.                                              |
| `maxItems`           | Integer | No       | 20                       | Maximum profiles to collect per start URL. Ignored for single profile URLs (always one row each). |
| `scrapeDetails`      | Boolean | No       | `true`                   | Open each profile for the full field set. Turn off to only collect the profile URLs.              |
| `useCache`           | Boolean | No       | `false`                  | Reuse profiles collected in an earlier run to speed up recurring runs.                            |
| `proxyConfiguration` | Object  | No       | UK residential proxy     | Proxy settings. A UK residential proxy is used by default and strongly recommended.               |

### Output Data

Each dataset item is one provider. Example (trimmed):

```json
{
    "url": "https://www.doctify.com/uk/specialist/matthew-cauldwell",
    "slug": "matthew-cauldwell",
    "id": "27862",
    "type": "specialist",
    "name": "Matthew Cauldwell",
    "title": "Mr",
    "qualifications": "MBBS, BSc, MD MEd MRCP, MRCOG",
    "gender": "male",
    "specialty": "Obstetrics & Gynaecology",
    "location": "London",
    "averageRating": 5,
    "reviewsTotal": 140,
    "peerRecommendations": 5,
    "reviewBreakdown": { "overallExperience": 5, "bedsideManner": 5, "explanation": 4.99 },
    "conditions": [
        { "name": "Pregnancy", "count": 125 },
        { "name": "Gestational Diabetes", "count": 11 }
    ],
    "phones": ["+447852929233"],
    "emails": ["secretary@example.co.uk"],
    "consultationFees": { "new": 400, "followUp": 300, "currency": "GBP" },
    "insurers": ["Cigna", "WPA"],
    "languages": ["English"],
    "registrations": [{ "body": "General Medical Council", "number": "6163824" }],
    "practices": [
        {
            "name": "The Portland Hospital",
            "address": "205–209 Great Portland Street, London, W1W 5AH",
            "postcode": "W1W 5AH",
            "city": "London"
        }
    ],
    "scrapedAt": "2026-09-01T09:00:00.000Z"
}
```

### Usage Examples

**Every dermatologist in a city**

- Start URL: a Doctify "dermatology / <city> / specialists" directory page
- `maxItems`: 500, `scrapeDetails`: true

**Practice directory for a region**

- Start URL: a `/uk/find/all/<region>/practices` page
- `maxItems`: 300, `scrapeDetails`: true

**Refresh a shortlist**

- Start URLs: several `/uk/specialist/<slug>` URLs
- `scrapeDetails`: true

### Tips for Best Results

- Search on Doctify with both a specialty and a location before copying the URL – it keeps the run focused.
- Add several start URLs to cover multiple specialties or cities in one run; `maxItems` applies to each separately.
- Keep the default UK residential proxy on.
- For monitoring, schedule the Actor and enable **Use cache**.

### Known Limitations

- A UK residential proxy is required in practice; the site is behind a CDN with bot protection.
- Directory pagination depth varies by specialty and location; split broad searches into narrower ones for full coverage.
- Contact details, fees, and insurers are only present when the provider has published them.
- Review text is summarised on the profile; this Actor collects the ratings and counts, not every individual review.
- Data reflects what Doctify publishes at run time.

### Integrations

Connect results to Google Sheets, Make, Zapier, Slack, or your own systems via the Apify API and webhooks. Schedule runs to keep a dataset current.

### Export Formats

JSON, CSV, Excel, and XML from the Dataset tab or the Apify API.

### Frequently Asked Questions

**How many profiles can I get per run?**
Up to `maxItems` per start URL, within the directory's own pagination depth. Use multiple start URLs for wider coverage.

**Can I scrape practices as well as individual specialists?**
Yes. Directory pages ending in `/practices` and individual `/uk/practice/<slug>` URLs are both supported.

**How are duplicates handled?**
Providers are deduplicated by profile URL within a run.

**Why are some fields `null`?**
The provider has not published that information on Doctify, or detail scraping was turned off.

**Can I schedule it?**
Yes, with Apify Schedules. Combine with **Use cache** to refresh only what changed.

**How fresh is the data?**
Every run loads live pages at run time, unless a profile is served from your cache.

### Support

Found a problem or need an extra field? Open an issue on the Actor's **Issues** tab in the Apify Console.

### Legal / Responsible Use

You are responsible for how you use this Actor and the data it collects, including compliance with Doctify's Terms of Use and applicable laws. Provider profiles contain personal data such as names, photos, phone numbers, and email addresses; if you collect personal data you are responsible for complying with applicable data-protection law (for example the UK GDPR), including having a lawful basis and honouring individuals' rights. Do not use the data for unsolicited marketing.

### Preview

![Doctify Scraper input options](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/doctify-scraper--input.png)

# Actor input Schema

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

One or more Doctify pages to scrape. On doctify.com, run a search and open a directory page (its URL looks like /uk/find/<specialty>/<location>/specialists) and paste it here. Individual profile URLs such as https://www.doctify.com/uk/specialist/matthew-cauldwell or /uk/practice/<slug> also work.

## `maxItems` (type: `integer`):

Maximum number of provider profiles to collect for each start URL. Keep this low for quick test runs and raise it for full exports. Ignored for individual profile URLs, which always return one row each.

## `scrapeDetails` (type: `boolean`):

When on, the Actor opens every provider profile to collect the qualifications, about text, review breakdown, conditions treated, consultation fees, insurers, languages, registrations, contact details, and practice addresses. Turn it off to only collect the profile URLs found on the directory pages.

## `useCache` (type: `boolean`):

Reuse details collected for a profile in an earlier run to speed up recurring runs. Disabled by default so every run returns fresh data.

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

Proxy settings. A UK residential proxy is used by default and strongly recommended, as the site is behind a CDN with bot protection.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.doctify.com/uk/find/dermatology/london/specialists"
    }
  ],
  "maxItems": 20,
  "scrapeDetails": true,
  "useCache": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}
```

# Actor output Schema

## `profiles` (type: `string`):

No description

# 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 = {
    "startUrls": [
        {
            "url": "https://www.doctify.com/uk/find/dermatology/london/specialists"
        }
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrdoe/doctify-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 = {
    "startUrls": [{ "url": "https://www.doctify.com/uk/find/dermatology/london/specialists" }],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("mrdoe/doctify-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 '{
  "startUrls": [
    {
      "url": "https://www.doctify.com/uk/find/dermatology/london/specialists"
    }
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}' |
apify call mrdoe/doctify-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mrdoe/doctify-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/NKxAyblW1AVbrTRd6/builds/29kdu8zXFsFjNYolb/openapi.json
